From bdb690af141581732069d2112e9e128d9f8e927a Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 5 Jun 2006 19:21:54 +0000 Subject: [PATCH] Adjust vertical scroll bar for visible text range only. Improves text editor performance when editing large files. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1463 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/Gui/TextAreaControl.cs | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaControl.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaControl.cs index 36d85741a1..dafcc852e0 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaControl.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaControl.cs @@ -181,6 +181,7 @@ namespace ICSharpCode.TextEditor void AdjustScrollBarsOnDocumentChange(object sender, DocumentEventArgs e) { if (motherTextEditorControl.IsInUpdate == false) { + AdjustScrollBarsClearCache(); AdjustScrollBars(); } else { adjustScrollBarsOnNextUpdate = true; @@ -190,30 +191,61 @@ namespace ICSharpCode.TextEditor void AdjustScrollBarsOnCommittedUpdate(object sender, EventArgs e) { if (motherTextEditorControl.IsInUpdate == false) { + if (!scrollToPosOnNextUpdate.IsEmpty) { + ScrollTo(scrollToPosOnNextUpdate.Y, scrollToPosOnNextUpdate.X); + } if (adjustScrollBarsOnNextUpdate) { - adjustScrollBarsOnNextUpdate = false; + AdjustScrollBarsClearCache(); AdjustScrollBars(); } - if (!scrollToPosOnNextUpdate.IsEmpty) { - ScrollTo(scrollToPosOnNextUpdate.Y, scrollToPosOnNextUpdate.X); + } + } + + int[] lineLengthCache; + const int LineLengthCacheAdditionalSize = 100; + + void AdjustScrollBarsClearCache() + { + if (lineLengthCache != null) { + if (lineLengthCache.Length < this.Document.TotalNumberOfLines + 2 * LineLengthCacheAdditionalSize) { + lineLengthCache = null; + } else { + Array.Clear(lineLengthCache, 0, lineLengthCache.Length); } } } public void AdjustScrollBars() { + adjustScrollBarsOnNextUpdate = false; vScrollBar.Minimum = 0; // number of visible lines in document (folding!) vScrollBar.Maximum = textArea.MaxVScrollValue; int max = 0; - foreach (LineSegment lineSegment in this.Document.LineSegmentCollection) { - int lineNumber = Document.GetLineNumberForOffset(lineSegment.Offset); - if(Document.FoldingManager.IsLineVisible(lineNumber)) { - max = Math.Max(max, textArea.TextView.GetVisualColumnFast(lineSegment, lineSegment.Length)); + + int firstLine = textArea.TextView.FirstVisibleLine; + int lastLine = this.Document.GetFirstLogicalLine(textArea.TextView.FirstPhysicalLine + textArea.TextView.VisibleLineCount); + if (lastLine >= this.Document.TotalNumberOfLines) + lastLine = this.Document.TotalNumberOfLines - 1; + + if (lineLengthCache == null || lineLengthCache.Length <= lastLine) { + lineLengthCache = new int[lastLine + LineLengthCacheAdditionalSize]; + } + + for (int lineNumber = firstLine; lineNumber <= lastLine; lineNumber++) { + LineSegment lineSegment = this.Document.GetLineSegment(lineNumber); + if (Document.FoldingManager.IsLineVisible(lineNumber)) { + if (lineLengthCache[lineNumber] > 0) { + max = Math.Max(max, lineLengthCache[lineNumber]); + } else { + int visualLength = textArea.TextView.GetVisualColumnFast(lineSegment, lineSegment.Length); + lineLengthCache[lineNumber] = Math.Max(1, visualLength); + max = Math.Max(max, visualLength); + } } } hScrollBar.Minimum = 0; - hScrollBar.Maximum = (Math.Max(0, max + textArea.TextView.VisibleColumnCount - 1)); + hScrollBar.Maximum = (Math.Max(max + 20, textArea.TextView.VisibleColumnCount - 1)); vScrollBar.LargeChange = Math.Max(0, textArea.TextView.DrawingPosition.Height); vScrollBar.SmallChange = Math.Max(0, textArea.TextView.FontHeight); @@ -248,6 +280,7 @@ namespace ICSharpCode.TextEditor { textArea.VirtualTop = new Point(textArea.VirtualTop.X, vScrollBar.Value); textArea.Invalidate(); + AdjustScrollBars(); } void HScrollBarValueChanged(object sender, EventArgs e) @@ -304,6 +337,9 @@ namespace ICSharpCode.TextEditor } else { scrollToPosOnNextUpdate = Point.Empty; } + + ScrollTo(line); + int curCharMin = (int)(this.hScrollBar.Value - this.hScrollBar.Minimum); int curCharMax = curCharMin + textArea.TextView.VisibleColumnCount; @@ -320,7 +356,6 @@ namespace ICSharpCode.TextEditor } } } - ScrollTo(line); } int scrollMarginHeight = 3;