Browse Source

continuing work on virtual space. Adjusted BackgroundGeometryBuilder and text input.

pull/23/head
Siegfried Pammer 14 years ago
parent
commit
b677f75db0
  1. 15
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs
  2. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EmptySelection.cs
  3. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs
  4. 27
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Selection.cs
  5. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionLayer.cs
  6. 3
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs
  7. 15
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionSegment.cs
  8. 48
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs
  9. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs
  10. 68
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/BackgroundGeometryBuilder.cs
  11. 12
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
  12. 20
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs
  13. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs

15
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs

@ -281,19 +281,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -281,19 +281,8 @@ namespace ICSharpCode.AvalonEdit.Editing
int caretOffset = textView.Document.GetOffset(position);
int firstDocumentLineOffset = visualLine.FirstDocumentLine.Offset;
if (position.VisualColumn < 0) {
position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset);
} else {
int offsetFromVisualColumn = visualLine.GetRelativeOffset(position.VisualColumn);
offsetFromVisualColumn += firstDocumentLineOffset;
if (offsetFromVisualColumn != caretOffset) {
position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset);
} else {
if (position.VisualColumn > visualLine.VisualLength && !textArea.Options.EnableVirtualSpace) {
position.VisualColumn = visualLine.VisualLength;
}
}
}
position.VisualColumn = visualLine.ValidateVisualColumn(position, textArea.Options.EnableVirtualSpace);
// search possible caret positions
int newVisualColumnForwards = visualLine.GetNextCaretPosition(position.VisualColumn - 1, LogicalDirection.Forward, CaretPositioningMode.Normal);
// If position.VisualColumn was valid, we're done with validation.

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/EmptySelection.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -34,7 +34,7 @@ namespace ICSharpCode.AvalonEdit.Editing
var document = textArea.Document;
if (document == null)
throw ThrowUtil.NoDocumentAssigned();
return Create(textArea, document.GetOffset(startPosition), document.GetOffset(endPosition));
return Create(textArea, startPosition, endPosition);
}
public override IEnumerable<SelectionSegment> Segments {
@ -50,6 +50,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -50,6 +50,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
if (newText == null)
throw new ArgumentNullException("newText");
newText = AddSpacesIfRequired(newText, textArea.Caret.Position);
if (newText.Length > 0) {
if (textArea.ReadOnlySectionProvider.CanInsert(textArea.Caret.Offset)) {
textArea.Document.Insert(textArea.Caret.Offset, newText);

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/RectangleSelection.cs

@ -131,7 +131,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -131,7 +131,7 @@ namespace ICSharpCode.AvalonEdit.Editing
int baseOffset = vl.FirstDocumentLine.Offset;
int startOffset = baseOffset + vl.GetRelativeOffset(startVC);
int endOffset = baseOffset + vl.GetRelativeOffset(endVC);
segments.Add(new SelectionSegment(startOffset, startVC, endOffset, endVC));
segments.Add(new SelectionSegment(startOffset, startVC, endOffset, endVC, true));
nextLine = vl.LastDocumentLine.NextLine;
} while (nextLine.LineNumber <= Math.Max(startLine, endLine));

27
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Selection.cs

@ -26,7 +26,19 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -26,7 +26,19 @@ namespace ICSharpCode.AvalonEdit.Editing
if (startOffset == endOffset)
return textArea.emptySelection;
else
return new SimpleSelection(textArea, startOffset, endOffset);
return new SimpleSelection(textArea,
new TextViewPosition(textArea.Document.GetLocation(startOffset)),
new TextViewPosition(textArea.Document.GetLocation(endOffset)));
}
internal static Selection Create(TextArea textArea, TextViewPosition start, TextViewPosition end)
{
if (textArea == null)
throw new ArgumentNullException("textArea");
if (textArea.Document.GetOffset(start) == textArea.Document.GetOffset(end) && start.VisualColumn == end.VisualColumn)
return textArea.emptySelection;
else
return new SimpleSelection(textArea, start, end);
}
/// <summary>
@ -67,6 +79,19 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -67,6 +79,19 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
public abstract void ReplaceSelectionWithText(string newText);
internal string AddSpacesIfRequired(string newText, TextViewPosition pos)
{
if (textArea.Options.EnableVirtualSpace) {
var vLine = textArea.TextView.GetOrConstructVisualLine(textArea.Document.GetLineByNumber(pos.Line));
int colDiff = pos.VisualColumn - vLine.VisualLength;
if (colDiff > 0) {
string additionalSpaces = new string(' ', colDiff);
return additionalSpaces + newText;
}
}
return newText;
}
/// <summary>
/// Updates the selection when the document changes.
/// </summary>

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionLayer.cs

@ -39,6 +39,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -39,6 +39,7 @@ namespace ICSharpCode.AvalonEdit.Editing
BackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder();
geoBuilder.AlignToMiddleOfPixels = true;
geoBuilder.ExtendToFullWidthAtLineEnd = textArea.Options.EnableVirtualSpace;
geoBuilder.CornerRadius = textArea.SelectionCornerRadius;
foreach (var segment in textArea.Selection.Segments) {
geoBuilder.AddSegment(textView, segment);

3
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs

@ -560,12 +560,11 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -560,12 +560,11 @@ namespace ICSharpCode.AvalonEdit.Editing
void ExtendSelectionToMouse(MouseEventArgs e)
{
int oldOffset = textArea.Caret.Offset;
TextViewPosition oldPosition = textArea.Caret.Position;
if (mode == SelectionMode.Normal || mode == SelectionMode.Rectangular) {
SetCaretOffsetToMousePosition(e);
if (mode == SelectionMode.Normal && textArea.Selection is RectangleSelection)
textArea.Selection = Selection.Create(textArea, oldOffset, textArea.Caret.Offset);
textArea.Selection = new SimpleSelection(textArea, oldPosition, textArea.Caret.Position);
else if (mode == SelectionMode.Rectangular && !(textArea.Selection is RectangleSelection))
textArea.Selection = new RectangleSelection(textArea, oldPosition, textArea.Caret.Position);
else

15
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SelectionSegment.cs

@ -11,16 +11,19 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -11,16 +11,19 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
public class SelectionSegment : ISegment
{
int startOffset, endOffset;
int startVC, endVC;
readonly int startOffset, endOffset;
readonly int startVC, endVC;
public bool AllowVirtualSpace { get; private set; }
public SelectionSegment(int startOffset, int endOffset)
{
this.startOffset = Math.Min(startOffset, endOffset);
this.endOffset = Math.Max(startOffset, endOffset);
this.startVC = this.endVC = -1;
}
public SelectionSegment(int startOffset, int startVC, int endOffset, int endVC)
public SelectionSegment(int startOffset, int startVC, int endOffset, int endVC, bool allowVirtualSpace)
{
if (startOffset <= endOffset) {
this.startOffset = startOffset;
@ -33,6 +36,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -33,6 +36,7 @@ namespace ICSharpCode.AvalonEdit.Editing
this.endOffset = startOffset;
this.endVC = startVC;
}
this.AllowVirtualSpace = allowVirtualSpace;
}
public int StartOffset {
@ -59,5 +63,10 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -59,5 +63,10 @@ namespace ICSharpCode.AvalonEdit.Editing
public int Length {
get { return endOffset - startOffset; }
}
public override string ToString()
{
return string.Format("[SelectionSegment StartOffset={0}, EndOffset={1}, StartVC={2}, EndVC={3}]", startOffset, endOffset, startVC, endVC);
}
}
}

48
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/SimpleSelection.cs

@ -15,22 +15,25 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -15,22 +15,25 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
sealed class SimpleSelection : Selection
{
readonly TextViewPosition start, end;
readonly int startOffset, endOffset;
/// <summary>
/// Creates a new SimpleSelection instance.
/// </summary>
internal SimpleSelection(TextArea textArea, int startOffset, int endOffset)
internal SimpleSelection(TextArea textArea, TextViewPosition start, TextViewPosition end)
: base(textArea)
{
this.startOffset = startOffset;
this.endOffset = endOffset;
this.start = start;
this.end = end;
this.startOffset = textArea.Document.GetOffset(start.Location);
this.endOffset = textArea.Document.GetOffset(end.Location);
}
/// <inheritdoc/>
public override IEnumerable<SelectionSegment> Segments {
get {
return ExtensionMethods.Sequence<SelectionSegment>(new SelectionSegment(startOffset, endOffset));
return ExtensionMethods.Sequence<SelectionSegment>(new SelectionSegment(startOffset, start.VisualColumn, endOffset, end.VisualColumn, textArea.Options.EnableVirtualSpace));
}
}
@ -47,25 +50,20 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -47,25 +50,20 @@ namespace ICSharpCode.AvalonEdit.Editing
if (newText == null)
throw new ArgumentNullException("newText");
using (textArea.Document.RunUpdate()) {
if (IsEmpty) {
if (newText.Length > 0) {
if (textArea.ReadOnlySectionProvider.CanInsert(textArea.Caret.Offset)) {
textArea.Document.Insert(textArea.Caret.Offset, newText);
ISegment[] segmentsToDelete = textArea.GetDeletableSegments(this.SurroundingSegment);
for (int i = segmentsToDelete.Length - 1; i >= 0; i--) {
if (i == segmentsToDelete.Length - 1) {
if (segmentsToDelete[i].Offset == SurroundingSegment.Offset && segmentsToDelete[i].Length == SurroundingSegment.Length) {
newText = AddSpacesIfRequired(newText, start);
}
textArea.Caret.Offset = segmentsToDelete[i].EndOffset;
textArea.Document.Replace(segmentsToDelete[i], newText);
} else {
textArea.Document.Remove(segmentsToDelete[i]);
}
} else {
ISegment[] segmentsToDelete = textArea.GetDeletableSegments(this.SurroundingSegment);
for (int i = segmentsToDelete.Length - 1; i >= 0; i--) {
if (i == segmentsToDelete.Length - 1) {
textArea.Caret.Offset = segmentsToDelete[i].EndOffset;
textArea.Document.Replace(segmentsToDelete[i], newText);
} else {
textArea.Document.Remove(segmentsToDelete[i]);
}
}
if (segmentsToDelete.Length != 0) {
textArea.ClearSelection();
}
}
if (segmentsToDelete.Length != 0) {
textArea.ClearSelection();
}
}
}
@ -111,7 +109,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -111,7 +109,7 @@ namespace ICSharpCode.AvalonEdit.Editing
/// <inheritdoc/>
public override Selection SetEndpoint(TextViewPosition endPosition)
{
return Create(textArea, startOffset, textArea.Document.GetOffset(endPosition));
return Create(textArea, start, endPosition);
}
public override Selection StartSelectionOrSetEndpoint(TextViewPosition startPosition, TextViewPosition endPosition)
@ -119,7 +117,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -119,7 +117,7 @@ namespace ICSharpCode.AvalonEdit.Editing
var document = textArea.Document;
if (document == null)
throw ThrowUtil.NoDocumentAssigned();
return Create(textArea, startOffset, document.GetOffset(endPosition));
return Create(textArea, start, endPosition);
}
/// <inheritdoc/>
@ -135,13 +133,13 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -135,13 +133,13 @@ namespace ICSharpCode.AvalonEdit.Editing
{
SimpleSelection other = obj as SimpleSelection;
if (other == null) return false;
return this.startOffset == other.startOffset && this.endOffset == other.endOffset && this.textArea == other.textArea;
return this.start.Equals(other.start) && this.end.Equals(other.end) && this.textArea == other.textArea;
}
/// <inheritdoc/>
public override string ToString()
{
return "[SimpleSelection Start=" + startOffset + " End=" + endOffset + "]";
return "[SimpleSelection Start=" + start + " End=" + end + "]";
}
}
}

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs

@ -386,11 +386,11 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -386,11 +386,11 @@ namespace ICSharpCode.AvalonEdit.Editing
if (value.textArea != this)
throw new ArgumentException("Cannot use a Selection instance that belongs to another text area.");
if (!object.Equals(selection, value)) {
//Debug.WriteLine("Selection change from " + selection + " to " + value);
// Debug.WriteLine("Selection change from " + selection + " to " + value);
if (textView != null) {
ISegment oldSegment = selection.SurroundingSegment;
ISegment newSegment = value.SurroundingSegment;
if (selection is SimpleSelection && value is SimpleSelection && oldSegment != null && newSegment != null) {
if (!Options.EnableVirtualSpace && (selection is SimpleSelection && value is SimpleSelection && oldSegment != null && newSegment != null)) {
// perf optimization:
// When a simple selection changes, don't redraw the whole selection, but only the changed parts.
int oldSegmentOffset = oldSegment.Offset;

68
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/BackgroundGeometryBuilder.cs

@ -5,10 +5,12 @@ using System; @@ -5,10 +5,12 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Utils;
namespace ICSharpCode.AvalonEdit.Rendering
@ -38,6 +40,11 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -38,6 +40,11 @@ namespace ICSharpCode.AvalonEdit.Rendering
/// </summary>
public bool AlignToMiddleOfPixels { get; set; }
/// <summary>
/// Gets/Sets whether to extend the rectangles to full width at line end.
/// </summary>
public bool ExtendToFullWidthAtLineEnd { get; set; }
/// <summary>
/// Creates a new BackgroundGeometryBuilder instance.
/// </summary>
@ -53,7 +60,7 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -53,7 +60,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
if (textView == null)
throw new ArgumentNullException("textView");
Size pixelSize = PixelSnapHelpers.GetPixelSize(textView);
foreach (Rect r in GetRectsForSegment(textView, segment)) {
foreach (Rect r in GetRectsForSegment(textView, segment, ExtendToFullWidthAtLineEnd)) {
if (AlignToWholePixels) {
AddRectangle(PixelSnapHelpers.Round(r.Left, pixelSize.Width),
PixelSnapHelpers.Round(r.Top + 1, pixelSize.Height),
@ -74,21 +81,33 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -74,21 +81,33 @@ namespace ICSharpCode.AvalonEdit.Rendering
/// Calculates the list of rectangle where the segment in shown.
/// This returns one rectangle for each line inside the segment.
/// </summary>
public static IEnumerable<Rect> GetRectsForSegment(TextView textView, ISegment segment)
public static IEnumerable<Rect> GetRectsForSegment(TextView textView, ISegment segment, bool extendToFullWidthAtLineEnd = false)
{
if (textView == null)
throw new ArgumentNullException("textView");
if (segment == null)
throw new ArgumentNullException("segment");
return GetRectsForSegmentImpl(textView, segment);
return GetRectsForSegmentImpl(textView, segment, extendToFullWidthAtLineEnd);
}
static IEnumerable<Rect> GetRectsForSegmentImpl(TextView textView, ISegment segment)
static IEnumerable<Rect> GetRectsForSegmentImpl(TextView textView, ISegment segment, bool extendToFullWidthAtLineEnd)
{
Vector scrollOffset = textView.ScrollOffset;
int segmentStart = segment.Offset;
int segmentEnd = segment.Offset + segment.Length;
TextViewPosition start;
TextViewPosition end;
if (segment is SelectionSegment) {
SelectionSegment sel = (SelectionSegment)segment;
start = new TextViewPosition(textView.Document.GetLocation(sel.StartOffset), sel.StartVisualColumn);
end = new TextViewPosition(textView.Document.GetLocation(sel.EndOffset), sel.EndVisualColumn);
} else {
start = new TextViewPosition(textView.Document.GetLocation(segmentStart), -1);
end = new TextViewPosition(textView.Document.GetLocation(segmentEnd), -1);
}
foreach (VisualLine vl in textView.VisualLines) {
int vlStartOffset = vl.FirstDocumentLine.Offset;
if (vlStartOffset > segmentEnd)
@ -101,13 +120,13 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -101,13 +120,13 @@ namespace ICSharpCode.AvalonEdit.Rendering
if (segmentStart < vlStartOffset)
segmentStartVC = 0;
else
segmentStartVC = vl.GetVisualColumn(segmentStart - vlStartOffset);
segmentStartVC = vl.ValidateVisualColumn(start, extendToFullWidthAtLineEnd);
int segmentEndVC;
if (segmentEnd > vlEndOffset)
segmentEndVC = vl.VisualLength;
segmentEndVC = extendToFullWidthAtLineEnd ? int.MaxValue : vl.VisualLength;
else
segmentEndVC = vl.GetVisualColumn(segmentEnd - vlStartOffset);
segmentEndVC = vl.ValidateVisualColumn(end, extendToFullWidthAtLineEnd);
TextLine lastTextLine = vl.TextLines.Last();
@ -121,7 +140,7 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -121,7 +140,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
if (segmentEndVC < visualStartCol)
break;
if (segmentStartVC > visualEndCol)
if (lastTextLine != line && segmentStartVC > visualEndCol)
continue;
int segmentStartVCInLine = Math.Max(segmentStartVC, visualStartCol);
int segmentEndVCInLine = Math.Min(segmentEndVC, visualEndCol);
@ -140,14 +159,33 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -140,14 +159,33 @@ namespace ICSharpCode.AvalonEdit.Rendering
continue;
yield return new Rect(pos, y, 1, line.Height);
} else {
foreach (TextBounds b in line.GetTextBounds(segmentStartVCInLine, segmentEndVCInLine - segmentStartVCInLine)) {
double left = b.Rectangle.Left;
double right = b.Rectangle.Right;
left -= scrollOffset.X;
right -= scrollOffset.X;
// left>right is possible in RTL languages
yield return new Rect(Math.Min(left, right), y, Math.Abs(right - left), line.Height);
Rect lastRect = Rect.Empty;
if (segmentStartVCInLine <= visualEndCol) {
foreach (TextBounds b in line.GetTextBounds(segmentStartVCInLine, segmentEndVCInLine - segmentStartVCInLine)) {
double left = b.Rectangle.Left - scrollOffset.X;
double right = b.Rectangle.Right - scrollOffset.X;
if (!lastRect.IsEmpty)
yield return lastRect;
// left>right is possible in RTL languages
lastRect = new Rect(Math.Min(left, right), y, Math.Abs(right - left), line.Height);
}
}
if (segmentEndVC >= vl.VisualLength) {
double left = (segmentStartVC > vl.VisualLength ? vl.GetTextLineVisualXPosition(line, segmentStartVC) : line.Width) - scrollOffset.X;
double right = (segmentEndVC == int.MaxValue ? Math.Max(((IScrollInfo)textView).ExtentWidth, ((IScrollInfo)textView).ViewportWidth) : vl.GetTextLineVisualXPosition(line, segmentEndVC)) - scrollOffset.X;
Rect extendSelection = new Rect(Math.Min(left, right), y, Math.Abs(right - left), line.Height);
if (!lastRect.IsEmpty) {
if (extendSelection.IntersectsWith(lastRect)) {
lastRect.Union(extendSelection);
yield return lastRect;
} else {
yield return lastRect;
yield return extendSelection;
}
} else
yield return extendSelection;
} else
yield return lastRect;
}
}
}

12
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs

@ -609,6 +609,18 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -609,6 +609,18 @@ namespace ICSharpCode.AvalonEdit.Rendering
InvalidateMeasure(DispatcherPriority.Normal);
}
/// <summary>
/// Causes a known layer to redraw.
/// This method does not invalidate visual lines;
/// use the <see cref="Redraw()"/> method to do that.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "knownLayer",
Justification="This method is meant to invalidate only a specific layer - I just haven't figured out how to do that, yet.")]
public void InvalidateLayer(KnownLayer knownLayer, DispatcherPriority priority)
{
InvalidateMeasure(priority);
}
/// <summary>
/// Causes the text editor to redraw all lines overlapping with the specified segment.
/// Does nothing if segment is null.

20
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs

@ -351,6 +351,26 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -351,6 +351,26 @@ namespace ICSharpCode.AvalonEdit.Rendering
return ch.FirstCharacterIndex + ch.TrailingLength;
}
public int ValidateVisualColumn(TextViewPosition position, bool allowVirtualSpace)
{
int offset = Document.GetOffset(position);
int firstDocumentLineOffset = this.FirstDocumentLine.Offset;
if (position.VisualColumn < 0) {
return GetVisualColumn(offset - firstDocumentLineOffset);
} else {
int offsetFromVisualColumn = GetRelativeOffset(position.VisualColumn);
offsetFromVisualColumn += firstDocumentLineOffset;
if (offsetFromVisualColumn != offset) {
return GetVisualColumn(offset - firstDocumentLineOffset);
} else {
if (position.VisualColumn > VisualLength && !allowVirtualSpace) {
return VisualLength;
}
}
}
return position.VisualColumn;
}
/// <summary>
/// Gets the visual column from a document position (relative to top left of the document).
/// If the user clicks between two visual columns, returns the first of those columns.

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Search/SearchPanel.cs

@ -279,7 +279,7 @@ namespace ICSharpCode.AvalonEdit.Search @@ -279,7 +279,7 @@ namespace ICSharpCode.AvalonEdit.Search
if (!string.IsNullOrEmpty(SearchPattern)) {
int offset = textArea.Caret.Offset;
if (changeSelection) {
textArea.Selection = SimpleSelection.Empty;
textArea.ClearSelection();
}
foreach (SearchResult result in strategy.FindAll(textArea.Document, 0, textArea.Document.TextLength)) {
if (currentResult == null && result.StartOffset >= offset) {
@ -303,7 +303,7 @@ namespace ICSharpCode.AvalonEdit.Search @@ -303,7 +303,7 @@ namespace ICSharpCode.AvalonEdit.Search
void SetResult(SearchResult result)
{
textArea.Caret.Offset = currentResult.StartOffset;
textArea.Selection = new SimpleSelection(currentResult.StartOffset, currentResult.EndOffset);
textArea.Selection = Selection.Create(textArea, currentResult.StartOffset, currentResult.EndOffset);
var foldingManager = textArea.GetService(typeof(FoldingManager)) as FoldingManager;
if (foldingManager != null) {
foreach (var folding in foldingManager.GetFoldingsContaining(result.StartOffset))

Loading…
Cancel
Save