/// <summary> /// Utility to apply the result of pressing keys against a buffer /// </summary> /// <param name="buffer"></param> /// <param name="keys"></param> public KeyboardInputResult ApplyKeyboardInput(StringBuilder m_SBuilder, UpdateState state, int cursorIndex, int cursorEndIndex, bool allowInput) { var PressedKeys = state.KeyboardState.GetPressedKeys(); int charCount = 0; if (state.FrameTextInput == null) { charCount = 0; } else { charCount = state.FrameTextInput.Count; } if (PressedKeys.Length + charCount == 0) { return(null); } //bit of a legacy thing going on here //we support both "pressed keys" and the keyboard event system. //todo: clean up a bit var didChange = false; var result = new KeyboardInputResult(); var m_CurrentKeyState = state.KeyboardState; var m_OldKeyState = state.PreviousKeyboardState; result.ShiftDown = PressedKeys.Contains(Keys.LeftShift) || PressedKeys.Contains(Keys.RightShift); result.CapsDown = System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock); result.NumLockDown = System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.NumLock); result.CtrlDown = PressedKeys.Contains(Keys.LeftControl) || PressedKeys.Contains(Keys.RightControl); for (int j = 0; j < state.NewKeys.Count + charCount; j++) { var key = (j < state.NewKeys.Count)?state.NewKeys[j]:Keys.None; bool processChar = true; if (key != Keys.None) { processChar = false; if (key == Keys.Back || key == Keys.Delete) { if (m_SBuilder.Length > 0) { /** * Delete previous character or delete selection */ if (cursorEndIndex == -1 && result.CtrlDown) { /** Delete up until the previous whitespace char **/ int newEndIndex = cursorIndex; if (newEndIndex == -1) { newEndIndex = m_SBuilder.Length - 1; } while (newEndIndex >= 0) { if (Char.IsWhiteSpace(m_SBuilder[newEndIndex])) { /** Keep the whitespace char **/ newEndIndex++; break; } newEndIndex--; } cursorEndIndex = newEndIndex; } if (cursorEndIndex == -1) { /** Previous character **/ var index = cursorIndex == -1 ? m_SBuilder.Length : cursorIndex; if ((key == Keys.Back) && (index > 0)) { var numToDelete = 1; if (index > 1 && m_SBuilder[index - 1] == '\n' && m_SBuilder[index - 2] == '\r') { numToDelete = 2; } m_SBuilder.Remove(index - numToDelete, numToDelete); result.NumDeletes += numToDelete; if (cursorIndex != -1) { cursorIndex -= numToDelete; } } else if ((key == Keys.Delete) && (index < m_SBuilder.Length)) { /** Guys, delete removes the next character, not the last!! **/ var numToDelete = 1; if ((index < m_SBuilder.Length - 1) && m_SBuilder[index] == '\r' && m_SBuilder[index + 1] == '\n') { numToDelete = 2; } m_SBuilder.Remove(index, numToDelete); result.NumDeletes += numToDelete; } } else { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } result.SelectionChanged = true; didChange = true; } } else if (key == Keys.Enter) { if (allowInput) { /** Line break **/ if (cursorEndIndex != -1) { /** Delete selected text **/ DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } if (cursorIndex == -1) { m_SBuilder.Append("\r\n"); } else { m_SBuilder.Insert(cursorIndex, "\r\n"); cursorIndex += 2; } result.NumInsertions += 2; didChange = true; result.EnterPressed = true; } } else if (key == Keys.Tab) { result.TabPressed = true; } else if (result.CtrlDown) { if (key != Keys.LeftControl) { } switch (key) { case Keys.A: /** Select all **/ cursorIndex = 0; cursorEndIndex = m_SBuilder.Length; result.SelectionChanged = true; break; case Keys.C: case Keys.X: /** Copy text to clipboard **/ if (cursorEndIndex != -1) { var selectionStart = Math.Max(0, cursorIndex); var selectionEnd = cursorEndIndex; GetSelectionRange(ref selectionStart, ref selectionEnd); var str = m_SBuilder.ToString().Substring(selectionStart, selectionEnd - selectionStart); System.Windows.Forms.Clipboard.SetText((String.IsNullOrEmpty(str)) ? " " : str); if (key == Keys.X) { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } } break; case Keys.V: /** Paste text in **/ var clipboardText = System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text); if (clipboardText != null) { /** TODO: Cleanup the clipboard text to make sure its valid **/ /** If i have selection, delete it **/ if (cursorEndIndex != -1) { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } /** Paste **/ if (cursorIndex == -1) { m_SBuilder.Append(clipboardText); } else { m_SBuilder.Insert(Math.Min(cursorIndex, m_SBuilder.Length), clipboardText); cursorIndex += clipboardText.Length; } result.NumInsertions += clipboardText.Length; didChange = true; } break; } } else { processChar = true; } } if (processChar) { char value; if (j >= state.NewKeys.Count) { value = state.FrameTextInput[j - state.NewKeys.Count]; } else if (state.FrameTextInput != null) { continue; } else { value = TranslateChar(key, result.ShiftDown, result.CapsDown, result.NumLockDown); } /** For now we dont support tabs in text **/ if (value != '\0' && value != '\t' && value != '\b' && value != '\r') { if (allowInput) { if (cursorEndIndex != -1) { /** Delete selected text **/ DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } if (cursorIndex == -1) { m_SBuilder.Append(value); } else { m_SBuilder.Insert(cursorIndex, value); cursorIndex++; } result.NumInsertions++; didChange = true; } } else { result.UnhandledKeys.Add(key); } } } result.SelectionStart = cursorIndex; result.SelectionEnd = cursorEndIndex; result.ContentChanged = didChange; return(result); }
private void DeleteSelectedText(StringBuilder m_SBuilder, ref int cursorIndex, ref int cursorEndIndex, ref bool didChange, KeyboardInputResult result) { /** Remove selected text **/ var index = cursorIndex == -1 ? m_SBuilder.Length : cursorIndex; var end = cursorEndIndex; if (end < index) { var temp = index; index = end; end = temp; } m_SBuilder.Remove(index, end - index); cursorIndex = index; if (cursorIndex >= m_SBuilder.Length) { cursorIndex = -1; } cursorEndIndex = -1; result.SelectionChanged = true; didChange = true; }
/// <summary> /// Utility to apply the result of pressing keys against a buffer /// </summary> /// <param name="buffer"></param> /// <param name="keys"></param> public KeyboardInputResult ApplyKeyboardInput(StringBuilder m_SBuilder, UpdateState state, int cursorIndex, int cursorEndIndex, bool allowInput) { var PressedKeys = state.KeyboardState.GetPressedKeys(); int charCount = 0; if (state.FrameTextInput == null) charCount = 0; else charCount = state.FrameTextInput.Count; if (PressedKeys.Length + charCount == 0) { return null; } //bit of a legacy thing going on here //we support both "pressed keys" and the keyboard event system. //todo: clean up a bit var didChange = false; var result = new KeyboardInputResult(); var m_CurrentKeyState = state.KeyboardState; var m_OldKeyState = state.PreviousKeyboardState; result.ShiftDown = PressedKeys.Contains(Keys.LeftShift) || PressedKeys.Contains(Keys.RightShift); result.CapsDown = state.KeyboardState.CapsLock; result.NumLockDown = state.KeyboardState.NumLock; result.CtrlDown = PressedKeys.Contains(Keys.LeftControl) || PressedKeys.Contains(Keys.RightControl); for (int j = 0; j < state.NewKeys.Count + charCount; j++) { var key = (j<state.NewKeys.Count)?state.NewKeys[j]:Keys.None; bool processChar = true; if (key != Keys.None) { processChar = false; if (key == Keys.Back || key == Keys.Delete) { if (m_SBuilder.Length > 0) { /** * Delete previous character or delete selection */ if (cursorEndIndex == -1 && result.CtrlDown) { /** Delete up until the previous whitespace char **/ int newEndIndex = cursorIndex; if (newEndIndex == -1) { newEndIndex = m_SBuilder.Length - 1; } while (newEndIndex >= 0) { if (Char.IsWhiteSpace(m_SBuilder[newEndIndex])) { /** Keep the whitespace char **/ newEndIndex++; break; } newEndIndex--; } cursorEndIndex = newEndIndex; } if (cursorEndIndex == -1) { /** Previous character **/ var index = cursorIndex == -1 ? m_SBuilder.Length : cursorIndex; if ((key == Keys.Back) && (index > 0)) { var numToDelete = 1; if (index > 1 && m_SBuilder[index - 1] == '\n' && m_SBuilder[index - 2] == '\r') { numToDelete = 2; } m_SBuilder.Remove(index - numToDelete, numToDelete); result.NumDeletes += numToDelete; if (cursorIndex != -1) { cursorIndex -= numToDelete; } } else if ((key == Keys.Delete) && (index < m_SBuilder.Length)) { /** Guys, delete removes the next character, not the last!! **/ var numToDelete = 1; if ((index < m_SBuilder.Length - 1) && m_SBuilder[index] == '\r' && m_SBuilder[index + 1] == '\n') { numToDelete = 2; } m_SBuilder.Remove(index, numToDelete); result.NumDeletes += numToDelete; } } else { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } result.SelectionChanged = true; didChange = true; } } else if (key == Keys.Enter) { if (allowInput) { /** Line break **/ if (cursorEndIndex != -1) { /** Delete selected text **/ DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } if (cursorIndex == -1) { m_SBuilder.Append("\r\n"); } else { m_SBuilder.Insert(cursorIndex, "\r\n"); cursorIndex += 2; } result.NumInsertions += 2; didChange = true; result.EnterPressed = true; } } else if (key == Keys.Tab) { result.TabPressed = true; } else if (result.CtrlDown) { if (key != Keys.LeftControl) { } switch (key) { case Keys.A: /** Select all **/ cursorIndex = 0; cursorEndIndex = m_SBuilder.Length; result.SelectionChanged = true; break; case Keys.C: case Keys.X: /** Copy text to clipboard **/ if (cursorEndIndex > 0) { var selectionStart = Math.Max(0, cursorIndex); var selectionEnd = cursorEndIndex; GetSelectionRange(ref selectionStart, ref selectionEnd); var str = m_SBuilder.ToString().Substring(selectionStart, selectionEnd - selectionStart); var copyThread = new Thread(x => { //System.Windows.Forms.Clipboard.SetText((String.IsNullOrEmpty(str)) ? " " : str); }); copyThread.SetApartmentState(ApartmentState.STA); copyThread.Start(); if (key == Keys.X) { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } } break; case Keys.V: /** Paste text in **/ var wait = new AutoResetEvent(false); string clipboardText = ""; var clipThread = new Thread(x => { //clipboardText = System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text); wait.Set(); }); clipThread.SetApartmentState(ApartmentState.STA); clipThread.Start(); wait.WaitOne(); if (clipboardText != null) { /** TODO: Cleanup the clipboard text to make sure its valid **/ /** If i have selection, delete it **/ if (cursorEndIndex != -1) { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } /** Paste **/ if (cursorIndex == -1) { m_SBuilder.Append(clipboardText); } else { m_SBuilder.Insert(Math.Min(cursorIndex, m_SBuilder.Length), clipboardText); cursorIndex += clipboardText.Length; } result.NumInsertions += clipboardText.Length; didChange = true; } break; } } else { processChar = true; } } if (processChar) { char value; if (j >= state.NewKeys.Count) value = state.FrameTextInput[j - state.NewKeys.Count]; else if (state.FrameTextInput != null) continue; else value = TranslateChar(key, result.ShiftDown, result.CapsDown, result.NumLockDown); /** For now we dont support tabs in text **/ if (value != '\0' && value != '\t' && value != '\b' && value != '\r') { if (allowInput) { if (cursorEndIndex != -1) { /** Delete selected text **/ DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } if (cursorIndex == -1) { m_SBuilder.Append(value); } else { m_SBuilder.Insert(cursorIndex, value); cursorIndex++; } result.NumInsertions++; didChange = true; } } else { result.UnhandledKeys.Add(key); } } } result.SelectionStart = cursorIndex; result.SelectionEnd = cursorEndIndex; result.ContentChanged = didChange; return result; }
private void DeleteSelectedText(StringBuilder m_SBuilder, ref int cursorIndex, ref int cursorEndIndex, ref bool didChange, KeyboardInputResult result) { /** Remove selected text **/ var index = cursorIndex == -1 ? m_SBuilder.Length : cursorIndex; var end = cursorEndIndex; if (end < index) { var temp = index; index = end; end = temp; } m_SBuilder.Remove(index, end - index); cursorIndex = index; if (cursorIndex >= m_SBuilder.Length) { cursorIndex = -1; } cursorEndIndex = -1; result.SelectionChanged = true; didChange = true; }
/// <summary> /// Utility to apply the result of pressing keys against a buffer /// </summary> /// <param name="buffer"></param> /// <param name="keys"></param> public KeyboardInputResult ApplyKeyboardInput(StringBuilder m_SBuilder, UpdateState state, int cursorIndex, int cursorEndIndex, bool allowInput) { var PressedKeys = state.KeyboardState.GetPressedKeys(); if (PressedKeys.Length == 0) { return null; } var didChange = false; var result = new KeyboardInputResult(); var m_CurrentKeyState = state.KeyboardState; var m_OldKeyState = state.PreviousKeyboardState; result.ShiftDown = PressedKeys.Contains(Keys.LeftShift) || PressedKeys.Contains(Keys.RightShift); result.CapsDown = System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock); result.NumLockDown = System.Windows.Forms.Control.IsKeyLocked(System.Windows.Forms.Keys.NumLock); result.CtrlDown = PressedKeys.Contains(Keys.LeftControl) || PressedKeys.Contains(Keys.RightControl); for (int j = 0; j < state.NewKeys.Count; j++) { var key = state.NewKeys[j]; if (key == Keys.Back || key == Keys.Delete) { if (m_SBuilder.Length > 0) { /** * Delete previous character or delete selection */ if (cursorEndIndex == -1 && result.CtrlDown) { /** Delete up until the previous whitespace char **/ int newEndIndex = cursorIndex; if (newEndIndex == -1) { newEndIndex = m_SBuilder.Length - 1; } while (newEndIndex >= 0) { if (Char.IsWhiteSpace(m_SBuilder[newEndIndex])) { /** Keep the whitespace char **/ newEndIndex++; break; } newEndIndex--; } cursorEndIndex = newEndIndex; } if (cursorEndIndex == -1) { /** Previous character **/ var index = cursorIndex == -1 ? m_SBuilder.Length : cursorIndex; if ((key == Keys.Back) && (index > 0)) { var numToDelete = 1; if (index > 1 && m_SBuilder[index-1] == '\n' && m_SBuilder[index - 2] == '\r') { numToDelete = 2; } m_SBuilder.Remove(index - numToDelete, numToDelete); result.NumDeletes += numToDelete; if (cursorIndex != -1) { cursorIndex -= numToDelete; } } else if ((key == Keys.Delete) && (index < m_SBuilder.Length)) { /** Guys, delete removes the next character, not the last!! **/ var numToDelete = 1; if ((index < m_SBuilder.Length - 1) && m_SBuilder[index] == '\r' && m_SBuilder[index + 1] == '\n') { numToDelete = 2; } m_SBuilder.Remove(index, numToDelete); result.NumDeletes += numToDelete; } } else { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } result.SelectionChanged = true; didChange = true; } } else if (key == Keys.Enter) { if (allowInput) { /** Line break **/ if (cursorEndIndex != -1) { /** Delete selected text **/ DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } if (cursorIndex == -1) { m_SBuilder.Append("\r\n"); } else { m_SBuilder.Insert(cursorIndex, "\r\n"); cursorIndex += 2; } result.NumInsertions += 2; didChange = true; result.EnterPressed = true; } } else if (key == Keys.Tab) { result.TabPressed = true; } else { if (result.CtrlDown) { switch (key) { case Keys.A: /** Select all **/ cursorIndex = 0; cursorEndIndex = m_SBuilder.Length; result.SelectionChanged = true; break; case Keys.C: case Keys.X: /** Copy text to clipboard **/ if (cursorEndIndex != -1) { var selectionStart = Math.Max(0, cursorIndex); var selectionEnd = cursorEndIndex; GetSelectionRange(ref selectionStart, ref selectionEnd); var str = m_SBuilder.ToString().Substring(selectionStart, selectionEnd - selectionStart); System.Windows.Forms.Clipboard.SetText((str == null) ? " " : str); if (key == Keys.X) { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } } break; case Keys.V: /** Paste text in **/ var clipboardText = System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text); if (clipboardText != null) { /** TODO: Cleanup the clipboard text to make sure its valid **/ /** If i have selection, delete it **/ if (cursorEndIndex != -1) { DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } /** Paste **/ if (cursorIndex == -1) { m_SBuilder.Append(clipboardText); } else { m_SBuilder.Insert(Math.Min(cursorIndex, m_SBuilder.Length), clipboardText); cursorIndex += clipboardText.Length; } result.NumInsertions += clipboardText.Length; didChange = true; } break; } continue; } char value = TranslateChar(key, result.ShiftDown, result.CapsDown, result.NumLockDown); /** For now we dont support tabs in text **/ if (value != '\0' && value != '\t') { if (allowInput) { if (cursorEndIndex != -1) { /** Delete selected text **/ DeleteSelectedText(m_SBuilder, ref cursorIndex, ref cursorEndIndex, ref didChange, result); } if (cursorIndex == -1) { m_SBuilder.Append(value); } else { m_SBuilder.Insert(cursorIndex, value); cursorIndex++; } result.NumInsertions++; didChange = true; } } else { result.UnhandledKeys.Add(key); } } } result.SelectionStart = cursorIndex; result.SelectionEnd = cursorEndIndex; result.ContentChanged = didChange; return result; }