Skip to content

Instantly share code, notes, and snippets.

@grokys
Forked from SuperJMN/Version1
Last active August 29, 2015 14:11
Show Gist options
  • Save grokys/36af58333b6cc3f9e09d to your computer and use it in GitHub Desktop.
Save grokys/36af58333b6cc3f9e09d to your computer and use it in GitHub Desktop.
protected override void OnKeyDown(KeyEventArgs e)
{
var modifiers = e.Device.Modifiers;
var key = e.Key;
if (IsNavigational(key))
{
var shouldSelectAlong = modifiers.HasFlag(ModifierKeys.Shift);
var isWordJumpEnabled = modifiers.HasFlag(ModifierKeys.Control);
this.MoveCaret(TranslateToDirection(key, modifiers), shouldSelectAlong, isWordJumpEnabled);
}
else if (IsTextInput(e, modifiers))
{
this.InsertText(e.Text);
}
else
{
this.TryPerformSpecialInput(key, modifiers);
}
e.Handled = true;
}
private static bool IsNavigational(Key key)
{
switch (key)
{
case Key.Left:
case Key.Right:
case Key.Up:
case Key.Down:
case Key.Home:
case Key.End:
return true;
default:
return false;
}
}
private void InsertText(string textToInsert)
{
int caretIndex;
DeleteSelection();
caretIndex = this.CaretIndex;
var currentText = this.Text;
this.Text = currentText.Substring(0, caretIndex) + textToInsert + currentText.Substring(caretIndex);
++this.CaretIndex;
}
private static TextCursorMovementDirection TranslateToDirection(Key key, ModifierKeys modifierKeys)
{
switch (key)
{
case Key.Left:
return TextCursorMovementDirection.Left;
case Key.Right:
return TextCursorMovementDirection.Right;
case Key.Up:
return TextCursorMovementDirection.Up;
case Key.Down:
return TextCursorMovementDirection.Down;
case Key.End:
case Key.Home:
return TranslateToWarp(key, modifierKeys);
default:
throw new InvalidOperationException(string.Format("The key {0} cannot be traslated to a direction", key));
}
}
private static bool IsTextInput(KeyEventArgs e, ModifierKeys modifierKeys)
{
var isControlPressed = modifierKeys.IsPressed(ModifierKeys.Control);
var isShortcutKey = e.Key == Key.A;
var isShortCut = isShortcutKey && isControlPressed;
return !string.IsNullOrEmpty(e.Text) && !IsCharacterDeletionKey(e.Key) && !isShortCut;
}
private void MoveCaret(TextCursorMovementDirection direction, int stride)
{
switch (direction)
{
case TextCursorMovementDirection.Left:
MoveHorizontal(-stride, new ModifierKeys());
break;
case TextCursorMovementDirection.Right:
MoveHorizontal(stride, new ModifierKeys());
break;
case TextCursorMovementDirection.Up:
MoveVertical(-stride);
break;
case TextCursorMovementDirection.Down:
MoveVertical(stride);
break;
case TextCursorMovementDirection.Beginning:
MoveToBeginning();
break;
case TextCursorMovementDirection.End:
MoveToEnd();
break;
case TextCursorMovementDirection.BeginingOfLine:
MoveToBeginningOfLine();
break;
case TextCursorMovementDirection.EndOfLine:
MoveToEndOfLine();
break;
}
}
public enum TextCursorMovementDirection
{
/// <summary>
/// Moves the cursor to the left.
/// </summary>
Left,
/// <summary>
/// Moves the cursor to the right.
/// </summary>
Right,
/// <summary>
/// Moves the cursor up.
/// </summary>
Up,
/// <summary>
/// Moves the cursor down.
/// </summary>
Down,
/// <summary>
/// Moves the cursor to the beginning.
/// </summary>
Beginning,
/// <summary>
/// Moves the the end.
/// </summary>
End,
EndOfLine,
BeginingOfLine,
Begining
}
protected override void OnKeyDown(KeyEventArgs e)
{
string text = this.Text ?? string.Empty;
int caretIndex = this.CaretIndex;
bool movement = false;
bool textEntered = false;
var modifiers = e.Device.Modifiers;
switch (e.Key)
{
case Key.A:
if (modifiers == ModifierKeys.Control)
{
this.SelectionStart = 0;
this.SelectionEnd = this.Text.Length;
}
break;
case Key.Left:
this.MoveHorizontal(-1, modifiers);
movement = true;
break;
case Key.Right:
this.MoveHorizontal(1, modifiers);
movement = true;
break;
case Key.Up:
this.MoveVertical(-1, modifiers);
movement = true;
break;
case Key.Down:
this.MoveVertical(1, modifiers);
movement = true;
break;
case Key.Home:
this.MoveHome(modifiers);
movement = true;
break;
case Key.End:
this.MoveEnd(modifiers);
movement = true;
break;
case Key.Back:
if (!this.DeleteSelection() && this.CaretIndex > 0)
{
this.Text = text.Substring(0, caretIndex - 1) + text.Substring(caretIndex);
--this.CaretIndex;
}
break;
case Key.Delete:
if (!this.DeleteSelection() && caretIndex < text.Length)
{
this.Text = text.Substring(0, caretIndex) + text.Substring(caretIndex + 1);
}
break;
case Key.Enter:
if (this.AcceptsReturn)
{
goto default;
}
break;
case Key.Tab:
if (this.AcceptsTab)
{
goto default;
}
break;
default:
if (!string.IsNullOrEmpty(e.Text))
{
this.DeleteSelection();
caretIndex = this.CaretIndex;
text = this.Text;
this.Text = text.Substring(0, caretIndex) + e.Text + text.Substring(caretIndex);
++this.CaretIndex;
textEntered = true;
}
break;
}
if (movement && ((modifiers & ModifierKeys.Shift) != 0))
{
this.SelectionEnd = this.CaretIndex;
}
else if (movement || textEntered)
{
this.SelectionStart = this.SelectionEnd = this.CaretIndex;
}
e.Handled = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment