diff --git a/AUTHORS b/AUTHORS index f2870c679f..07db2afcc4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -42,6 +42,7 @@ Also thanks to: * Gordon Martin (Happy0) * Ian T. Jacobsen (Smilex) * Igor Popov (ihptru) + * Imago * Iran * James Dunne (jsd) * Jason (atlimit8) diff --git a/OpenRA.Game/Graphics/IGraphicsDevice.cs b/OpenRA.Game/Graphics/IGraphicsDevice.cs index 8c28531bf0..d8214007f7 100755 --- a/OpenRA.Game/Graphics/IGraphicsDevice.cs +++ b/OpenRA.Game/Graphics/IGraphicsDevice.cs @@ -47,7 +47,7 @@ namespace OpenRA void Clear(); void Present(); void PumpInput(IInputHandler inputHandler); - + string GetClipboardText(); void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices); void SetLineWidth(float width); diff --git a/OpenRA.Game/Widgets/TextFieldWidget.cs b/OpenRA.Game/Widgets/TextFieldWidget.cs index fe26485bd4..810454af5c 100644 --- a/OpenRA.Game/Widgets/TextFieldWidget.cs +++ b/OpenRA.Game/Widgets/TextFieldWidget.cs @@ -42,7 +42,7 @@ namespace OpenRA.Widgets public Color TextColorDisabled = ChromeMetrics.Get("TextfieldColorDisabled"); public Color TextColorInvalid = ChromeMetrics.Get("TextfieldColorInvalid"); - public TextFieldWidget() {} + public TextFieldWidget() { } protected TextFieldWidget(TextFieldWidget widget) : base(widget) { @@ -101,6 +101,7 @@ namespace OpenRA.Widgets minValue = dist; minIndex = i; } + return minIndex; } @@ -135,7 +136,7 @@ namespace OpenRA.Widgets if (e.Key == Keycode.RIGHT) { - if (CursorPosition <= Text.Length-1) + if (CursorPosition <= Text.Length - 1) CursorPosition++; return true; @@ -160,6 +161,7 @@ namespace OpenRA.Widgets Text = Text.Remove(CursorPosition, 1); OnTextEdited(); } + return true; } @@ -168,6 +170,25 @@ namespace OpenRA.Widgets 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.Device.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; @@ -181,8 +202,14 @@ namespace OpenRA.Widgets if (MaxLength > 0 && Text.Length >= MaxLength) return true; - Text = Text.Insert(CursorPosition, text); - CursorPosition++; + var pasteLength = text.Length; + + // Truncate the pasted string if the total length (current + paste) is greater than the maximum. + if (MaxLength > 0 && MaxLength > Text.Length) + pasteLength = Math.Min(text.Length, MaxLength - Text.Length); + + Text = Text.Insert(CursorPosition, text.Substring(0, pasteLength)); + CursorPosition += pasteLength; OnTextEdited(); return true; diff --git a/OpenRA.Renderer.Null/NullGraphicsDevice.cs b/OpenRA.Renderer.Null/NullGraphicsDevice.cs index c367a94ce3..3e2d8d6f67 100644 --- a/OpenRA.Renderer.Null/NullGraphicsDevice.cs +++ b/OpenRA.Renderer.Null/NullGraphicsDevice.cs @@ -51,6 +51,7 @@ namespace OpenRA.Renderer.Null public void Clear() { } public void Present() { } + public string GetClipboardText() { return ""; } public void PumpInput(IInputHandler ih) { Game.HasInputFocus = false; diff --git a/OpenRA.Renderer.Sdl2/Sdl2GraphicsDevice.cs b/OpenRA.Renderer.Sdl2/Sdl2GraphicsDevice.cs index 9549640352..dce2c1bd73 100755 --- a/OpenRA.Renderer.Sdl2/Sdl2GraphicsDevice.cs +++ b/OpenRA.Renderer.Sdl2/Sdl2GraphicsDevice.cs @@ -238,6 +238,7 @@ namespace OpenRA.Renderer.Sdl2 public void Present() { SDL.SDL_GL_SwapWindow(window); } public void PumpInput(IInputHandler inputHandler) { input.PumpInput(inputHandler); } + public string GetClipboardText() { return input.GetClipboardText(); } public IVertexBuffer CreateVertexBuffer(int size) { return new VertexBuffer(size); } public ITexture CreateTexture() { return new Texture(); } public ITexture CreateTexture(Bitmap bitmap) { return new Texture(bitmap); } diff --git a/OpenRA.Renderer.Sdl2/Sdl2Input.cs b/OpenRA.Renderer.Sdl2/Sdl2Input.cs index 5769181ce2..be609f4064 100644 --- a/OpenRA.Renderer.Sdl2/Sdl2Input.cs +++ b/OpenRA.Renderer.Sdl2/Sdl2Input.cs @@ -8,6 +8,8 @@ */ #endregion +using System; +using System.Runtime.InteropServices; using System.Text; using SDL2; @@ -17,6 +19,8 @@ namespace OpenRA.Renderer.Sdl2 { MouseButton lastButtonBits = (MouseButton)0; + public string GetClipboardText() { return SDL.SDL_GetClipboardText(); } + static MouseButton MakeButton(byte b) { return b == SDL.SDL_BUTTON_LEFT ? MouseButton.Left @@ -126,24 +130,9 @@ namespace OpenRA.Renderer.Sdl2 case SDL.SDL_EventType.SDL_TEXTINPUT: { - string input; - unsafe - { - var data = new byte[SDL.SDL_TEXTINPUTEVENT_TEXT_SIZE]; - var i = 0; - for (; i < SDL.SDL_TEXTINPUTEVENT_TEXT_SIZE; i++) - { - var b = e.text.text[i]; - if (b == '\0') - break; - - data[i] = b; - } - - input = Encoding.UTF8.GetString(data, 0, i); - } - - inputHandler.OnTextInput(input); + var rawBytes = new byte[SDL.SDL_TEXTINPUTEVENT_TEXT_SIZE]; + unsafe { Marshal.Copy((IntPtr)e.text.text, rawBytes, 0, SDL.SDL_TEXTINPUTEVENT_TEXT_SIZE); } + inputHandler.OnTextInput(Encoding.UTF8.GetString(rawBytes, 0, Array.IndexOf(rawBytes, (byte)0))); break; }