From 96c30788b007f5e22a3681af661484d89d08491a Mon Sep 17 00:00:00 2001 From: Kevin Azzam Date: Fri, 9 Oct 2015 23:56:19 +0200 Subject: [PATCH 1/5] Add hotkeys for TextFieldWidget including: - ctrl+left/ctrl+right (cmd on osx) (back/forward by a word) - ctrl+backspace/ctrl+delete (alt on osx) (delete word) - ctrl+k/ctrl+u (cmd+delete/cmd+backspace on osx) (delete line from cursor) - ctrl+x (cmd on osx) (deletes line) --- OpenRA.Mods.Common/Widgets/TextFieldWidget.cs | 114 ++++++++++++++++-- 1 file changed, 107 insertions(+), 7 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs index f48c3d7ed5..330de7b869 100644 --- a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs @@ -127,18 +127,51 @@ namespace OpenRA.Mods.Common.Widgets if (e.Key == Keycode.LALT && OnAltKey()) return true; + Func getPrevWhitespaceIndex = () => + Text.Substring(0, CursorPosition).TrimEnd().LastIndexOf(' ') + 1; + + Func getNextWhitespaceIndex = () => { + var substr_len = Text.Substring(CursorPosition).Length; + var substr_trimmed = Text.Substring(CursorPosition).TrimStart(); + var trimmed_spaces = substr_len - substr_trimmed.Length; + var next_whitespace = substr_trimmed.IndexOf(' '); + if (next_whitespace == -1) + return Text.Length; + else + return CursorPosition + trimmed_spaces + next_whitespace; + }; + if (e.Key == Keycode.LEFT) { if (CursorPosition > 0) - CursorPosition--; + { + if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) + { + CursorPosition = getPrevWhitespaceIndex(); + } + else + { + CursorPosition--; + } + } return true; } if (e.Key == Keycode.RIGHT) { - if (CursorPosition <= Text.Length - 1) - CursorPosition++; + if (CursorPosition <= Text.Length - 1) { + if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) + { + CursorPosition = getNextWhitespaceIndex(); + } + else + { + CursorPosition++; + } + } return true; } @@ -155,11 +188,61 @@ namespace OpenRA.Mods.Common.Widgets return true; } + if (e.Key == Keycode.K && e.Modifiers.HasModifier(Modifiers.Ctrl) && + (Platform.CurrentPlatform != PlatformType.OSX)) + { + // equivalent to cmd+delete on osx + if (CursorPosition < Text.Length) + { + Text = Text.Remove(CursorPosition); + OnTextEdited(); + } + + return true; + } + + if (e.Key == Keycode.U && e.Modifiers.HasModifier(Modifiers.Ctrl) && + (Platform.CurrentPlatform != PlatformType.OSX)) + { + // equivalent to cmd+backspace on osx + Text = Text.Substring(CursorPosition); + CursorPosition = 0; + OnTextEdited(); + return true; + } + + if (e.Key == Keycode.X && + ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)))) + { + if (!string.IsNullOrEmpty(Text)) + { + Text = Text.Remove(0); + CursorPosition = 0; + OnTextEdited(); + return true; + } + } + if (e.Key == Keycode.DELETE) { if (CursorPosition < Text.Length) { - Text = Text.Remove(CursorPosition, 1); + if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) + { + Text = Text.Substring(0, CursorPosition) + Text.Substring(getNextWhitespaceIndex()); + } + else if (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)) + { + // equivalent to ctrl+k on non-osx + Text = Text.Remove(CursorPosition); + } + else + { + Text = Text.Remove(CursorPosition, 1); + } + OnTextEdited(); } @@ -168,8 +251,25 @@ namespace OpenRA.Mods.Common.Widgets if (e.Key == Keycode.BACKSPACE && CursorPosition > 0) { - CursorPosition--; - Text = Text.Remove(CursorPosition, 1); + if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) + { + var prev_whitespace = getPrevWhitespaceIndex(); + Text = Text.Substring(0, prev_whitespace) + Text.Substring(CursorPosition); + CursorPosition = prev_whitespace; + } + else if (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)) + { + // equivalent to ctrl+u on non-osx + Text = Text.Substring(CursorPosition); + CursorPosition = 0; + } + else + { + CursorPosition--; + Text = Text.Remove(CursorPosition, 1); + } + OnTextEdited(); return true; } @@ -284,4 +384,4 @@ namespace OpenRA.Mods.Common.Widgets public override Widget Clone() { return new TextFieldWidget(this); } } -} \ No newline at end of file +} From 5e4ea69dbda1f31c8db4c2440520ad9787a86f7b Mon Sep 17 00:00:00 2001 From: Kevin Azzam Date: Sat, 10 Oct 2015 00:50:33 +0200 Subject: [PATCH 2/5] Refactor TextFieldWidget into much clearer and extensible code --- OpenRA.Mods.Common/Widgets/TextFieldWidget.cs | 277 +++++++++--------- 1 file changed, 132 insertions(+), 145 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs index 330de7b869..5984e6d16e 100644 --- a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs @@ -115,18 +115,6 @@ namespace OpenRA.Mods.Common.Widgets if (!HasKeyboardFocus) return false; - if ((e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER) && OnEnterKey()) - return true; - - if (e.Key == Keycode.TAB && OnTabKey()) - return true; - - if (e.Key == Keycode.ESCAPE && OnEscKey()) - return true; - - if (e.Key == Keycode.LALT && OnAltKey()) - return true; - Func getPrevWhitespaceIndex = () => Text.Substring(0, CursorPosition).TrimEnd().LastIndexOf(' ') + 1; @@ -141,157 +129,156 @@ namespace OpenRA.Mods.Common.Widgets return CursorPosition + trimmed_spaces + next_whitespace; }; - if (e.Key == Keycode.LEFT) - { - if (CursorPosition > 0) - { - if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) - { - CursorPosition = getPrevWhitespaceIndex(); - } - else - { - CursorPosition--; - } - } + Func isOSX = () => Platform.CurrentPlatform == PlatformType.OSX; - return true; - } + switch (e.Key) { + case Keycode.RETURN: + case Keycode.KP_ENTER: + if (OnEnterKey()) + return true; + break; - if (e.Key == Keycode.RIGHT) - { - if (CursorPosition <= Text.Length - 1) { - if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) - { - CursorPosition = getNextWhitespaceIndex(); - } - else - { - CursorPosition++; - } - } + case Keycode.TAB: + if (OnTabKey()) + return true; + break; - return true; - } + case Keycode.ESCAPE: + if (OnEscKey()) + return true; + break; - if (e.Key == Keycode.HOME) - { - CursorPosition = 0; - return true; - } + case Keycode.LALT: + if (OnAltKey()) + return true; + break; - if (e.Key == Keycode.END) - { - CursorPosition = Text.Length; - return true; - } + case Keycode.LEFT: + if (CursorPosition > 0) + if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + CursorPosition = getPrevWhitespaceIndex(); + else + CursorPosition--; + break; - if (e.Key == Keycode.K && e.Modifiers.HasModifier(Modifiers.Ctrl) && - (Platform.CurrentPlatform != PlatformType.OSX)) - { - // equivalent to cmd+delete on osx - if (CursorPosition < Text.Length) - { - Text = Text.Remove(CursorPosition); - OnTextEdited(); - } + case Keycode.RIGHT: + if (CursorPosition <= Text.Length - 1) + if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + CursorPosition = getNextWhitespaceIndex(); + else + CursorPosition++; - return true; - } + break; - if (e.Key == Keycode.U && e.Modifiers.HasModifier(Modifiers.Ctrl) && - (Platform.CurrentPlatform != PlatformType.OSX)) - { - // equivalent to cmd+backspace on osx - Text = Text.Substring(CursorPosition); - CursorPosition = 0; - OnTextEdited(); - return true; - } - - if (e.Key == Keycode.X && - ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)))) - { - if (!string.IsNullOrEmpty(Text)) - { - Text = Text.Remove(0); + case Keycode.HOME: CursorPosition = 0; - OnTextEdited(); - return true; - } - } + break; - if (e.Key == Keycode.DELETE) - { - if (CursorPosition < Text.Length) - { - if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) + case Keycode.END: + CursorPosition = Text.Length; + break; + + case Keycode.K: + // ctrl+k is equivalent to cmd+delete on osx + if (!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) { - Text = Text.Substring(0, CursorPosition) + Text.Substring(getNextWhitespaceIndex()); - } - else if (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)) - { - // equivalent to ctrl+k on non-osx Text = Text.Remove(CursorPosition); + OnTextEdited(); } - else + + break; + + case Keycode.U: + // ctrl+u is equivalent to cmd+backspace on osx + if (!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition > 0) { - Text = Text.Remove(CursorPosition, 1); + Text = Text.Substring(CursorPosition); + CursorPosition = 0; + OnTextEdited(); } - OnTextEdited(); + break; + + case Keycode.X: + if (((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta))) && + (!string.IsNullOrEmpty(Text))) + { + Text = Text.Remove(0); + CursorPosition = 0; + OnTextEdited(); + } + + break; + + case Keycode.DELETE: + // cmd+delete is equivalent to ctrl+k on non-osx + if (CursorPosition < Text.Length) + { + if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + Text = Text.Substring(0, CursorPosition) + Text.Substring(getNextWhitespaceIndex()); + else if (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta)) + Text = Text.Remove(CursorPosition); + else + Text = Text.Remove(CursorPosition, 1); + + OnTextEdited(); + } + + break; + + case Keycode.BACKSPACE: + // cmd+backspace is equivalent to ctrl+u on non-osx + if (CursorPosition > 0) + { + if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + { + var prev_whitespace = getPrevWhitespaceIndex(); + Text = Text.Substring(0, prev_whitespace) + Text.Substring(CursorPosition); + CursorPosition = prev_whitespace; + } + else if (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta)) + { + Text = Text.Substring(CursorPosition); + CursorPosition = 0; + } + else + { + CursorPosition--; + Text = Text.Remove(CursorPosition, 1); + } + + OnTextEdited(); + } + + break; + + case Keycode.V: + if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta))) + { + var clipboardText = Game.Renderer.GetClipboardText(); + + // Take only the first line of the clipboard contents + var nl = clipboardText.IndexOf('\n'); + if (nl > 0) + clipboardText = clipboardText.Substring(0, nl); + + clipboardText = clipboardText.Trim(); + if (clipboardText.Length > 0) + HandleTextInput(clipboardText); + } + + break; + + default: + break; } - return true; - } - - if (e.Key == Keycode.BACKSPACE && CursorPosition > 0) - { - if ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Alt))) - { - var prev_whitespace = getPrevWhitespaceIndex(); - Text = Text.Substring(0, prev_whitespace) + Text.Substring(CursorPosition); - CursorPosition = prev_whitespace; - } - else if (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)) - { - // equivalent to ctrl+u on non-osx - Text = Text.Substring(CursorPosition); - CursorPosition = 0; - } - else - { - CursorPosition--; - Text = Text.Remove(CursorPosition, 1); - } - - OnTextEdited(); - return true; - } - - if (e.Key == Keycode.V && - ((Platform.CurrentPlatform != PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (Platform.CurrentPlatform == PlatformType.OSX && e.Modifiers.HasModifier(Modifiers.Meta)))) - { - var clipboardText = Game.Renderer.GetClipboardText(); - - // Take only the first line of the clipboard contents - var nl = clipboardText.IndexOf('\n'); - if (nl > 0) - clipboardText = clipboardText.Substring(0, nl); - - clipboardText = clipboardText.Trim(); - if (clipboardText.Length > 0) - HandleTextInput(clipboardText); - - return true; - } - return true; } From fdf993ddda369259014e6df244eb5d89c31624be Mon Sep 17 00:00:00 2001 From: Kevin Azzam Date: Sat, 10 Oct 2015 13:16:16 +0200 Subject: [PATCH 3/5] Reset cursor blinking after keyboard-activated cursor movement --- OpenRA.Mods.Common/Widgets/TextFieldWidget.cs | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs index 5984e6d16e..ee7b65859e 100644 --- a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs @@ -62,6 +62,12 @@ namespace OpenRA.Mods.Common.Widgets return base.YieldKeyboardFocus(); } + protected void ResetBlinkCycle() + { + blinkCycle = 10; + showCursor = true; + } + public override bool HandleMouseInput(MouseInput mi) { if (IsDisabled()) @@ -74,8 +80,7 @@ namespace OpenRA.Mods.Common.Widgets if (!RenderBounds.Contains(mi.Location) || !TakeKeyboardFocus()) return false; - blinkCycle = 10; - showCursor = true; + ResetBlinkCycle(); CursorPosition = ClosestCursorPosition(mi.Location.X); return true; } @@ -119,17 +124,17 @@ namespace OpenRA.Mods.Common.Widgets Text.Substring(0, CursorPosition).TrimEnd().LastIndexOf(' ') + 1; Func getNextWhitespaceIndex = () => { - var substr_len = Text.Substring(CursorPosition).Length; - var substr_trimmed = Text.Substring(CursorPosition).TrimStart(); - var trimmed_spaces = substr_len - substr_trimmed.Length; - var next_whitespace = substr_trimmed.IndexOf(' '); - if (next_whitespace == -1) + var substr = Text.Substring(CursorPosition); + var substrTrimmed = substr.TrimStart(); + var trimmedSpaces = substr.Length - substrTrimmed.Length; + var nextWhitespace = substrTrimmed.IndexOf(' '); + if (nextWhitespace == -1) return Text.Length; else - return CursorPosition + trimmed_spaces + next_whitespace; + return CursorPosition + trimmedSpaces + nextWhitespace; }; - Func isOSX = () => Platform.CurrentPlatform == PlatformType.OSX; + var isOSX = Platform.CurrentPlatform == PlatformType.OSX; switch (e.Key) { case Keycode.RETURN: @@ -154,18 +159,20 @@ namespace OpenRA.Mods.Common.Widgets break; case Keycode.LEFT: + ResetBlinkCycle(); if (CursorPosition > 0) - if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) CursorPosition = getPrevWhitespaceIndex(); else CursorPosition--; break; case Keycode.RIGHT: + ResetBlinkCycle(); if (CursorPosition <= Text.Length - 1) - if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) CursorPosition = getNextWhitespaceIndex(); else CursorPosition++; @@ -173,16 +180,19 @@ namespace OpenRA.Mods.Common.Widgets break; case Keycode.HOME: + ResetBlinkCycle(); CursorPosition = 0; break; case Keycode.END: + ResetBlinkCycle(); CursorPosition = Text.Length; break; case Keycode.K: // ctrl+k is equivalent to cmd+delete on osx - if (!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) + ResetBlinkCycle(); + if (!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) { Text = Text.Remove(CursorPosition); OnTextEdited(); @@ -192,7 +202,8 @@ namespace OpenRA.Mods.Common.Widgets case Keycode.U: // ctrl+u is equivalent to cmd+backspace on osx - if (!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition > 0) + ResetBlinkCycle(); + if (!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition > 0) { Text = Text.Substring(CursorPosition); CursorPosition = 0; @@ -202,8 +213,9 @@ namespace OpenRA.Mods.Common.Widgets break; case Keycode.X: - if (((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta))) && + ResetBlinkCycle(); + if (((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))) && (!string.IsNullOrEmpty(Text))) { Text = Text.Remove(0); @@ -215,12 +227,13 @@ namespace OpenRA.Mods.Common.Widgets case Keycode.DELETE: // cmd+delete is equivalent to ctrl+k on non-osx + ResetBlinkCycle(); if (CursorPosition < Text.Length) { - if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) Text = Text.Substring(0, CursorPosition) + Text.Substring(getNextWhitespaceIndex()); - else if (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta)) + else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) Text = Text.Remove(CursorPosition); else Text = Text.Remove(CursorPosition, 1); @@ -232,16 +245,17 @@ namespace OpenRA.Mods.Common.Widgets case Keycode.BACKSPACE: // cmd+backspace is equivalent to ctrl+u on non-osx + ResetBlinkCycle(); if (CursorPosition > 0) { - if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX() && e.Modifiers.HasModifier(Modifiers.Alt))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) { var prev_whitespace = getPrevWhitespaceIndex(); Text = Text.Substring(0, prev_whitespace) + Text.Substring(CursorPosition); CursorPosition = prev_whitespace; } - else if (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta)) + else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) { Text = Text.Substring(CursorPosition); CursorPosition = 0; @@ -258,8 +272,9 @@ namespace OpenRA.Mods.Common.Widgets break; case Keycode.V: - if ((!isOSX() && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX() && e.Modifiers.HasModifier(Modifiers.Meta))) + ResetBlinkCycle(); + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || + (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))) { var clipboardText = Game.Renderer.GetClipboardText(); From 96c0c2dec669c8b1f3fbd3e3956215ee6ac755d5 Mon Sep 17 00:00:00 2001 From: Kevin Azzam Date: Sat, 10 Oct 2015 13:49:23 +0200 Subject: [PATCH 4/5] Make ctrl+x cut to clipboard --- OpenRA.Game/Graphics/IGraphicsDevice.cs | 1 + OpenRA.Game/Renderer.cs | 5 +++ OpenRA.Mods.Common/Widgets/TextFieldWidget.cs | 32 +++++++++---------- .../Sdl2GraphicsDevice.cs | 6 ++++ OpenRA.Platforms.Default/Sdl2Input.cs | 3 +- OpenRA.Platforms.Null/NullGraphicsDevice.cs | 1 + 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/OpenRA.Game/Graphics/IGraphicsDevice.cs b/OpenRA.Game/Graphics/IGraphicsDevice.cs index deb7ee4b48..4f35983d28 100644 --- a/OpenRA.Game/Graphics/IGraphicsDevice.cs +++ b/OpenRA.Game/Graphics/IGraphicsDevice.cs @@ -61,6 +61,7 @@ namespace OpenRA Bitmap TakeScreenshot(); void PumpInput(IInputHandler inputHandler); string GetClipboardText(); + bool SetClipboardText(string text); void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices); void SetLineWidth(float width); diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index 25206015a4..6e01b39813 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -267,5 +267,10 @@ namespace OpenRA { return Device.GetClipboardText(); } + + public bool SetClipboardText(string text) + { + return Device.SetClipboardText(text); + } } } diff --git a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs index ee7b65859e..0caf248560 100644 --- a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs @@ -123,15 +123,15 @@ namespace OpenRA.Mods.Common.Widgets Func getPrevWhitespaceIndex = () => Text.Substring(0, CursorPosition).TrimEnd().LastIndexOf(' ') + 1; - Func getNextWhitespaceIndex = () => { + Func getNextWhitespaceIndex = () => + { var substr = Text.Substring(CursorPosition); var substrTrimmed = substr.TrimStart(); var trimmedSpaces = substr.Length - substrTrimmed.Length; var nextWhitespace = substrTrimmed.IndexOf(' '); if (nextWhitespace == -1) return Text.Length; - else - return CursorPosition + trimmedSpaces + nextWhitespace; + return CursorPosition + trimmedSpaces + nextWhitespace; }; var isOSX = Platform.CurrentPlatform == PlatformType.OSX; @@ -161,21 +161,24 @@ namespace OpenRA.Mods.Common.Widgets case Keycode.LEFT: ResetBlinkCycle(); if (CursorPosition > 0) - if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) + { + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) CursorPosition = getPrevWhitespaceIndex(); else CursorPosition--; + } + break; case Keycode.RIGHT: ResetBlinkCycle(); if (CursorPosition <= Text.Length - 1) - if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) + { + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) CursorPosition = getNextWhitespaceIndex(); else CursorPosition++; + } break; @@ -214,10 +217,10 @@ namespace OpenRA.Mods.Common.Widgets case Keycode.X: ResetBlinkCycle(); - if (((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))) && - (!string.IsNullOrEmpty(Text))) + if (((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))) && + !string.IsNullOrEmpty(Text)) { + Game.Renderer.SetClipboardText(Text); Text = Text.Remove(0); CursorPosition = 0; OnTextEdited(); @@ -230,8 +233,7 @@ namespace OpenRA.Mods.Common.Widgets ResetBlinkCycle(); if (CursorPosition < Text.Length) { - if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) Text = Text.Substring(0, CursorPosition) + Text.Substring(getNextWhitespaceIndex()); else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) Text = Text.Remove(CursorPosition); @@ -248,8 +250,7 @@ namespace OpenRA.Mods.Common.Widgets ResetBlinkCycle(); if (CursorPosition > 0) { - if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) { var prev_whitespace = getPrevWhitespaceIndex(); Text = Text.Substring(0, prev_whitespace) + Text.Substring(CursorPosition); @@ -273,8 +274,7 @@ namespace OpenRA.Mods.Common.Widgets case Keycode.V: ResetBlinkCycle(); - if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || - (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))) + if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))) { var clipboardText = Game.Renderer.GetClipboardText(); diff --git a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs index edcfcf5bcf..51fbbfb5f0 100644 --- a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs +++ b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs @@ -382,6 +382,12 @@ namespace OpenRA.Platforms.Default return input.GetClipboardText(); } + public bool SetClipboardText(string text) + { + VerifyThreadAffinity(); + return input.SetClipboardText(text); + } + public IVertexBuffer CreateVertexBuffer(int size) { VerifyThreadAffinity(); diff --git a/OpenRA.Platforms.Default/Sdl2Input.cs b/OpenRA.Platforms.Default/Sdl2Input.cs index 2582876ffc..48c078306a 100644 --- a/OpenRA.Platforms.Default/Sdl2Input.cs +++ b/OpenRA.Platforms.Default/Sdl2Input.cs @@ -20,6 +20,7 @@ namespace OpenRA.Platforms.Default MouseButton lastButtonBits = (MouseButton)0; public string GetClipboardText() { return SDL.SDL_GetClipboardText(); } + public bool SetClipboardText(string text) { return SDL.SDL_SetClipboardText(text) == 0; } static MouseButton MakeButton(byte b) { @@ -177,4 +178,4 @@ namespace OpenRA.Platforms.Default ErrorHandler.CheckGlError(); } } -} \ No newline at end of file +} diff --git a/OpenRA.Platforms.Null/NullGraphicsDevice.cs b/OpenRA.Platforms.Null/NullGraphicsDevice.cs index b6a9174b63..c8ff2b75c4 100644 --- a/OpenRA.Platforms.Null/NullGraphicsDevice.cs +++ b/OpenRA.Platforms.Null/NullGraphicsDevice.cs @@ -42,6 +42,7 @@ namespace OpenRA.Platforms.Null public Bitmap TakeScreenshot() { return new Bitmap(1, 1); } public string GetClipboardText() { return ""; } + public bool SetClipboardText(string text) { return false; } public void PumpInput(IInputHandler ih) { Game.HasInputFocus = false; From 3c79e9075b6f0ef5756f8db4513aad8af81b76f5 Mon Sep 17 00:00:00 2001 From: Kevin Azzam Date: Mon, 12 Oct 2015 19:48:23 +0200 Subject: [PATCH 5/5] Add some hotkeys for OSX (cmd + arrow_keys, ctrl + k, and ctrl + d) --- OpenRA.Mods.Common/Widgets/TextFieldWidget.cs | 62 ++++++++++++------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs index 0caf248560..d30f5eacb0 100644 --- a/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs +++ b/OpenRA.Mods.Common/Widgets/TextFieldWidget.cs @@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Widgets protected virtual string GetApparentText() { return text; } - public int ClosestCursorPosition(int x) + int ClosestCursorPosition(int x) { var apparentText = GetApparentText(); var font = Game.Renderer.Fonts[Font]; @@ -111,6 +111,23 @@ namespace OpenRA.Mods.Common.Widgets return minIndex; } + int GetPrevWhitespaceIndex() + { + return Text.Substring(0, CursorPosition).TrimEnd().LastIndexOf(' ') + 1; + } + + int GetNextWhitespaceIndex() + { + var substr = Text.Substring(CursorPosition); + var substrTrimmed = substr.TrimStart(); + var trimmedSpaces = substr.Length - substrTrimmed.Length; + var nextWhitespace = substrTrimmed.IndexOf(' '); + if (nextWhitespace == -1) + return Text.Length; + + return CursorPosition + trimmedSpaces + nextWhitespace; + } + public override bool HandleKeyPress(KeyInput e) { if (IsDisabled() || e.Event == KeyInputEvent.Up) @@ -120,20 +137,6 @@ namespace OpenRA.Mods.Common.Widgets if (!HasKeyboardFocus) return false; - Func getPrevWhitespaceIndex = () => - Text.Substring(0, CursorPosition).TrimEnd().LastIndexOf(' ') + 1; - - Func getNextWhitespaceIndex = () => - { - var substr = Text.Substring(CursorPosition); - var substrTrimmed = substr.TrimStart(); - var trimmedSpaces = substr.Length - substrTrimmed.Length; - var nextWhitespace = substrTrimmed.IndexOf(' '); - if (nextWhitespace == -1) - return Text.Length; - return CursorPosition + trimmedSpaces + nextWhitespace; - }; - var isOSX = Platform.CurrentPlatform == PlatformType.OSX; switch (e.Key) { @@ -163,7 +166,9 @@ namespace OpenRA.Mods.Common.Widgets if (CursorPosition > 0) { if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) - CursorPosition = getPrevWhitespaceIndex(); + CursorPosition = GetPrevWhitespaceIndex(); + else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) + CursorPosition = 0; else CursorPosition--; } @@ -175,7 +180,9 @@ namespace OpenRA.Mods.Common.Widgets if (CursorPosition <= Text.Length - 1) { if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) - CursorPosition = getNextWhitespaceIndex(); + CursorPosition = GetNextWhitespaceIndex(); + else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) + CursorPosition = Text.Length; else CursorPosition++; } @@ -192,10 +199,19 @@ namespace OpenRA.Mods.Common.Widgets CursorPosition = Text.Length; break; + case Keycode.D: + if (e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) + { + Text = Text.Remove(CursorPosition, 1); + OnTextEdited(); + } + + break; + case Keycode.K: - // ctrl+k is equivalent to cmd+delete on osx + // ctrl+k is equivalent to cmd+delete on osx (but also works on osx) ResetBlinkCycle(); - if (!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) + if (e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) { Text = Text.Remove(CursorPosition); OnTextEdited(); @@ -234,7 +250,7 @@ namespace OpenRA.Mods.Common.Widgets if (CursorPosition < Text.Length) { if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) - Text = Text.Substring(0, CursorPosition) + Text.Substring(getNextWhitespaceIndex()); + Text = Text.Substring(0, CursorPosition) + Text.Substring(GetNextWhitespaceIndex()); else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) Text = Text.Remove(CursorPosition); else @@ -252,9 +268,9 @@ namespace OpenRA.Mods.Common.Widgets { if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) { - var prev_whitespace = getPrevWhitespaceIndex(); - Text = Text.Substring(0, prev_whitespace) + Text.Substring(CursorPosition); - CursorPosition = prev_whitespace; + var prevWhitespace = GetPrevWhitespaceIndex(); + Text = Text.Substring(0, prevWhitespace) + Text.Substring(CursorPosition); + CursorPosition = prevWhitespace; } else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) {