/// <summary> /// Splits the element. /// </summary> /// <param name="splitStartOffset">Position inside this element at which it should be broken</param> /// <param name="elements">The collection of line elements</param> /// <param name="elementIndex">The index at which this element is in the elements list.</param> public void Split(int splitStartOffset, IList<VisualLineElement> elements, int elementIndex) { if (splitStartOffset <= Offset || splitStartOffset >= Offset + Length) throw new ArgumentOutOfRangeException("splitStartOffset", splitStartOffset, "Value must be between " + (Offset + 1) + " and " + (Offset + Length - 1)); if (elements == null) throw new ArgumentNullException("elements"); if (elements[elementIndex] != this) throw new ArgumentException("Invalid elementIndex - couldn't find this element at the index"); int part1Length = splitStartOffset - Offset; int part2Length = Length - part1Length; Length = part1Length; UpdateText(); var splitPart = new VisualLineElement((VisualLine) Parent, splitStartOffset, part2Length); elements.Insert(elementIndex + 1, splitPart); }
/// <summary> /// Applies a highlighting color to a visual line element. /// </summary> protected virtual void ApplyColorToElement(VisualLineElement element, HighlightingColor color) { element.TextRunProperties = color.Apply(element.TextRunProperties); }
void PerformVisualElementConstruction(VisualLineElementGenerator[] generators) { TextDocument document = TextLayer.Document; int offset = DocumentLine.Offset; int currentLineEnd = offset + DocumentLine.Length; int askInterestOffset = 0; // 0 or 1 while (offset + askInterestOffset <= currentLineEnd) { int textLineEndOffset = currentLineEnd; foreach (VisualLineElementGenerator g in generators) { g.cachedInterest = g.GetFirstInterestedOffset(offset + askInterestOffset); if (g.cachedInterest != -1) { if (g.cachedInterest < offset) { throw new ArgumentOutOfRangeException(g.GetType().Name + ".GetFirstInterestedOffset", g.cachedInterest, "GetFirstInterestedOffset must not return an offset less than startOffset. Return -1 to signal no interest."); } if (g.cachedInterest < textLineEndOffset) { textLineEndOffset = g.cachedInterest; } } } Debug.Assert(textLineEndOffset >= offset); if (textLineEndOffset > offset) { int textElementLength = textLineEndOffset - offset; var element = new VisualLineElement(this, offset, textElementLength); elements.Add(element); offset = textLineEndOffset; } // If no elements constructed / only zero-length elements constructed: // do not asking the generators again for the same location (would cause endless loop) askInterestOffset = 1; foreach (VisualLineElementGenerator g in generators) { if (g.cachedInterest == offset) { VisualLineElement element = g.ConstructElement(offset); if (element != null) { elements.Add(element); if (element.Text.Length > 0) { // a non-zero-length element was constructed askInterestOffset = 0; offset += element.Text.Length; if (offset > currentLineEnd) { DocumentLine newEndLine = document.GetLineByOffset(offset); currentLineEnd = newEndLine.Offset + newEndLine.Length; if (currentLineEnd < offset) { throw new InvalidOperationException( "The VisualLineElementGenerator " + g.GetType().Name + " produced an element which ends within the line delimiter"); } } break; } } } } } }
void PerformVisualElementConstruction(VisualLineElementGenerator[] generators) { TextDocument document = TextLayer.Document; int offset = DocumentLine.Offset; int currentLineEnd = offset + DocumentLine.Length; int askInterestOffset = 0; // 0 or 1 while (offset + askInterestOffset <= currentLineEnd) { int textLineEndOffset = currentLineEnd; foreach (VisualLineElementGenerator g in generators) { g.cachedInterest = g.GetFirstInterestedOffset(offset + askInterestOffset); if (g.cachedInterest != -1) { if (g.cachedInterest < offset) throw new ArgumentOutOfRangeException(g.GetType().Name + ".GetFirstInterestedOffset", g.cachedInterest, "GetFirstInterestedOffset must not return an offset less than startOffset. Return -1 to signal no interest."); if (g.cachedInterest < textLineEndOffset) textLineEndOffset = g.cachedInterest; } } Debug.Assert(textLineEndOffset >= offset); if (textLineEndOffset > offset) { int textElementLength = textLineEndOffset - offset; var element = new VisualLineElement(this, offset, textElementLength); elements.Add(element); offset = textLineEndOffset; } // If no elements constructed / only zero-length elements constructed: // do not asking the generators again for the same location (would cause endless loop) askInterestOffset = 1; foreach (VisualLineElementGenerator g in generators) { if (g.cachedInterest == offset) { VisualLineElement element = g.ConstructElement(offset); if (element != null) { elements.Add(element); if (element.Text.Length > 0) { // a non-zero-length element was constructed askInterestOffset = 0; offset += element.Text.Length; if (offset > currentLineEnd) { DocumentLine newEndLine = document.GetLineByOffset(offset); currentLineEnd = newEndLine.Offset + newEndLine.Length; if (currentLineEnd < offset) { throw new InvalidOperationException( "The VisualLineElementGenerator " + g.GetType().Name + " produced an element which ends within the line delimiter"); } } break; } } } } } }