diff --git a/Example/demo.cs.orig b/Example/demo.cs.orig new file mode 100644 index 000000000..f3363488b --- /dev/null +++ b/Example/demo.cs.orig @@ -0,0 +1,611 @@ +using Terminal.Gui; +using System; +using Mono.Terminal; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Reflection; +using NStack; +using System.Text; + +static class Demo { + //class Box10x : View, IScrollView { + class Box10x : View { + int w = 40; + int h = 50; + + public bool WantCursorPosition { get; set; } = false; + + public Box10x (int x, int y) : base (new Rect (x, y, 20, 10)) + { + } + + public Size GetContentSize () + { + return new Size (w, h); + } + + public void SetCursorPosition (Point pos) + { + throw new NotImplementedException (); + } + + public override void Redraw (Rect region) + { + //Point pos = new Point (region.X, region.Y); + Driver.SetAttribute (ColorScheme.Focus); + + for (int y = 0; y < h; y++) { + Move (0, y); + Driver.AddStr (y.ToString ()); + for (int x = 0; x < w - y.ToString ().Length; x++) { + //Driver.AddRune ((Rune)('0' + (x + y) % 10)); + if (y.ToString ().Length < w) + Driver.AddStr (" "); + } + } + //Move (pos.X, pos.Y); + } + } + + class Filler : View { + public Filler (Rect rect) : base (rect) + { + } + + public override void Redraw (Rect region) + { + Driver.SetAttribute (ColorScheme.Focus); + var f = Frame; + + for (int y = 0; y < f.Width; y++) { + Move (0, y); + for (int x = 0; x < f.Height; x++) { + Rune r; + switch (x % 3) { + case 0: + Driver.AddRune (y.ToString ().ToCharArray (0, 1) [0]); + if (y > 9) + Driver.AddRune (y.ToString ().ToCharArray (1, 1) [0]); + r = '.'; + break; + case 1: + r = 'o'; + break; + default: + r = 'O'; + break; + } + Driver.AddRune (r); + } + } + } + } + + static void ShowTextAlignments () + { +<<<<<<< HEAD + var container = new Window ($"Show Text Alignments") { + X = 0, + Y = 0, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + container.OnKeyUp += (KeyEvent ke) => { + if (ke.Key == Key.Esc) + container.Running = false; + }; +======= + var container = new Dialog ( + "Text Alignments", 70, 20, + new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } }, + new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } }); + +>>>>>>> cb40c5c2491a559658481d20dd4b6a3343c0183f + + int i = 0; + string txt = "Hello world, how are you doing today?"; + container.Add ( +<<<<<<< HEAD + new Label ($"{i+1}-{txt}") { TextAlignment = TextAlignment.Left, Y = 3, Width = Dim.Fill () }, + new Label ($"{i+2}-{txt}") { TextAlignment = TextAlignment.Right, Y = 5, Width = Dim.Fill () }, + new Label ($"{i+3}-{txt}") { TextAlignment = TextAlignment.Centered, Y = 7, Width = Dim.Fill () }, + new Label ($"{i+4}-{txt}") { TextAlignment = TextAlignment.Justified, Y = 9, Width = Dim.Fill () } +======= + new Label (new Rect (0, 1, 50, 3), $"{i+1}-{txt}") { TextAlignment = TextAlignment.Left }, + new Label (new Rect (0, 3, 50, 3), $"{i+2}-{txt}") { TextAlignment = TextAlignment.Right }, + new Label (new Rect (0, 5, 50, 3), $"{i+3}-{txt}") { TextAlignment = TextAlignment.Centered }, + new Label (new Rect (0, 7, 50, 3), $"{i+4}-{txt}") { TextAlignment = TextAlignment.Justified } +>>>>>>> cb40c5c2491a559658481d20dd4b6a3343c0183f + ); + + Application.Run (container); + } + + static void ShowEntries (View container) + { + var scrollView = new ScrollView (new Rect (50, 10, 20, 8)) { + ContentSize = new Size (20, 50), + //ContentOffset = new Point (0, 0), + ShowVerticalScrollIndicator = true, + ShowHorizontalScrollIndicator = true + }; +#if false + scrollView.Add (new Box10x (0, 0)); +#else + scrollView.Add (new Filler (new Rect (0, 0, 40, 40))); +#endif + + // This is just to debug the visuals of the scrollview when small + var scrollView2 = new ScrollView (new Rect (72, 10, 3, 3)) { + ContentSize = new Size (100, 100), + ShowVerticalScrollIndicator = true, + ShowHorizontalScrollIndicator = true + }; + scrollView2.Add (new Box10x (0, 0)); + var progress = new ProgressBar (new Rect (68, 1, 10, 1)); + bool timer (MainLoop caller) + { + progress.Pulse (); + return true; + } + + Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300), timer); + + + // A little convoluted, this is because I am using this to test the + // layout based on referencing elements of another view: + + var login = new Label ("Login: ") { X = 3, Y = 6 }; + var password = new Label ("Password: ") { + X = Pos.Left (login), + Y = Pos.Bottom (login) + 1 + }; + var loginText = new TextField ("") { + X = Pos.Right (password), + Y = Pos.Top (login), + Width = 40 + }; + + var passText = new TextField ("") { + Secret = true, + X = Pos.Left (loginText), + Y = Pos.Top (password), + Width = Dim.Width (loginText) + }; + + var tf = new Button (3, 19, "Ok"); + // Add some content + container.Add ( + login, + loginText, + password, + passText, + new FrameView (new Rect (3, 10, 25, 6), "Options"){ + new CheckBox (1, 0, "Remember me"), + new RadioGroup (1, 2, new [] { "_Personal", "_Company" }), + }, + new ListView (new Rect (59, 6, 16, 4), new string [] { + "First row", + "<>", + "This is a very long row that should overflow what is shown", + "4th", + "There is an empty slot on the second row", + "Whoa", + "This is so cool" + }), + scrollView, + scrollView2, + tf, + new Button (10, 19, "Cancel"), + new TimeField (3, 20, DateTime.Now), + new TimeField (23, 20, DateTime.Now, true), + new DateField (3, 22, DateTime.Now), + new DateField (23, 22, DateTime.Now, true), + progress, + new Label (3, 24, "Press F9 (on Unix, ESC+9 is an alias) to activate the menubar"), + menuKeysStyle, + menuAutoMouseNav + + ); + container.SendSubviewToBack (tf); + } + + public static Label ml2; + + static void NewFile () + { + var d = new Dialog ( + "New File", 50, 20, + new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } }, + new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } }); + ml2 = new Label (1, 1, "Mouse Debug Line"); + d.Add (ml2); + Application.Run (d); + } + + // + // Creates a nested editor + static void Editor (Toplevel top) + { + var tframe = top.Frame; + var ntop = new Toplevel (tframe); + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("_File", new MenuItem [] { + new MenuItem ("_Close", "", () => {Application.RequestStop ();}), + }), + new MenuBarItem ("_Edit", new MenuItem [] { + new MenuItem ("_Copy", "", null), + new MenuItem ("C_ut", "", null), + new MenuItem ("_Paste", "", null) + }), + }); + ntop.Add (menu); + + string fname = null; + foreach (var s in new [] { "/etc/passwd", "c:\\windows\\win.ini" }) + if (System.IO.File.Exists (s)) { + fname = s; + break; + } + + var win = new Window (fname ?? "Untitled") { + X = 0, + Y = 1, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + ntop.Add (win); + + var text = new TextView (new Rect (0, 0, tframe.Width - 2, tframe.Height - 3)); + + if (fname != null) + text.Text = System.IO.File.ReadAllText (fname); + win.Add (text); + + Application.Run (ntop); + } + + static bool Quit () + { + var n = MessageBox.Query (50, 7, "Quit Demo", "Are you sure you want to quit this demo?", "Yes", "No"); + return n == 0; + } + + static void Close () + { + MessageBox.ErrorQuery (50, 7, "Error", "There is nothing to close", "Ok"); + } + + // Watch what happens when I try to introduce a newline after the first open brace + // it introduces a new brace instead, and does not indent. Then watch me fight + // the editor as more oddities happen. + + public static void Open () + { + var d = new OpenDialog ("Open", "Open a file") { AllowsMultipleSelection = true }; + Application.Run (d); + + if (!d.Canceled) + MessageBox.Query (50, 7, "Selected File", string.Join (", ", d.FilePaths), "Ok"); + } + + public static void ShowHex (Toplevel top) + { + var tframe = top.Frame; + var ntop = new Toplevel (tframe); + var menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("_File", new MenuItem [] { + new MenuItem ("_Close", "", () => {Application.RequestStop ();}), + }), + }); + ntop.Add (menu); + + var win = new Window ("/etc/passwd") { + X = 0, + Y = 1, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + ntop.Add (win); + + var source = System.IO.File.OpenRead ("/etc/passwd"); + var hex = new HexView (source) { + X = 0, + Y = 0, + Width = Dim.Fill (), + Height = Dim.Fill () + }; + win.Add (hex); + Application.Run (ntop); + + } + + public class MenuItemDetails : MenuItem { + ustring title; + string help; + Action action; + + public MenuItemDetails (ustring title, string help, Action action) : base (title, help, action) + { + this.title = title; + this.help = help; + this.action = action; + } + + public static MenuItemDetails Instance (MenuItem mi) + { + return (MenuItemDetails)mi.GetMenuItem (); + } + } + + public delegate MenuItem MenuItemDelegate (MenuItemDetails menuItem); + + public static void ShowMenuItem (MenuItem mi) + { + BindingFlags flags = BindingFlags.Public | BindingFlags.Static; + MethodInfo minfo = typeof (MenuItemDetails).GetMethod ("Instance", flags); + MenuItemDelegate mid = (MenuItemDelegate)Delegate.CreateDelegate (typeof (MenuItemDelegate), minfo); + MessageBox.Query (70, 7, mi.Title.ToString (), + $"{mi.Title.ToString ()} selected. Is from submenu: {mi.GetMenuBarItem ()}", "Ok"); + } + + static void MenuKeysStyle_Toggled (object sender, EventArgs e) + { + menu.UseKeysUpDownAsKeysLeftRight = menuKeysStyle.Checked; + } + + static void MenuAutoMouseNav_Toggled (object sender, EventArgs e) + { + menu.WantMousePositionReports = menuAutoMouseNav.Checked; + } + + + static void Copy () + { + TextField textField = menu.LastFocused as TextField; + if (textField != null && textField.SelectedLength != 0) { + textField.Copy (); + } + } + + static void Cut () + { + TextField textField = menu.LastFocused as TextField; + if (textField != null && textField.SelectedLength != 0) { + textField.Cut (); + } + } + + static void Paste () + { + TextField textField = menu.LastFocused as TextField; + if (textField != null) { + textField.Paste (); + } + } + + static void Help () + { + MessageBox.Query (50, 7, "Help", "This is a small help\nBe kind.", "Ok"); + } + + #region Selection Demo + + static void ListSelectionDemo (bool multiple) + { + var d = new Dialog ("Selection Demo", 60, 20, + new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } }, + new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } }); + + var animals = new List () { "Alpaca", "Llama", "Lion", "Shark", "Goat" }; + var msg = new Label ("Use space bar or control-t to toggle selection") { + X = 1, + Y = 1, + Width = Dim.Fill () - 1, + Height = 1 + }; + + var list = new ListView (animals) { + X = 1, + Y = 3, + Width = Dim.Fill () - 4, + Height = Dim.Fill () - 4, + AllowsMarking = true, + AllowsMultipleSelection = multiple + }; + d.Add (msg, list); + Application.Run (d); + + var result = ""; + for (int i = 0; i < animals.Count; i++) { + if (list.Source.IsMarked (i)) { + result += animals [i] + " "; + } + } + MessageBox.Query (60, 10, "Selected Animals", result == "" ? "No animals selected" : result, "Ok"); + } + #endregion + + + #region OnKeyDown / OnKeyUp Demo + private static void OnKeyDownUpDemo () + { + var container = new Dialog ( + "OnKeyDown & OnKeyUp demo", 80, 20, + new Button ("Close") { Clicked = () => { Application.RequestStop (); } }) { + Width = Dim.Fill (), + Height = Dim.Fill (), + }; + + var list = new List (); + var listView = new ListView (list) { + X = 0, + Y = 0, + Width = Dim.Fill () - 1, + Height = Dim.Fill () - 2, + }; + listView.ColorScheme = Colors.TopLevel; + container.Add (listView); + + void KeyUpDown (KeyEvent keyEvent, string updown) + { + if ((keyEvent.Key & Key.CtrlMask) != 0) { + list.Add ($"Key{updown,-4}: Ctrl "); + } else if ((keyEvent.Key & Key.AltMask) != 0) { + list.Add ($"Key{updown,-4}: Alt "); + } else { + list.Add ($"Key{updown,-4}: {(((uint)keyEvent.KeyValue & (uint)Key.CharMask) > 26 ? $"{(char)keyEvent.KeyValue}" : $"{keyEvent.Key}")}"); + } + listView.MoveDown (); + } + + container.OnKeyDown += (KeyEvent keyEvent) => KeyUpDown (keyEvent, "Down"); + container.OnKeyUp += (KeyEvent keyEvent) => KeyUpDown (keyEvent, "Up"); + Application.Run (container); + } + #endregion + + public static Label ml; + public static MenuBar menu; + public static CheckBox menuKeysStyle; + public static CheckBox menuAutoMouseNav; + static void Main () + { + if (Debugger.IsAttached) + CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); + + //Application.UseSystemConsole = true; + + Application.Init (); + + var top = Application.Top; + + //Open (); +#if true + int margin = 3; + var win = new Window ("Hello") { + X = 1, + Y = 1, + + Width = Dim.Fill () - margin, + Height = Dim.Fill () - margin + }; +#else + var tframe = top.Frame; + + var win = new Window (new Rect (0, 1, tframe.Width, tframe.Height - 1), "Hello"); +#endif + MenuItemDetails [] menuItems = { + new MenuItemDetails ("F_ind", "", null), + new MenuItemDetails ("_Replace", "", null), + new MenuItemDetails ("_Item1", "", null), + new MenuItemDetails ("_Not From Sub Menu", "", null) + }; + + menuItems [0].Action = () => ShowMenuItem (menuItems [0]); + menuItems [1].Action = () => ShowMenuItem (menuItems [1]); + menuItems [2].Action = () => ShowMenuItem (menuItems [2]); + menuItems [3].Action = () => ShowMenuItem (menuItems [3]); + + menu = new MenuBar (new MenuBarItem [] { + new MenuBarItem ("_File", new MenuItem [] { + new MenuItem ("Text _Editor Demo", "", () => { Editor (top); }), + new MenuItem ("_New", "Creates new file", NewFile), + new MenuItem ("_Open", "", Open), + new MenuItem ("_Hex", "", () => ShowHex (top)), + new MenuItem ("_Close", "", () => Close ()), + new MenuItem ("_Disabled", "", () => { }, () => false), + null, + new MenuItem ("_Quit", "", () => { if (Quit ()) top.Running = false; }) + }), + new MenuBarItem ("_Edit", new MenuItem [] { + new MenuItem ("_Copy", "", Copy), + new MenuItem ("C_ut", "", Cut), + new MenuItem ("_Paste", "", Paste), + new MenuItem ("_Find and Replace", + new MenuBarItem (new MenuItem[] {menuItems [0], menuItems [1] })), + menuItems[3] + }), + new MenuBarItem ("_List Demos", new MenuItem [] { + new MenuItem ("Select _Multiple Items", "", () => ListSelectionDemo (true)), + new MenuItem ("Select _Single Item", "", () => ListSelectionDemo (false)), + }), + new MenuBarItem ("A_ssorted", new MenuItem [] { + new MenuItem ("_Show text alignments", "", () => ShowTextAlignments ()), + new MenuItem ("_OnKeyDown/Up", "", () => OnKeyDownUpDemo ()) + }), + new MenuBarItem ("_Test Menu and SubMenus", new MenuItem [] { + new MenuItem ("SubMenu1Item_1", + new MenuBarItem (new MenuItem[] { + new MenuItem ("SubMenu2Item_1", + new MenuBarItem (new MenuItem [] { + new MenuItem ("SubMenu3Item_1", + new MenuBarItem (new MenuItem [] { menuItems [2] }) + ) + }) + ) + }) + ) + }), + new MenuBarItem ("_About...", "Demonstrates top-level menu item", () => MessageBox.ErrorQuery (50, 7, "About Demo", "This is a demo app for gui.cs", "Ok")), + }); + + menuKeysStyle = new CheckBox (3, 25, "UseKeysUpDownAsKeysLeftRight", true); + menuKeysStyle.Toggled += MenuKeysStyle_Toggled; + menuAutoMouseNav = new CheckBox (40, 25, "UseMenuAutoNavigation", true); + menuAutoMouseNav.Toggled += MenuAutoMouseNav_Toggled; + + ShowEntries (win); + + int count = 0; + ml = new Label (new Rect (3, 17, 47, 1), "Mouse: "); + Application.RootMouseEvent += delegate (MouseEvent me) { + ml.TextColor = Colors.TopLevel.Normal; + ml.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}"; + }; + + var test = new Label (3, 18, "Se iniciarĂ¡ el anĂ¡lisis"); + win.Add (test); + win.Add (ml); + + var drag = new Label ("Drag: ") { X = 70, Y = 24 }; + var dragText = new TextField ("") { + X = Pos.Right (drag), + Y = Pos.Top (drag), + Width = 40 + }; + + var statusBar = new StatusBar (new StatusItem [] { + new StatusItem(Key.F1, "~F1~ Help", () => Help()), + new StatusItem(Key.F2, "~F2~ Load", null), + new StatusItem(Key.F3, "~F3~ Save", null), + new StatusItem(Key.ControlX, "~^X~ Quit", () => { if (Quit ()) top.Running = false; }), + }) { + Parent = null, + }; + + win.Add (drag, dragText); +#if true + // FIXED: This currently causes a stack overflow, because it is referencing a window that has not had its size allocated yet + + var bottom = new Label ("This should go on the bottom of the same top-level!"); + win.Add (bottom); + var bottom2 = new Label ("This should go on the bottom of another top-level!"); + top.Add (bottom2); + + Application.OnLoad = () => { + bottom.X = win.X; + bottom.Y = Pos.Bottom (win) - Pos.Top (win) - margin; + bottom2.X = Pos.Left (win); + bottom2.Y = Pos.Bottom (win); + }; +#endif + + + top.Add (win); + //top.Add (menu); + top.Add (menu, statusBar); + Application.Run (); + } +} diff --git a/Terminal.Gui/Drivers/CursesDriver.cs b/Terminal.Gui/Drivers/CursesDriver.cs index 95a658108..2e8e7059a 100644 --- a/Terminal.Gui/Drivers/CursesDriver.cs +++ b/Terminal.Gui/Drivers/CursesDriver.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Threading.Tasks; using Mono.Terminal; using NStack; using Unix.Terminal; @@ -183,12 +184,185 @@ namespace Terminal.Gui { } } - static MouseEvent ToDriverMouse (Curses.MouseEvent cev) + Curses.Event? LastMouseButtonPressed = null; + bool IsButtonPressed = false; + bool cancelButtonClicked = false; + Point point; + + MouseEvent ToDriverMouse (Curses.MouseEvent cev) + { + MouseFlags mouseFlag = MouseFlags.AllEvents; + + if (LastMouseButtonPressed != null && cev.ButtonState != Curses.Event.ReportMousePosition) { + LastMouseButtonPressed = null; + IsButtonPressed = false; + } + + + if ((cev.ButtonState == Curses.Event.Button1Clicked || cev.ButtonState == Curses.Event.Button2Clicked || + cev.ButtonState == Curses.Event.Button3Clicked) && + LastMouseButtonPressed == null) { + + IsButtonPressed = false; + mouseFlag = ProcessButtonClickedEvent (cev, mouseFlag); + + } else if (((cev.ButtonState == Curses.Event.Button1Pressed || cev.ButtonState == Curses.Event.Button2Pressed || + cev.ButtonState == Curses.Event.Button3Pressed) && LastMouseButtonPressed == null) || + IsButtonPressed && cev.ButtonState == Curses.Event.ReportMousePosition) { + + mouseFlag = (MouseFlags)cev.ButtonState; + if (cev.ButtonState != Curses.Event.ReportMousePosition) + LastMouseButtonPressed = cev.ButtonState; + IsButtonPressed = true; + + if (cev.ButtonState == Curses.Event.ReportMousePosition) { + mouseFlag = (MouseFlags)LastMouseButtonPressed | MouseFlags.ReportMousePosition; + point = new Point (); + cancelButtonClicked = true; + } else { + point = new Point () { + X = cev.X, + Y = cev.Y + }; + } + + if ((mouseFlag & MouseFlags.ReportMousePosition) == 0) { + Task.Run (async () => { + while (IsButtonPressed && LastMouseButtonPressed != null) { + await Task.Delay (200); + var me = new MouseEvent () { + X = cev.X, + Y = cev.Y, + Flags = mouseFlag + }; + + var view = Application.wantContinuousButtonPressedView; + if (view == null) + break; + if (IsButtonPressed && LastMouseButtonPressed != null && (mouseFlag & MouseFlags.ReportMousePosition) == 0) { + mouseHandler (me); + mainLoop.Driver.Wakeup (); + } + } + }); + } + + + } else if ((cev.ButtonState == Curses.Event.Button1Released || cev.ButtonState == Curses.Event.Button2Released || + cev.ButtonState == Curses.Event.Button3Released)) { + + mouseFlag = ProcessButtonReleasedEvent (cev, mouseFlag); + IsButtonPressed = false; + + } else if (cev.ButtonState == Curses.Event.Button4Pressed) { + + mouseFlag = MouseFlags.WheeledUp; + + } else if (cev.ButtonState == Curses.Event.ReportMousePosition && cev.X == point.X && cev.Y == point.Y) { + + mouseFlag = MouseFlags.WheeledDown; + + } + else if (cev.ButtonState == Curses.Event.ReportMousePosition) { + + mouseFlag = MouseFlags.ReportMousePosition; + } else { + mouseFlag = (MouseFlags)cev.ButtonState; + } + + point = new Point () { + X = cev.X, + Y = cev.Y + }; + + + + if (cev.ID != 0) + mouseFlag = MouseFlags.WheeledDown; + + return new MouseEvent () { + X = cev.X, + Y = cev.Y, + //Flags = (MouseFlags)cev.ButtonState + Flags = mouseFlag + }; + } + + private MouseFlags ProcessButtonClickedEvent (Curses.MouseEvent cev, MouseFlags mf) + { + LastMouseButtonPressed = cev.ButtonState; + mf = GetButtonState (cev, true); + mouseHandler (ProcessButtonState (cev, mf)); + if (LastMouseButtonPressed != null && LastMouseButtonPressed == cev.ButtonState) { + mf = GetButtonState (cev, false); + mouseHandler (ProcessButtonState (cev, mf)); + if (LastMouseButtonPressed != null && LastMouseButtonPressed == cev.ButtonState) { + mf = (MouseFlags)cev.ButtonState; + } + } + LastMouseButtonPressed = null; + return mf; + } + + private MouseFlags ProcessButtonReleasedEvent (Curses.MouseEvent cev, MouseFlags mf) + { + mf = (MouseFlags)cev.ButtonState; + mouseHandler (ProcessButtonState (cev, mf)); + if (!cancelButtonClicked && LastMouseButtonPressed == null) + mf = GetButtonState (cev); + else + cancelButtonClicked = false; + return mf; + } + + MouseFlags GetButtonState (Curses.MouseEvent cev, bool pressed = false) + { + MouseFlags mf = default; + switch (cev.ButtonState) { + case Curses.Event.Button1Clicked: + if (pressed) + mf = MouseFlags.Button1Pressed; + else + mf = MouseFlags.Button1Released; + break; + + case Curses.Event.Button2Clicked: + if (pressed) + mf = MouseFlags.Button2Pressed; + else + mf = MouseFlags.Button2Released; + break; + + case Curses.Event.Button3Clicked: + if (pressed) + mf = MouseFlags.Button3Pressed; + else + mf = MouseFlags.Button3Released; + break; + + case Curses.Event.Button1Released: + mf = MouseFlags.Button1Clicked; + break; + + case Curses.Event.Button2Released: + mf = MouseFlags.Button2Clicked; + break; + + case Curses.Event.Button3Released: + mf = MouseFlags.Button3Clicked; + break; + + + } + return mf; + } + + MouseEvent ProcessButtonState (Curses.MouseEvent cev, MouseFlags mf) { return new MouseEvent () { X = cev.X, Y = cev.Y, - Flags = (MouseFlags)cev.ButtonState + Flags = mf }; } @@ -252,10 +426,15 @@ namespace Terminal.Gui { keyUpHandler (new KeyEvent ((Key)wch)); } + Action mouseHandler; + MainLoop mainLoop; + public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) { // Note: Curses doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called - Curses.timeout (-1); + Curses.timeout (0); + this.mouseHandler = mouseHandler; + this.mainLoop = mainLoop; (mainLoop.Driver as Mono.Terminal.UnixMainLoop).AddWatch (0, Mono.Terminal.UnixMainLoop.Condition.PollIn, x => { ProcessInput (keyHandler, keyUpHandler, mouseHandler); @@ -425,21 +604,21 @@ namespace Terminal.Gui { Console.Out.Flush (); } - int lastMouseInterval; - bool mouseGrabbed; + //int lastMouseInterval; + //bool mouseGrabbed; public override void UncookMouse () { - if (mouseGrabbed) - return; - lastMouseInterval = Curses.mouseinterval (0); - mouseGrabbed = true; + //if (mouseGrabbed) + // return; + //lastMouseInterval = Curses.mouseinterval (0); + //mouseGrabbed = true; } public override void CookMouse () { - mouseGrabbed = false; - Curses.mouseinterval (lastMouseInterval); + //mouseGrabbed = false; + //Curses.mouseinterval (lastMouseInterval); } } diff --git a/Terminal.Gui/Drivers/WindowsDriver.cs b/Terminal.Gui/Drivers/WindowsDriver.cs index 0576071e3..1a1863ee9 100644 --- a/Terminal.Gui/Drivers/WindowsDriver.cs +++ b/Terminal.Gui/Drivers/WindowsDriver.cs @@ -677,6 +677,8 @@ namespace Terminal.Gui { keyHandler (new KeyEvent (map)); keyDownHandler (new KeyEvent (map)); } else { + // Key Up - Fire KeyDown Event and KeyStroke (ProcessKey) Event + keyHandler (new KeyEvent (map)); keyUpHandler (new KeyEvent (map)); } } diff --git a/Terminal.Gui/MonoCurses/constants.cs b/Terminal.Gui/MonoCurses/constants.cs index df19c30e2..8eed47967 100644 --- a/Terminal.Gui/MonoCurses/constants.cs +++ b/Terminal.Gui/MonoCurses/constants.cs @@ -2,6 +2,8 @@ * This file is autogenerated by the attrib.c program, do not edit */ +#define XTERM1006 + using System; namespace Unix.Terminal { @@ -77,6 +79,15 @@ namespace Unix.Terminal { ReportMousePosition = unchecked((int)0x8000000), AllEvents = unchecked((int)0x7ffffff), } +#if XTERM1006 + public const int LeftRightUpNPagePPage= unchecked((int)0x8); + public const int DownEnd = unchecked((int)0x6); + public const int Home = unchecked((int)0x7); +#else + public const int LeftRightUpNPagePPage= unchecked((int)0x0); + public const int DownEnd = unchecked((int)0x0); + public const int Home = unchecked((int)0x0); +#endif public const int ERR = unchecked((int)0xffffffff); public const int KeyBackspace = unchecked((int)0x107); public const int KeyUp = unchecked((int)0x103); @@ -110,30 +121,30 @@ namespace Unix.Terminal { public const int ShiftKeyPPage = unchecked((int)0x18e); public const int ShiftKeyHome = unchecked((int)0x187); public const int ShiftKeyEnd = unchecked((int)0x182); - public const int AltKeyUp = unchecked((int)0x234); - public const int AltKeyDown = unchecked((int)0x20b); - public const int AltKeyLeft = unchecked((int)0x21f); - public const int AltKeyRight = unchecked((int)0x22e); - public const int AltKeyNPage = unchecked((int)0x224); - public const int AltKeyPPage = unchecked((int)0x229); - public const int AltKeyHome = unchecked((int)0x215); - public const int AltKeyEnd = unchecked((int)0x210); - public const int CtrlKeyUp = unchecked((int)0x236); - public const int CtrlKeyDown = unchecked((int)0x20d); - public const int CtrlKeyLeft = unchecked((int)0x221); - public const int CtrlKeyRight = unchecked((int)0x230); - public const int CtrlKeyNPage = unchecked((int)0x226); - public const int CtrlKeyPPage = unchecked((int)0x22b); - public const int CtrlKeyHome = unchecked((int)0x217); - public const int CtrlKeyEnd = unchecked((int)0x212); - public const int ShiftCtrlKeyUp = unchecked((int)0x237); - public const int ShiftCtrlKeyDown = unchecked((int)0x20e); - public const int ShiftCtrlKeyLeft = unchecked((int)0x222); - public const int ShiftCtrlKeyRight = unchecked((int)0x231); - public const int ShiftCtrlKeyNPage = unchecked((int)0x227); - public const int ShiftCtrlKeyPPage = unchecked((int)0x22c); - public const int ShiftCtrlKeyHome = unchecked((int)0x218); - public const int ShiftCtrlKeyEnd = unchecked((int)0x213); + public const int AltKeyUp = unchecked((int)0x234 + LeftRightUpNPagePPage); + public const int AltKeyDown = unchecked((int)0x20b + DownEnd); + public const int AltKeyLeft = unchecked((int)0x21f + LeftRightUpNPagePPage); + public const int AltKeyRight = unchecked((int)0x22e + LeftRightUpNPagePPage); + public const int AltKeyNPage = unchecked((int)0x224 + LeftRightUpNPagePPage); + public const int AltKeyPPage = unchecked((int)0x229 + LeftRightUpNPagePPage); + public const int AltKeyHome = unchecked((int)0x215 + Home); + public const int AltKeyEnd = unchecked((int)0x210 + DownEnd); + public const int CtrlKeyUp = unchecked((int)0x236 + LeftRightUpNPagePPage); + public const int CtrlKeyDown = unchecked((int)0x20d + DownEnd); + public const int CtrlKeyLeft = unchecked((int)0x221 + LeftRightUpNPagePPage); + public const int CtrlKeyRight = unchecked((int)0x230 + LeftRightUpNPagePPage); + public const int CtrlKeyNPage = unchecked((int)0x226 + LeftRightUpNPagePPage); + public const int CtrlKeyPPage = unchecked((int)0x22b + LeftRightUpNPagePPage); + public const int CtrlKeyHome = unchecked((int)0x217 + Home); + public const int CtrlKeyEnd = unchecked((int)0x212 + DownEnd); + public const int ShiftCtrlKeyUp = unchecked((int)0x237 + LeftRightUpNPagePPage); + public const int ShiftCtrlKeyDown = unchecked((int)0x20e + DownEnd); + public const int ShiftCtrlKeyLeft = unchecked((int)0x222 + LeftRightUpNPagePPage); + public const int ShiftCtrlKeyRight = unchecked((int)0x231 + LeftRightUpNPagePPage); + public const int ShiftCtrlKeyNPage = unchecked((int)0x227 + LeftRightUpNPagePPage); + public const int ShiftCtrlKeyPPage = unchecked((int)0x22c + LeftRightUpNPagePPage); + public const int ShiftCtrlKeyHome = unchecked((int)0x218 + Home); + public const int ShiftCtrlKeyEnd = unchecked((int)0x213 + DownEnd); public const int LC_ALL = 6; static public int ColorPair(int n){ diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 16b7c0b87..d6438a8a4 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -562,6 +562,7 @@ namespace Terminal.Gui { } bool openedByAltKey; + /// public override bool OnKeyDown (KeyEvent keyEvent) { diff --git a/UICatalog/Program.cs b/UICatalog/Program.cs index f81df07df..3a4c1054d 100644 --- a/UICatalog/Program.cs +++ b/UICatalog/Program.cs @@ -148,6 +148,7 @@ namespace UICatalog { } _top = Application.Top; + _top.KeyUp += KeyUpHandler; _top.Add (_menu); _top.Add (_leftPane); diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index 4f3b4da4e..3584709b6 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -43,8 +43,8 @@ namespace UICatalog { public override bool ProcessColdKey (KeyEvent keyEvent) { _processColdKeyList.Add (keyEvent.ToString ()); - return base.ProcessColdKey (keyEvent); + return base.ProcessColdKey (keyEvent); } }