protected void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Handled)
{
return;
}
var caretIndex = CaretIndex;
var movement = false;
var handled = true;
var modifiers = e.Modifiers;
switch (e.Key)
{
case Key.OemPlus:
if (modifiers == InputModifiers.Control)
{
if (TextView.FontSize < 60)
{
TextView.FontSize++;
}
}
break;
case Key.OemMinus:
if (modifiers == InputModifiers.Control)
{
if (TextView.FontSize > 1)
{
TextView.FontSize--;
}
}
break;
case Key.A:
if (modifiers == InputModifiers.Control)
{
SelectAll();
}
break;
case Key.C:
if (modifiers == InputModifiers.Control)
{
Copy();
}
break;
case Key.V:
if (modifiers == InputModifiers.Control)
{
Paste();
}
break;
case Key.X:
if (modifiers == InputModifiers.Control)
{
Cut();
}
break;
case Key.Y:
if (modifiers == InputModifiers.Control)
{
Redo();
}
break;
case Key.Z:
if (modifiers == InputModifiers.Control)
{
Undo();
}
break;
case Key.Left:
MoveHorizontal(-1, modifiers);
movement = true;
break;
case Key.Right:
MoveHorizontal(1, modifiers);
movement = true;
break;
case Key.Up:
MoveVertical(-1, modifiers);
movement = true;
break;
case Key.Down:
MoveVertical(1, modifiers);
movement = true;
break;
case Key.Home:
MoveHome(modifiers);
movement = true;
break;
case Key.End:
MoveEnd(modifiers);
movement = true;
break;
case Key.Back:
if (!DeleteSelection() && CaretIndex > 0)
{
var line = TextDocument.GetLineByOffset(CaretIndex);
if (CaretIndex == line.Offset && line.PreviousLine != null)
{
var delimiterLength = line.PreviousLine.DelimiterLength;
TextDocument.Remove(CaretIndex - delimiterLength, delimiterLength);
CaretIndex -= delimiterLength;
}
else
{
TextDocument.Remove(caretIndex - 1, 1);
--CaretIndex;
}
TextView.Invalidate();
}
break;
case Key.Delete:
if (!DeleteSelection() && caretIndex < TextDocument.TextLength)
{
var line = TextDocument.GetLineByOffset(CaretIndex);
if (CaretIndex == line.EndOffset && line.NextLine != null)
{
TextDocument.Remove(CaretIndex, line.DelimiterLength);
}
else
{
TextDocument.Remove(caretIndex, 1);
}
TextView.Invalidate();
}
break;
case Key.Enter:
if (AcceptsReturn)
{
HandleTextInput("\r\n");
}
break;
case Key.Tab:
if (AcceptsTab)
{
e.Handled = true;
var shiftedLines = false;
// TODO implement Selection.IsMultiLine
if (SelectionStart != SelectionEnd)
{
if (e.Modifiers == InputModifiers.Shift)
{
var selection = GetSelectionAsSegment();
var lines = VisualLineGeometryBuilder.GetLinesForSegmentInDocument(TextDocument, selection);
if (lines.Count() > 1)
{
TransformSelectedLines(line =>
{
var offset = line.Offset;
var s = TextUtilities.GetSingleIndentationSegment(TextDocument, offset, TabCharacter.Length);
if (s.Length > 0)
{
TextDocument.Remove(s.Offset, s.Length);
}
});
}
}
else
{
var selection = GetSelectionAsSegment();
var lines = VisualLineGeometryBuilder.GetLinesForSegmentInDocument(TextDocument, selection);
if (lines.Count() > 1)
{
TransformSelectedLines(line => { TextDocument.Insert(line.Offset, TabCharacter); });
shiftedLines = true;
}
}
}
if (!shiftedLines)
{
if (e.Modifiers == InputModifiers.Shift)
{
TransformSelectedLines(line =>
{
var offset = CaretIndex - TabCharacter.Length;
var s = TextUtilities.GetSingleIndentationSegment(TextDocument, offset, TabCharacter.Length);
if (s.Length > 0)
{
TextDocument.Remove(s.Offset, s.Length);
}
});
}
else
{
HandleTextInput(TabCharacter);
}
}
}
else
{
base.OnKeyDown(e);
handled = false;
}
break;
case Key.PageUp:
TextView.PageUp();
break;
case Key.PageDown:
TextView.PageDown();
break;
}
if (movement && ((modifiers & InputModifiers.Shift) != 0))
{
SelectionEnd = CaretIndex;
}
else if (movement)
{
SelectionStart = SelectionEnd = CaretIndex;
}
if (handled)
{
InvalidateVisual();
}
}