コード例 #1
0
        void TextViewVisualLinesChanged(object sender, EventArgs e)
        {
            foreach (FoldingMarginMarker m in markers)
            {
                RemoveVisualChild(m);
            }
            markers.Clear();
            InvalidateVisual();
            if (TextView != null && FoldingManager != null && TextView.VisualLinesValid)
            {
                foreach (VisualLine line in TextView.VisualLines)
                {
                    FoldingSection fs = FoldingManager.GetNextFolding(line.FirstDocumentLine.Offset);
                    if (fs == null)
                    {
                        continue;
                    }
                    if (fs.StartOffset <= line.LastDocumentLine.Offset + line.LastDocumentLine.Length)
                    {
                        FoldingMarginMarker m = new FoldingMarginMarker {
                            IsExpanded     = !fs.IsFolded,
                            VisualLine     = line,
                            FoldingSection = fs
                        };
                        markers.Add(m);
                        AddVisualChild(m);

                        m.IsMouseDirectlyOverChanged += delegate { InvalidateVisual(); };

                        InvalidateMeasure();
                        continue;
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Gets the first offset greater or equal to <paramref name="startOffset"/> where a folded folding starts.
        /// Returns -1 if there are no foldings after <paramref name="startOffset"/>.
        /// </summary>
        public int GetNextFoldedFoldingStart(int startOffset)
        {
            FoldingSection fs = foldings.FindFirstSegmentWithStartAfter(startOffset);

            while (fs != null && !fs.IsFolded)
            {
                fs = foldings.GetNextSegment(fs);
            }
            return(fs != null ? fs.StartOffset : -1);
        }
コード例 #3
0
 /// <summary>
 /// Removes a folding section from this manager.
 /// </summary>
 public void RemoveFolding(FoldingSection fs)
 {
     if (fs == null)
     {
         throw new ArgumentNullException("fs");
     }
     fs.IsFolded = false;
     foldings.Remove(fs);
     textView.Redraw(fs, DispatcherPriority.Normal);
 }
コード例 #4
0
        /// <summary>
        /// Gets all foldings that start exactly at <paramref name="startOffset"/>.
        /// </summary>
        public ReadOnlyCollection <FoldingSection> GetFoldingsAt(int startOffset)
        {
            List <FoldingSection> result = new List <FoldingSection>();
            FoldingSection        fs     = foldings.FindFirstSegmentWithStartAfter(startOffset);

            while (fs != null && fs.StartOffset == startOffset)
            {
                result.Add(fs);
                fs = foldings.GetNextSegment(fs);
            }
            return(result.AsReadOnly());
        }
コード例 #5
0
        /// <summary>
        /// Creates a folding for the specified text section.
        /// </summary>
        public FoldingSection CreateFolding(int startOffset, int endOffset)
        {
            if (startOffset >= endOffset)
            {
                throw new ArgumentException("startOffset must be less than endOffset");
            }
            FoldingSection fs = new FoldingSection(this, startOffset, endOffset);

            foldings.Add(fs);
            textView.Redraw(fs, DispatcherPriority.Normal);
            return(fs);
        }
コード例 #6
0
        void OnDocumentChanged(DocumentChangeEventArgs e)
        {
            foldings.UpdateOffsets(e);
            FoldingSection s = foldings.FindFirstSegmentWithStartAfter(e.Offset);

            while (s != null && s.StartOffset == e.Offset)
            {
                FoldingSection next = foldings.GetNextSegment(s);
                if (s.Length == 0)
                {
                    RemoveFolding(s);
                }
                s = next;
            }
        }
コード例 #7
0
        /// <summary>
        /// Updates the foldings in this <see cref="FoldingManager"/> using the given new foldings.
        /// This method will try to detect which new foldings correspond to which existing foldings; and will keep the state
        /// (<see cref="FoldingSection.IsFolded"/>) for existing foldings.
        /// </summary>
        /// <param name="newFoldings">The new set of foldings. These must be sorted by starting offset.</param>
        /// <param name="firstErrorOffset">The first position of a parse error. Existing foldings starting after
        /// this offset will be kept even if they don't appear in <paramref name="newFoldings"/>.
        /// Use -1 for this parameter if there were no parse errors.</param>
        public void UpdateFoldings(IEnumerable <NewFolding> newFoldings, int firstErrorOffset)
        {
            if (newFoldings == null)
            {
                throw new ArgumentNullException("newFoldings");
            }

            if (firstErrorOffset < 0)
            {
                firstErrorOffset = int.MaxValue;
            }

            var oldFoldings         = this.AllFoldings.ToArray();
            int oldFoldingIndex     = 0;
            int previousStartOffset = 0;

            // merge new foldings into old foldings so that sections keep being collapsed
            // both oldFoldings and newFoldings are sorted by start offset
            foreach (NewFolding newFolding in newFoldings)
            {
                // ensure newFoldings are sorted correctly
                if (newFolding.StartOffset < previousStartOffset)
                {
                    throw new ArgumentException("newFoldings must be sorted by start offset");
                }
                previousStartOffset = newFolding.StartOffset;

                if (newFolding.StartOffset == newFolding.EndOffset)
                {
                    continue;                     // ignore zero-length foldings
                }
                // remove old foldings that were skipped
                while (oldFoldingIndex < oldFoldings.Length && newFolding.StartOffset > oldFoldings[oldFoldingIndex].StartOffset)
                {
                    this.RemoveFolding(oldFoldings[oldFoldingIndex++]);
                }
                FoldingSection section;
                // reuse current folding if its matching:
                if (oldFoldingIndex < oldFoldings.Length && newFolding.StartOffset == oldFoldings[oldFoldingIndex].StartOffset)
                {
                    section        = oldFoldings[oldFoldingIndex++];
                    section.Length = newFolding.EndOffset - newFolding.StartOffset;
                }
                else
                {
                    // no matching current folding; create a new one:
                    section = this.CreateFolding(newFolding.StartOffset, newFolding.EndOffset);
                    // auto-close #regions only when opening the document
                    section.IsFolded = newFolding.DefaultClosed;
                    section.Tag      = newFolding;
                }
                section.Title = newFolding.Name;
            }
            // remove all outstanding old foldings:
            while (oldFoldingIndex < oldFoldings.Length)
            {
                FoldingSection oldSection = oldFoldings[oldFoldingIndex++];
                if (oldSection.StartOffset >= firstErrorOffset)
                {
                    break;
                }
                this.RemoveFolding(oldSection);
            }
        }