📄 textview.cs
字号:
column = (column / tabIndent) * tabIndent;
break;
default:
++column;
break;
}
}
return column;
}
/// <summary>
/// returns line/column for a visual point position
/// </summary>
public Point GetLogicalPosition(int xPos, int yPos)
{
xPos += (int)(textArea.VirtualTop.X * GetWidth(' '));
int clickedVisualLine = Math.Max(0, (yPos + this.textArea.VirtualTop.Y) / fontHeight);
int logicalLine = Document.GetFirstLogicalLine(clickedVisualLine);
Point pos = GetLogicalColumn(logicalLine, xPos);
return pos;
}
/// <summary>
/// returns logical line number for a visual point
/// </summary>
public int GetLogicalLine(Point mousepos)
{
int physicalLine = FirstPhysicalLine + (int)(mousepos.Y / FontHeight);
return Document.GetFirstLogicalLine(physicalLine);
}
public Point GetLogicalColumn(int firstLogicalLine, int xPos)
{
// Console.WriteLine("GetLogicalColumn: line = {0}, xPos = {1}", firstLogicalLine, xPos);
float spaceWidth = GetWidth(' ');
LineSegment line = firstLogicalLine < Document.TotalNumberOfLines ? Document.GetLineSegment(firstLogicalLine) : null;
if (line == null) {
// Console.WriteLine("LineSegment not found");
return new Point((int)(xPos / spaceWidth), firstLogicalLine);
}
int lineNumber = firstLogicalLine;
int tabIndent = Document.TextEditorProperties.TabIndent;
int column = 0;
int logicalColumn = 0;
float paintPos = 0;
ArrayList starts = textArea.Document.FoldingManager.GetFoldedFoldingsWithStart(lineNumber);
while (true) {
// save current paint position
float oldPaintPos = paintPos;
// search for folding
if (starts.Count > 0) {
// Console.WriteLine("Foldings found");
foreach (FoldMarker folding in starts) {
if (folding.IsFolded && logicalColumn >= folding.StartColumn && (logicalColumn < folding.EndColumn || lineNumber != folding.EndLine)) {
column += folding.FoldText.Length;
paintPos += folding.FoldText.Length * spaceWidth;
// special case when xPos is inside the fold marker
if (xPos <= paintPos - (paintPos - oldPaintPos) / 2) {
return new Point(logicalColumn, lineNumber);
}
logicalColumn = folding.EndColumn;
if (lineNumber != folding.EndLine) {
lineNumber = folding.EndLine;
line = Document.GetLineSegment(lineNumber);
starts = textArea.Document.FoldingManager.GetFoldedFoldingsWithStart(lineNumber);
}
break;
}
}
}
// --> no folding, going on with the count
char ch = logicalColumn >= line.Length ? ' ' : Document.GetCharAt(line.Offset + logicalColumn);
switch (ch) {
case '\t':
int oldColumn = column;
column += tabIndent;
column = (column / tabIndent) * tabIndent;
paintPos += (column - oldColumn) * spaceWidth;
break;
default:
paintPos += GetWidth(ch);
++column;
break;
}
// when the paint position is reached, give it back otherwise advance to the next char
if (xPos <= paintPos - (paintPos - oldPaintPos) / 2) {
return new Point(logicalColumn, lineNumber);
}
++logicalColumn;
}
}
/// <summary>
/// returns line/column for a visual point position
/// </summary>
public FoldMarker GetFoldMarkerFromPosition(int xPos, int yPos)
{
xPos += (int)(textArea.VirtualTop.X * GetWidth(' '));
int clickedVisualLine = (yPos + this.textArea.VirtualTop.Y) / fontHeight;
int logicalLine = Document.GetFirstLogicalLine(clickedVisualLine);
return GetFoldMarkerFromColumn(logicalLine, xPos);
}
FoldMarker GetFoldMarkerFromColumn(int firstLogicalLine, int xPos)
{
float spaceWidth = GetWidth(' ');
LineSegment line = firstLogicalLine < Document.TotalNumberOfLines ? Document.GetLineSegment(firstLogicalLine) : null;
if (line == null) {
return null;
}
int lineNumber = firstLogicalLine;
int tabIndent = Document.TextEditorProperties.TabIndent;
int column = 0;
int logicalColumn = 0;
float paintPos = 0;
ArrayList starts = textArea.Document.FoldingManager.GetFoldedFoldingsWithStart(lineNumber);
while (true) {
// save current paint position
float oldPaintPos = paintPos;
// search for folding
if (starts.Count > 0) {
foreach (FoldMarker folding in starts) {
if (folding.IsFolded && logicalColumn >= folding.StartColumn && (logicalColumn < folding.EndColumn || lineNumber != folding.EndLine)) {
column += folding.FoldText.Length;
paintPos += folding.FoldText.Length * spaceWidth;
// special case when xPos is inside the fold marker
if (xPos <= paintPos) {
return folding;
}
logicalColumn = folding.EndColumn;
if (lineNumber != folding.EndLine) {
lineNumber = folding.EndLine;
line = Document.GetLineSegment(lineNumber);
starts = textArea.Document.FoldingManager.GetFoldedFoldingsWithStart(lineNumber);
}
break;
}
}
}
// --> no folding, going on with the count
char ch = logicalColumn >= line.Length ? ' ' : Document.GetCharAt(line.Offset + logicalColumn);
switch (ch) {
case '\t':
int oldColumn = column;
column += tabIndent;
column = (column / tabIndent) * tabIndent;
paintPos += (column - oldColumn) * spaceWidth;
break;
default:
paintPos += GetWidth(ch);
++column;
break;
}
// when the paint position is reached, give it back otherwise advance to the next char
if (xPos <= paintPos - (paintPos - oldPaintPos) / 2) {
return null;
}
++logicalColumn;
}
}
float CountColumns(ref int column, int start, int end, int logicalLine)
{
float spaceWidth = GetWidth(' ');
float drawingPos = 0;
int tabIndent = Document.TextEditorProperties.TabIndent;
for (int j = start; j < end; ++j) {
char ch;
LineSegment line = Document.GetLineSegment(logicalLine);
if (j >= line.Length) {
ch = ' ';
} else {
ch = Document.GetCharAt(line.Offset + j);
}
switch (ch) {
case '\t':
int oldColumn = column;
column += tabIndent;
column = (column / tabIndent) * tabIndent;
drawingPos += (column - oldColumn) * spaceWidth;
break;
default:
++column;
drawingPos += GetWidth(ch);
break;
}
}
return drawingPos;
}
public int GetDrawingXPos(int logicalLine, int logicalColumn)
{
float spaceWidth = GetWidth(' ');
ArrayList foldings = Document.FoldingManager.GetTopLevelFoldedFoldings();
int i;
FoldMarker f = null;
// search the last folding that's interresting
for (i = foldings.Count - 1; i >= 0; --i) {
f = (FoldMarker)foldings[i];
if (f.StartLine < logicalLine || f.StartLine == logicalLine && f.StartColumn < logicalColumn) {
break;
}
}
int lastFolding = 0;
int firstFolding = 0;
int column = 0;
int tabIndent = Document.TextEditorProperties.TabIndent;
float drawingPos;
// if no folding is interresting
if (f == null || !(f.StartLine < logicalLine || f.StartLine == logicalLine && f.StartColumn < logicalColumn)) {
drawingPos = CountColumns(ref column, 0, logicalColumn, logicalLine);
return (int)(drawingPos - textArea.VirtualTop.X * spaceWidth);
}
// if logicalLine/logicalColumn is in folding
if (f.EndLine > logicalLine || f.EndLine == logicalLine && f.EndColumn > logicalColumn) {
logicalColumn = f.StartColumn;
logicalLine = f.StartLine;
--i;
}
lastFolding = i;
// search backwards until a new visible line is reched
for (; i >= 0; --i) {
f = (FoldMarker)foldings[i];
if (f.EndLine < logicalLine) { // reached the begin of a new visible line
break;
}
}
firstFolding = i + 1;
if (lastFolding < firstFolding) {
drawingPos = CountColumns(ref column, 0, logicalColumn, logicalLine);
return (int)(drawingPos - textArea.VirtualTop.X * spaceWidth);
}
int foldEnd = 0;
drawingPos = 0;
for (i = firstFolding; i <= lastFolding; ++i) {
f = (FoldMarker)foldings[i];
drawingPos += CountColumns(ref column, foldEnd, f.StartColumn, f.StartLine);
foldEnd = f.EndColumn;
column += f.FoldText.Length;
drawingPos += GetWidth(f.FoldText);
}
drawingPos += CountColumns(ref column, foldEnd, logicalColumn, logicalLine);
return (int)(drawingPos - textArea.VirtualTop.X * spaceWidth);
}
#endregion
#region DrawHelper functions
void DrawBracketHighlight(Graphics g, Rectangle rect)
{
g.FillRectangle(BrushRegistry.GetBrush(Color.FromArgb(50, 0, 0, 255)), rect);
g.DrawRectangle(Pens.Blue, rect);
}
void DrawInvalidLineMarker(Graphics g, float x, float y)
{
HighlightColor invalidLinesColor = textArea.Document.HighlightingStrategy.GetColorFor("InvalidLines");
g.DrawString("~", invalidLinesColor.Font, BrushRegistry.GetBrush(invalidLinesColor.Color), x, y, measureStringFormat);
}
void DrawSpaceMarker(Graphics g, Color color, float x, float y)
{
HighlightColor spaceMarkerColor = textArea.Document.HighlightingStrategy.GetColorFor("SpaceMarkers");
g.DrawString("\u00B7", spaceMarkerColor.Font, BrushRegistry.GetBrush(color), x, y, measureStringFormat);
}
void DrawTabMarker(Graphics g, Color color, float x, float y)
{
HighlightColor tabMarkerColor = textArea.Document.HighlightingStrategy.GetColorFor("TabMarkers");
g.DrawString("\u00BB", tabMarkerColor.Font, BrushRegistry.GetBrush(color), x, y, measureStringFormat);
}
float DrawEOLMarker(Graphics g, Color color, Brush backBrush, float x, float y)
{
float width = GetWidth(g, '\u00B6');
g.FillRectangle(backBrush,
new RectangleF(x, y, width, fontHeight));
HighlightColor eolMarkerColor = textArea.Document.HighlightingStrategy.GetColorFor("EOLMarkers");
g.DrawString("\u00B6", eolMarkerColor.Font, BrushRegistry.GetBrush(color), x, y, measureStringFormat);
return width;
}
void DrawVerticalRuler(Graphics g, Rectangle lineRectangle)
{
if (TextEditorProperties.VerticalRulerRow < textArea.VirtualTop.X) {
return;
}
HighlightColor vRulerColor = textArea.Document.HighlightingStrategy.GetColorFor("VRuler");
int xpos = (int)(drawingPosition.Left + GetWidth(g, ' ') * (TextEditorProperties.VerticalRulerRow - textArea.VirtualTop.X));
g.DrawLine(BrushRegistry.GetPen(vRulerColor.Color),
xpos,
lineRectangle.Top,
xpos,
lineRectangle.Bottom);
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -