📄 textarea.cs
字号:
textView.DrawingPosition = textViewArea;
}
if (clipRectangle.IntersectsWith(textViewArea)) {
textViewArea.Intersect(clipRectangle);
if (!textViewArea.IsEmpty) {
try {
textView.Paint(g, textViewArea);
} catch (Exception ex) {
Console.WriteLine("Got exception : " + ex);
}
}
}
if (adjustScrollBars) {
try {
this.motherTextAreaControl.AdjustScrollBars(null, null);
} catch (Exception) {}
}
try {
Caret.UpdateCaretPosition();
} catch (Exception) {}
base.OnPaint(e);
}
void DocumentFoldingsChanged(object sender, EventArgs e)
{
this.motherTextAreaControl.AdjustScrollBars(null, null);
}
#region keyboard handling methods
/// <summary>
/// This method is called on each Keypress
/// </summary>
/// <returns>
/// True, if the key is handled by this method and should NOT be
/// inserted in the textarea.
/// </returns>
protected virtual bool HandleKeyPress(char ch)
{
if (KeyEventHandler != null) {
return KeyEventHandler(ch);
}
return false;
}
public void SimulateKeyPress(char ch)
{
if (Document.ReadOnly) {
return;
}
if (TextEditorProperties.UseCustomLine == true) {
if (SelectionManager.HasSomethingSelected) {
if (Document.CustomLineManager.IsReadOnly(SelectionManager.SelectionCollection[0], false))
return;
} else if (Document.CustomLineManager.IsReadOnly(Caret.Line, false) == true)
return;
}
if (ch < ' ') {
return;
}
if (!HiddenMouseCursor && TextEditorProperties.HideMouseCursor) {
HiddenMouseCursor = true;
Cursor.Hide();
}
if (!HandleKeyPress(ch)) {
motherTextEditorControl.BeginUpdate();
switch (Caret.CaretMode)
{
case CaretMode.InsertMode:
InsertChar(ch);
break;
case CaretMode.OverwriteMode:
ReplaceChar(ch);
break;
default:
Debug.Assert(false, "Unknown caret mode " + Caret.CaretMode);
break;
}
int currentLineNr = Caret.Line;
int delta = Document.FormattingStrategy.FormatLine(this, currentLineNr, Document.PositionToOffset(Caret.Position), ch);
motherTextEditorControl.EndUpdate();
}
}
protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
base.OnKeyPress(e);
SimulateKeyPress(e.KeyChar);
}
/// <summary>
/// This method executes a dialog key
/// </summary>
public bool ExecuteDialogKey(Keys keyData)
{
// try, if a dialog key processor was set to use this
if (DoProcessDialogKey != null && DoProcessDialogKey(keyData)) {
return true;
}
if (keyData == Keys.Back || keyData == Keys.Delete || keyData == Keys.Enter) {
if (TextEditorProperties.UseCustomLine == true) {
if (SelectionManager.HasSomethingSelected) {
if (Document.CustomLineManager.IsReadOnly(SelectionManager.SelectionCollection[0], false))
return true;
} else {
int curLineNr = Document.GetLineNumberForOffset(Caret.Offset);
if (Document.CustomLineManager.IsReadOnly(curLineNr, false) == true)
return true;
if ((Caret.Column == 0) && (curLineNr - 1 >= 0) && keyData == Keys.Back &&
Document.CustomLineManager.IsReadOnly(curLineNr - 1, false) == true)
return true;
if (keyData == Keys.Delete) {
LineSegment curLine = Document.GetLineSegment(curLineNr);
if (curLine.Offset + curLine.Length == Caret.Offset &&
Document.CustomLineManager.IsReadOnly(curLineNr + 1, false) == true) {
return true;
}
}
}
}
}
// if not (or the process was 'silent', use the standard edit actions
IEditAction action = motherTextEditorControl.GetEditAction(keyData);
AutoClearSelection = true;
if (action != null) {
motherTextEditorControl.BeginUpdate();
try {
lock (Document) {
action.Execute(this);
if (SelectionManager.HasSomethingSelected && AutoClearSelection /*&& caretchanged*/) {
if (Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal) {
SelectionManager.ClearSelection();
}
}
}
} catch (Exception e) {
Console.WriteLine("Got Exception while executing action " + action + " : " + e.ToString());
} finally {
motherTextEditorControl.EndUpdate();
Caret.UpdateCaretPosition();
}
return true;
}
return false;
}
protected override bool ProcessDialogKey(Keys keyData)
{
return ExecuteDialogKey(keyData) || base.ProcessDialogKey(keyData);
}
#endregion
public void ScrollToCaret()
{
motherTextAreaControl.ScrollToCaret();
}
public void ScrollTo(int line)
{
motherTextAreaControl.ScrollTo(line);
}
public void BeginUpdate()
{
motherTextEditorControl.BeginUpdate();
}
public void EndUpdate()
{
motherTextEditorControl.EndUpdate();
}
string GenerateWhitespaceString(int length)
{
return new String(' ', length);
}
public bool EnableCutOrPaste
{
get {
if ( motherTextEditorControl == null)
return false;
if (TextEditorProperties.UseCustomLine == true) {
if (SelectionManager.HasSomethingSelected == true) {
if (Document.CustomLineManager.IsReadOnly(SelectionManager.SelectionCollection[0], false))
return false;
}
if (Document.CustomLineManager.IsReadOnly(Caret.Line, false) == true)
return false;
}
return true;
}
}
/// <remarks>
/// Inserts a single character at the caret position
/// </remarks>
public void InsertChar(char ch)
{
bool updating = motherTextEditorControl.IsUpdating;
if (!updating) {
BeginUpdate();
}
// filter out forgein whitespace chars and replace them with standard space (ASCII 32)
if (Char.IsWhiteSpace(ch) && ch != '\t' && ch != '\n') {
ch = ' ';
}
bool removedText = false;
if (Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal &&
SelectionManager.SelectionCollection.Count > 0) {
Caret.Position = SelectionManager.SelectionCollection[0].StartPosition;
SelectionManager.RemoveSelectedText();
removedText = true;
}
LineSegment caretLine = Document.GetLineSegment(Caret.Line);
int offset = Caret.Offset;
// use desired column for generated whitespaces
int dc=Math.Min(Caret.Column,Caret.DesiredColumn);
if (caretLine.Length < dc && ch != '\n') {
Document.Insert(offset, GenerateWhitespaceString(dc - caretLine.Length) + ch);
} else {
Document.Insert(offset, ch.ToString());
}
++Caret.Column;
if (removedText) {
Document.UndoStack.UndoLast(2);
}
if (!updating) {
EndUpdate();
UpdateLineToEnd(Caret.Line, Caret.Column);
}
// I prefer to set NOT the standard column, if you type something
// ++Caret.DesiredColumn;
}
/// <remarks>
/// Inserts a whole string at the caret position
/// </remarks>
public void InsertString(string str)
{
bool updating = motherTextEditorControl.IsUpdating;
if (!updating) {
BeginUpdate();
}
try {
bool removedText = false;
if (Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal &&
SelectionManager.SelectionCollection.Count > 0) {
Caret.Position = SelectionManager.SelectionCollection[0].StartPosition;
SelectionManager.RemoveSelectedText();
removedText = true;
}
int oldOffset = Document.PositionToOffset(Caret.Position);
int oldLine = Caret.Line;
LineSegment caretLine = Document.GetLineSegment(Caret.Line);
if (caretLine.Length < Caret.Column) {
int whiteSpaceLength = Caret.Column - caretLine.Length;
Document.Insert(oldOffset, GenerateWhitespaceString(whiteSpaceLength) + str);
Caret.Position = Document.OffsetToPosition(oldOffset + str.Length + whiteSpaceLength);
} else {
Document.Insert(oldOffset, str);
Caret.Position = Document.OffsetToPosition(oldOffset + str.Length);
}
if (removedText) {
Document.UndoStack.UndoLast(2);
}
if (oldLine != Caret.Line) {
UpdateToEnd(oldLine);
} else {
UpdateLineToEnd(Caret.Line, Caret.Column);
}
} finally {
if (!updating) {
EndUpdate();
}
}
}
/// <remarks>
/// Replaces a char at the caret position
/// </remarks>
public void ReplaceChar(char ch)
{
bool updating = motherTextEditorControl.IsUpdating;
if (!updating) {
BeginUpdate();
}
if (Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && SelectionManager.SelectionCollection.Count > 0) {
Caret.Position = SelectionManager.SelectionCollection[0].StartPosition;
SelectionManager.RemoveSelectedText();
}
int lineNr = Caret.Line;
LineSegment line = Document.GetLineSegment(lineNr);
int offset = Document.PositionToOffset(Caret.Position);
if (offset < line.Offset + line.Length) {
Document.Replace(offset, 1, ch.ToString());
} else {
Document.Insert(offset, ch.ToString());
}
if (!updating) {
EndUpdate();
UpdateLineToEnd(lineNr, Caret.Column);
}
++Caret.Column;
// ++Caret.DesiredColumn;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing) {
if (caret != null) {
caret.PositionChanged -= new EventHandler(SearchMatchingBracket);
caret.Dispose();
caret = null;
}
if (selectionManager != null) {
selectionManager.Dispose();
selectionManager = null;
}
Document.TextContentChanged -= new EventHandler(TextContentChanged);
Document.FoldingManager.FoldingsChanged -= new EventHandler(DocumentFoldingsChanged);
motherTextAreaControl = null;
motherTextEditorControl = null;
gutterMargin.Dispose();
textView.Dispose();
toolTip.Dispose();
}
}
#region UPDATE Commands
internal void UpdateLine(int line)
{
UpdateLines(0, line, line);
}
internal void UpdateLines(int lineBegin, int lineEnd)
{
UpdateLines(0, lineBegin, lineEnd);
}
internal void UpdateToEnd(int lineBegin)
{
// if (lineBegin > FirstPhysicalLine + textView.VisibleLineCount) {
// return;
// }
lineBegin = Math.Min(lineBegin, FirstPhysicalLine);
int y = Math.Max( 0, (int)(lineBegin * textView.FontHeight));
y = Math.Max(0, y - this.virtualTop.Y);
Rectangle r = new Rectangle(0,
y,
Width,
Height - y);
Invalidate(r);
}
internal void UpdateLineToEnd(int lineNr, int xStart)
{
UpdateLines(xStart, lineNr, lineNr);
}
internal void UpdateLine(int line, int begin, int end)
{
UpdateLines(line, line);
}
int FirstPhysicalLine {
get {
return VirtualTop.Y / textView.FontHeight;
}
}
internal void UpdateLines(int xPos, int lineBegin, int lineEnd)
{
// if (lineEnd < FirstPhysicalLine || lineBegin > FirstPhysicalLine + textView.VisibleLineCount) {
// return;
// }
InvalidateLines((int)(xPos * this.TextView.GetWidth(' ')), lineBegin, lineEnd);
}
void InvalidateLines(int xPos, int lineBegin, int lineEnd)
{
lineBegin = Math.Max(Document.GetVisibleLine(lineBegin), FirstPhysicalLine);
lineEnd = Math.Min(Document.GetVisibleLine(lineEnd), FirstPhysicalLine + textView.VisibleLineCount);
int y = Math.Max( 0, (int)(lineBegin * textView.FontHeight));
int height = Math.Min(textView.DrawingPosition.Height, (int)((1 + lineEnd - lineBegin) * (textView.FontHeight + 1)));
Rectangle r = new Rectangle(0,
y - 1 - this.virtualTop.Y,
Width,
height + 3);
Invalidate(r);
}
#endregion
public event KeyEventHandler KeyEventHandler;
public event DialogKeyProcessor DoProcessDialogKey;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -