void ElementGenerator_Removed(VisualLineElementGenerator generator) { DisconnectFromTextView(generator); Redraw(); }
internal void ConstructVisualElements(VisualLineElementGenerator[] generators) { Debug.Assert(phase == LifetimePhase.Generating); foreach (VisualLineElementGenerator g in generators) { g.StartGeneration(this); } elements.Clear(); PerformVisualElementConstruction(generators); foreach (VisualLineElementGenerator g in generators) { g.FinishGeneration(); } phase = LifetimePhase.Transforming; }
void ElementGenerator_Added(VisualLineElementGenerator generator) { ConnectToTextView(generator); Redraw(); }
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; } } } } } }