Browse Source

Made AvalonEdit work without 'DoEvents'.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3834 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
ea4dd216fd
  1. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextAnchorTree.cs
  2. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/FoldingMargin.cs
  3. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/LineNumberMargin.cs
  4. 39
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/SelectionMouseHandler.cs
  5. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs
  6. 49
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextView.cs
  7. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColor.cs
  8. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Xshd/SaveXshdVisitor.cs
  9. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  10. 16
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ExtensionMethods.cs

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextAnchorTree.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.AvalonEdit.Document
#region Insert Text #region Insert Text
public void InsertText(int offset, int length) public void InsertText(int offset, int length)
{ {
Log("InsertText(" + offset + ", " + length + ")"); //Log("InsertText(" + offset + ", " + length + ")");
if (length == 0 || root == null || offset > root.totalLength) if (length == 0 || root == null || offset > root.totalLength)
return; return;
@ -139,7 +139,7 @@ namespace ICSharpCode.AvalonEdit.Document
#region Remove Text #region Remove Text
public void RemoveText(int offset, int length, DelayedEvents delayedEvents) public void RemoveText(int offset, int length, DelayedEvents delayedEvents)
{ {
Log("RemoveText(" + offset + ", " + length + ")"); //Log("RemoveText(" + offset + ", " + length + ")");
if (length == 0 || root == null || offset >= root.totalLength) if (length == 0 || root == null || offset >= root.totalLength)
return; return;
TextAnchorNode node = FindNode(ref offset); TextAnchorNode node = FindNode(ref offset);

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/FoldingMargin.cs

@ -75,7 +75,7 @@ namespace ICSharpCode.AvalonEdit.Gui
} }
markers.Clear(); markers.Clear();
InvalidateVisual(); InvalidateVisual();
if (TextView != null && FoldingManager != null) { if (TextView != null && FoldingManager != null && TextView.VisualLinesValid) {
foreach (VisualLine line in TextView.VisualLines) { foreach (VisualLine line in TextView.VisualLines) {
FoldingSection fs = FoldingManager.GetNextFolding(line.FirstDocumentLine.Offset); FoldingSection fs = FoldingManager.GetNextFolding(line.FirstDocumentLine.Offset);
if (fs == null) if (fs == null)
@ -113,6 +113,8 @@ namespace ICSharpCode.AvalonEdit.Gui
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnRender(DrawingContext drawingContext) protected override void OnRender(DrawingContext drawingContext)
{ {
if (!TextView.VisualLinesValid)
return;
if (TextView.VisualLines.Count == 0 || FoldingManager == null) if (TextView.VisualLines.Count == 0 || FoldingManager == null)
return; return;

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/LineNumberMargin.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.AvalonEdit.Gui
{ {
TextView textView = this.TextView; TextView textView = this.TextView;
Size renderSize = this.RenderSize; Size renderSize = this.RenderSize;
if (textView != null) { if (textView != null && textView.VisualLinesValid) {
var foreground = (Brush)GetValue(Control.ForegroundProperty); var foreground = (Brush)GetValue(Control.ForegroundProperty);
foreach (VisualLine line in textView.VisualLines) { foreach (VisualLine line in textView.VisualLines) {
int lineNumber = line.FirstDocumentLine.LineNumber; int lineNumber = line.FirstDocumentLine.LineNumber;
@ -170,7 +170,6 @@ namespace ICSharpCode.AvalonEdit.Gui
SimpleSegment GetTextLineSegment(MouseEventArgs e) SimpleSegment GetTextLineSegment(MouseEventArgs e)
{ {
TextView.EnsureVisualLines();
Point pos = e.GetPosition(TextView); Point pos = e.GetPosition(TextView);
pos.X = 0; pos.X = 0;
pos.Y += TextView.VerticalOffset; pos.Y += TextView.VerticalOffset;

39
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/SelectionMouseHandler.cs

@ -154,7 +154,10 @@ namespace ICSharpCode.AvalonEdit.Gui
if (mode != SelectionMode.None || !AllowTextDragDrop) { if (mode != SelectionMode.None || !AllowTextDragDrop) {
e.Cursor = Cursors.IBeam; e.Cursor = Cursors.IBeam;
e.Handled = true; e.Handled = true;
} else { } else if (textArea.TextView.VisualLinesValid) {
// Only query the cursor if the visual lines are valid.
// If they are invalid, the cursor will get re-queried when the visual lines
// get refreshed.
Point p = e.GetPosition(textArea.TextView); Point p = e.GetPosition(textArea.TextView);
if (p.X >= 0 && p.Y >= 0 && p.X <= textArea.TextView.ActualWidth && p.Y <= textArea.TextView.ActualHeight) { if (p.X >= 0 && p.Y >= 0 && p.X <= textArea.TextView.ActualWidth && p.Y <= textArea.TextView.ActualHeight) {
int visualColumn; int visualColumn;
@ -281,7 +284,6 @@ namespace ICSharpCode.AvalonEdit.Gui
{ {
TextView textView = textArea.TextView; TextView textView = textArea.TextView;
if (textView == null) return SimpleSegment.Invalid; if (textView == null) return SimpleSegment.Invalid;
textView.EnsureVisualLines();
Point pos = e.GetPosition(textView); Point pos = e.GetPosition(textView);
if (pos.Y < 0) if (pos.Y < 0)
pos.Y = 0; pos.Y = 0;
@ -325,7 +327,6 @@ namespace ICSharpCode.AvalonEdit.Gui
{ {
visualColumn = 0; visualColumn = 0;
TextView textView = textArea.TextView; TextView textView = textArea.TextView;
textView.EnsureVisualLines();
Point pos = positionRelativeToTextView; Point pos = positionRelativeToTextView;
if (pos.Y < 0) if (pos.Y < 0)
pos.Y = 0; pos.Y = 0;
@ -348,17 +349,11 @@ namespace ICSharpCode.AvalonEdit.Gui
return; return;
if (mode == SelectionMode.Normal || mode == SelectionMode.WholeWord) { if (mode == SelectionMode.Normal || mode == SelectionMode.WholeWord) {
e.Handled = true; e.Handled = true;
int oldOffset = textArea.Caret.Offset; if (textArea.TextView.VisualLinesValid) {
SetCaretOffsetToMousePosition(e); // If the visual lines are not valid, don't extend the selection.
if (mode == SelectionMode.Normal) { // Extending the selection forces a VisualLine refresh, and it is sufficient
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset); // to do that on MouseUp, we don't have to do it every MouseMove.
} else if (mode == SelectionMode.WholeWord) { ExtendSelectionToMouse(e);
var newWord = GetWordAtMousePosition(e);
if (newWord != SimpleSegment.Invalid) {
textArea.Selection = new SimpleSelection(
Math.Min(newWord.Offset, startWord.Offset),
Math.Max(newWord.GetEndOffset(), startWord.GetEndOffset()));
}
} }
} else if (mode == SelectionMode.PossibleDragStart) { } else if (mode == SelectionMode.PossibleDragStart) {
e.Handled = true; e.Handled = true;
@ -371,6 +366,20 @@ namespace ICSharpCode.AvalonEdit.Gui
} }
} }
void ExtendSelectionToMouse(MouseEventArgs e)
{
int oldOffset = textArea.Caret.Offset;
SetCaretOffsetToMousePosition(e);
if (mode == SelectionMode.Normal) {
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
} else if (mode == SelectionMode.WholeWord) {
var newWord = GetWordAtMousePosition(e);
if (newWord != SimpleSegment.Invalid) {
textArea.Selection = new SimpleSelection(Math.Min(newWord.Offset, startWord.Offset), Math.Max(newWord.GetEndOffset(), startWord.GetEndOffset()));
}
}
}
void textArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) void textArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{ {
if (mode == SelectionMode.None || e.Handled) if (mode == SelectionMode.None || e.Handled)
@ -380,6 +389,8 @@ namespace ICSharpCode.AvalonEdit.Gui
// -> this was not a drag start (mouse didn't move after mousedown) // -> this was not a drag start (mouse didn't move after mousedown)
SetCaretOffsetToMousePosition(e); SetCaretOffsetToMousePosition(e);
textArea.Selection = Selection.Empty; textArea.Selection = Selection.Empty;
} else if (mode == SelectionMode.Normal || mode == SelectionMode.WholeWord) {
ExtendSelectionToMouse(e);
} }
mode = SelectionMode.None; mode = SelectionMode.None;
textArea.ReleaseMouseCapture(); textArea.ReleaseMouseCapture();

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextEditor.cs

@ -99,6 +99,9 @@ namespace ICSharpCode.AvalonEdit
value = string.Empty; value = string.Empty;
TextDocument document = GetOrCreateDocument(); TextDocument document = GetOrCreateDocument();
document.Text = value; document.Text = value;
// after replacing the full text, the caret is positioned at the end of the document
// - reset it to the beginning.
this.CaretOffset = 0;
document.UndoStack.ClearAll(); document.UndoStack.ClearAll();
} }
} }

49
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Gui/TextView.cs

@ -242,17 +242,15 @@ namespace ICSharpCode.AvalonEdit.Gui
/// <summary> /// <summary>
/// Waits for the visual lines to be built. /// Waits for the visual lines to be built.
/// Warning: this methods runs all operations with priority &gt;= Render
/// </summary> /// </summary>
public void EnsureVisualLines() private void EnsureVisualLines()
{ {
Dispatcher.VerifyAccess(); Dispatcher.VerifyAccess();
if (visibleVisualLines == null) { if (visibleVisualLines == null) {
if (invalidateMeasureOperation != null) { // increase priority for real Redraw
// increase priority InvalidateMeasure(DispatcherPriority.Normal);
InvalidateMeasure(DispatcherPriority.Normal); // force immediate re-measure
} UpdateLayout();
Dispatcher.DoEvents(DispatcherPriority.Render);
} }
} }
@ -285,7 +283,7 @@ namespace ICSharpCode.AvalonEdit.Gui
/// </summary> /// </summary>
public VisualLine GetVisualLine(int documentLineNumber) public VisualLine GetVisualLine(int documentLineNumber)
{ {
VerifyAccess(); // TODO: EnsureVisualLines() ?
foreach (VisualLine visualLine in allVisualLines) { foreach (VisualLine visualLine in allVisualLines) {
Debug.Assert(visualLine.IsDisposed == false); Debug.Assert(visualLine.IsDisposed == false);
int start = visualLine.FirstDocumentLine.LineNumber; int start = visualLine.FirstDocumentLine.LineNumber;
@ -355,15 +353,23 @@ namespace ICSharpCode.AvalonEdit.Gui
/// <summary> /// <summary>
/// Gets the currently visible visual lines. /// Gets the currently visible visual lines.
/// Is empty when the visual lines are not available
/// (when one or more of the visual lines need to be regenerated).
/// </summary> /// </summary>
public ReadOnlyCollection<VisualLine> VisualLines { public ReadOnlyCollection<VisualLine> VisualLines {
get { get {
return visibleVisualLines ?? Empty<VisualLine>.ReadOnlyCollection; EnsureVisualLines();
return visibleVisualLines;
} }
} }
/// <summary>
/// Gets whether the visual lines are valid.
/// Will return false after a call to Redraw(). Accessing the visual lines property
/// will force immediate regeneration of valid lines.
/// </summary>
public bool VisualLinesValid {
get { return visibleVisualLines != null; }
}
/// <summary> /// <summary>
/// Occurs when the TextView was measured and changed its visual lines. /// Occurs when the TextView was measured and changed its visual lines.
/// </summary> /// </summary>
@ -398,10 +404,21 @@ namespace ICSharpCode.AvalonEdit.Gui
{ {
if (!canHorizontallyScroll && !availableSize.Width.IsClose(lastAvailableSize.Width)) if (!canHorizontallyScroll && !availableSize.Width.IsClose(lastAvailableSize.Width))
ClearVisualLines(); ClearVisualLines();
RemoveInlineObjectsNow();
lastAvailableSize = availableSize; lastAvailableSize = availableSize;
return DoMeasure(availableSize);
}
/// <summary>
/// Immediately performs the text creation.
/// </summary>
/// <param name="availableSize">The size of the text view.</param>
/// <returns></returns>
Size DoMeasure(Size availableSize)
{
bool isRealMeasure = true;
if (isRealMeasure)
RemoveInlineObjectsNow();
if (document == null) if (document == null)
return Size.Empty; return Size.Empty;
@ -455,7 +472,8 @@ namespace ICSharpCode.AvalonEdit.Gui
if (!newVisualLines.Contains(line)) if (!newVisualLines.Contains(line))
DisposeVisualLine(line); DisposeVisualLine(line);
} }
RemoveInlineObjectsNow(); if (isRealMeasure)
RemoveInlineObjectsNow();
allVisualLines = newVisualLines; allVisualLines = newVisualLines;
// visibleVisualLines = readonly copy of visual lines // visibleVisualLines = readonly copy of visual lines
@ -1032,7 +1050,6 @@ namespace ICSharpCode.AvalonEdit.Gui
/// </summary> /// </summary>
public VisualLine GetVisualLineFromVisualTop(double visualTop) public VisualLine GetVisualLineFromVisualTop(double visualTop)
{ {
VerifyAccess();
foreach (VisualLine vl in this.VisualLines) { foreach (VisualLine vl in this.VisualLines) {
if (visualTop < vl.VisualTop) if (visualTop < vl.VisualTop)
continue; continue;

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/HighlightingColor.cs

@ -34,6 +34,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting
/// <summary> /// <summary>
/// Gets CSS code for the color. /// Gets CSS code for the color.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "CSS usually uses lowercase, and all possible values are English-only")]
public virtual string ToCss() public virtual string ToCss()
{ {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Highlighting/Xshd/SaveXshdVisitor.cs

@ -94,6 +94,7 @@ namespace ICSharpCode.AvalonEdit.Highlighting.Xshd
} }
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "The file format requires lowercase, and all possible values are English-only")]
void WriteColorAttributes(XshdColor color) void WriteColorAttributes(XshdColor color)
{ {
if (color.Foreground != null) if (color.Foreground != null)

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -18,7 +18,7 @@
<DelaySign>False</DelaySign> <DelaySign>False</DelaySign>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> <AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<RunCodeAnalysis>False</RunCodeAnalysis> <RunCodeAnalysis>False</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1020;-Microsoft.Design#CA1033;-Microsoft.Globalization#CA1308</CodeAnalysisRules> <CodeAnalysisRules>-Microsoft.Design#CA1020;-Microsoft.Design#CA1033</CodeAnalysisRules>
<OutputPath>..\..\..\..\bin\</OutputPath> <OutputPath>..\..\..\..\bin\</OutputPath>
<DocumentationFile>..\..\..\..\bin\ICSharpCode.AvalonEdit.xml</DocumentationFile> <DocumentationFile>..\..\..\..\bin\ICSharpCode.AvalonEdit.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>

16
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ExtensionMethods.cs

@ -58,22 +58,6 @@ namespace ICSharpCode.AvalonEdit.Utils
(FontStretch)fe.GetValue(TextBlock.FontStretchProperty)); (FontStretch)fe.GetValue(TextBlock.FontStretchProperty));
} }
/// <summary>
/// Runs all outstanding dispatcher tasks with a priority higher or equal to <paramref name="priority"/>.
/// </summary>
public static void DoEvents(this Dispatcher dispatcher, DispatcherPriority priority)
{
dispatcher.VerifyAccess();
DispatcherFrame frame = new DispatcherFrame();
dispatcher.BeginInvoke(
priority, new DispatcherOperationCallback(
delegate {
frame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(frame);
}
public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> elements) public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> elements)
{ {
foreach (T e in elements) foreach (T e in elements)

Loading…
Cancel
Save