~ubuntu-branches/ubuntu/lucid/monodevelop/lucid

« back to all changes in this revision

Viewing changes to src/core/Mono.Texteditor/Mono.TextEditor/TextViewMargin.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-01-10 14:25:59 UTC
  • mfrom: (1.2.5 upstream) (1.3.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100110142559-sorji5exvk9tyknr
Tags: 2.2+dfsg-2
* debian/rules/remove_support_for_non_debian_functionality.patch:
  + Also fix monodevelop-core-addins.pc to remove links to the
    addins we remove in Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
                readonly TextEditor textEditor;
45
45
                Pango.TabArray tabArray = null;
46
46
                Pango.Layout markerLayout = null;
47
 
                int charWidth;
 
47
                internal int charWidth;
48
48
 
49
49
                int lineHeight = 16;
50
50
                int highlightBracketOffset = -1;
70
70
                        }
71
71
                }
72
72
                
 
73
                /// <summary>
 
74
                /// Set to true to highlight the caret line temporarly. It's
 
75
                /// the same as the option, but is unset when the caret moves.
 
76
                /// </summary>
 
77
                bool highlightCaretLine;
 
78
                public bool HighlightCaretLine {
 
79
                        get { 
 
80
                                return highlightCaretLine; 
 
81
                        }
 
82
                        set {
 
83
                                highlightCaretLine = value; 
 
84
                                RemoveCachedLine (Document.GetLine (Caret.Line)); 
 
85
                                Document.CommitLineUpdate (Caret.Line);
 
86
                        }
 
87
                }
73
88
 
74
89
                Caret Caret {
75
90
                        get { return textEditor.Caret; }
98
113
                                throw new ArgumentNullException ("textEditor");
99
114
                        this.textEditor = textEditor;
100
115
                        
101
 
                        ResetCaretBlink ();
102
116
                        textEditor.Document.TextReplaced += delegate(object sender, ReplaceEventArgs e) {
103
117
                                if (mouseSelectionMode == MouseSelectionMode.Word && e.Offset < mouseWordStart) {
104
118
                                        int delta = -e.Count;
127
141
                        markerLayout = new Pango.Layout (textEditor.PangoContext);
128
142
                        
129
143
                        textEditor.Document.EndUndo += UpdateBracketHighlighting;
 
144
                        textEditor.Document.Undone += delegate {
 
145
                                UpdateBracketHighlighting (this, EventArgs.Empty);
 
146
                        };
 
147
                        textEditor.Document.Redone += delegate {
 
148
                                UpdateBracketHighlighting (this, EventArgs.Empty);
 
149
                        };
130
150
                        Caret.PositionChanged += UpdateBracketHighlighting;
131
151
                }
132
152
                
149
169
                        linesToRemove.ForEach (line => RemoveCachedLine (line));
150
170
                        linesToRemove.Clear ();
151
171
 
152
 
                        ResetCaretBlink ();
 
172
                        textEditor.RequestResetCaretBlink ();
 
173
                }
 
174
                
 
175
                internal void ClearSearchMaker ()
 
176
                {
 
177
                        selectedRegions.Clear ();
153
178
                }
154
179
                
155
180
                void HandleSearchChanged (object sender, EventArgs args)
215
240
                
216
241
                void UpdateBracketHighlighting (object sender, EventArgs e)
217
242
                {
 
243
                        HighlightCaretLine = false;
218
244
                        if (!textEditor.Options.HighlightMatchingBracket)
219
245
                                return;
 
246
                        
220
247
                        int offset = Caret.Offset - 1;
221
248
                        if (offset >= 0 && offset < Document.Length && !Document.IsBracket (Document.GetCharAt (offset)))
222
249
                                offset++;
258
285
                                highlightBracketOffset = matchingBracket;
259
286
                                int line1 = oldIndex >= 0 ? Document.OffsetToLineNumber (oldIndex) : -1;
260
287
                                int line2 = highlightBracketOffset >= 0 ? Document.OffsetToLineNumber (highlightBracketOffset) : -1;
 
288
                                DocumentLocation matchingBracketLocation = Document.OffsetToLocation (matchingBracket);
261
289
                                Application.Invoke (delegate {
262
290
                                        if (line1 >= 0)
263
291
                                                textEditor.RedrawLine (line1);
305
333
                                tabArray = null;
306
334
                        }
307
335
                        
 
336
                        EnsureCaretGc ();
308
337
                        
309
338
                        Pango.Layout tabWidthLayout = new Pango.Layout (textEditor.PangoContext);
310
339
                        tabWidthLayout.Alignment = Pango.Alignment.Left;
320
349
                        chunkDict.Clear ();
321
350
                }
322
351
 
 
352
                void EnsureCaretGc ()
 
353
                {
 
354
                        if (caretGc != null) 
 
355
                                return;
 
356
                        caretGc = new Gdk.GC (textEditor.GdkWindow);
 
357
                        caretGc.RgbFgColor = new Color (255, 255, 255);
 
358
                        caretGc.Function = Gdk.Function.Xor;
 
359
                }
 
360
                
323
361
                void DisposeGCs ()
324
362
                {
325
363
                        ShowTooltip (null, Gdk.Rectangle.Zero);
358
396
                        
359
397
                        DisposeHighightBackgroundWorker ();
360
398
                        DisposeSearchPatternWorker ();
 
399
                        lock (lockObject) {
 
400
                                if (caretTimer != null) {
 
401
                                        StopCaretThread ();
 
402
                                        caretTimer.Dispose ();
 
403
                                        caretTimer = null;
 
404
                                }
 
405
                        }
361
406
                        
362
 
                        caretTimer.Stop ();
363
 
                        caretTimer.Dispose ();
364
 
 
365
407
                        textEditor.Document.EndUndo -= UpdateBracketHighlighting;
366
408
                        Caret.PositionChanged -= UpdateBracketHighlighting;
367
409
 
395
437
                #region Caret blinking
396
438
                Timer caretTimer = null;
397
439
                bool caretBlink = true;
398
 
                int caretBlinkStatus;
399
 
 
 
440
//              bool firstBlink = true;
 
441
                object lockObject = new object ();
 
442
                
400
443
                public void ResetCaretBlink ()
401
444
                {
402
 
                        if (caretTimer == null) {
403
 
                                caretTimer = new Timer ();
404
 
                                caretTimer.Elapsed += UpdateCaret;
405
 
                                caretTimer.Interval = (uint)Gtk.Settings.Default.CursorBlinkTime / 2;
406
 
                        } else {
407
 
                                caretTimer.Stop ();
408
 
                        }
409
 
                        bool shouldRedraw = !caretBlink;
410
 
                        caretBlink = true; 
411
 
                        caretBlinkStatus = 0;
412
 
                        if (shouldRedraw)
413
 
                                textEditor.RedrawMarginLine (this, Caret.Line);
414
 
                        caretTimer.Start ();
 
445
                        lock (lockObject) {
 
446
                                if (caretTimer != null)
 
447
                                        StopCaretThread ();
 
448
                                
 
449
                                if (caretTimer == null) {
 
450
                                        caretTimer = new Timer (Gtk.Settings.Default.CursorBlinkTime / 2);
 
451
                                        caretTimer.Elapsed += UpdateCaret;
 
452
                                }
 
453
                                bool shouldRedraw = !caretBlink;
 
454
                                caretBlink = true; 
 
455
                                if (shouldRedraw)
 
456
                                        textEditor.RedrawMarginLine (this, Caret.Line);
 
457
//                              firstBlink = true;
 
458
                                caretTimer.Start ();
 
459
                        }
 
460
                }
 
461
 
 
462
                internal void StopCaretThread ()
 
463
                {
 
464
                        lock (lockObject) {
 
465
                                
 
466
                                if (caretTimer != null)
 
467
                                        caretTimer.Stop ();
 
468
                                caretBlink = false; 
 
469
                        }
415
470
                }
416
471
                
417
472
                void UpdateCaret (object sender, EventArgs args)
418
473
                {
419
 
                        bool newCaretBlink = caretBlinkStatus < 4 || (caretBlinkStatus - 4) % 3 != 0;
420
 
                        if (newCaretBlink != caretBlink) {
421
 
                                caretBlink = newCaretBlink;
422
 
                                
423
 
                                Application.Invoke (delegate {
424
 
                                        try {
425
 
                                                textEditor.RedrawMarginLine (this, Caret.Line);
426
 
                                        } catch (Exception) {
427
 
                                                
428
 
                                        }
429
 
                                });
 
474
                        lock (lockObject) {
 
475
                        /*      if (firstBlink) {
 
476
                                        firstBlink = false;
 
477
                                        return;
 
478
                                }*/
 
479
                                caretBlink = !caretBlink;
 
480
                                if (Caret.IsVisible) {
 
481
                                        Application.Invoke (delegate {
 
482
                                                try {
 
483
                                                        textEditor.RedrawMarginLine (this, Caret.Line);
 
484
                                                } catch (Exception) {
 
485
                                                        
 
486
                                                }
 
487
                                        });
 
488
                                }
430
489
                        }
431
 
                        caretBlinkStatus++;
432
490
                }
433
491
                #endregion
434
492
 
445
503
                }
446
504
                
447
505
                public static Gdk.Rectangle EmptyRectangle = new Gdk.Rectangle (0, 0, 0, 0);
448
 
                public Gdk.Rectangle DrawCaret (Gdk.Drawable win)
 
506
                public void DrawCaret (Gdk.Drawable win)
449
507
                {
450
508
                        if (!this.textEditor.IsInDrag) {
451
 
                                if (!(this.caretX >= 0 && (!this.textEditor.IsSomethingSelected || this.textEditor.SelectionRange.Length == 0)))
452
 
                                        return EmptyRectangle;
453
 
                                if (!textEditor.HasFocus)
454
 
                                        return EmptyRectangle;
455
 
                        }
456
 
                        if (Settings.Default.CursorBlink && (!Caret.IsVisible || !caretBlink))
457
 
                                return EmptyRectangle;
458
 
                        if (caretGc == null) {
459
 
                                caretGc = new Gdk.GC (win);
460
 
                                caretGc.RgbFgColor = new Color (255, 255, 255);
461
 
                                caretGc.Function = Gdk.Function.Xor;
462
 
                        }
463
 
                        // Unlike the clip region for the backing store buffer, this needs
464
 
                        // to be clipped to the range of the visible area of the widget to
465
 
                        // prevent drawing outside the widget on some Gdk backends.
466
 
                        Gdk.Rectangle caretClipRectangle = GetCaretRectangle (Caret.Mode);
467
 
                        int width, height;
468
 
                        win.GetSize (out width, out height);
469
 
                        caretClipRectangle.Intersect (new Gdk.Rectangle (0, 0, width, height));
470
 
                        caretGc.ClipRectangle = caretClipRectangle;
 
509
                                if (!(this.caretX >= 0 && (!this.textEditor.IsSomethingSelected || this.textEditor.SelectionRange.Length == 0))) {
 
510
                                        return;
 
511
                                }
 
512
                        }
 
513
                        if (Settings.Default.CursorBlink && (!Caret.IsVisible || !caretBlink)) {
 
514
                                return;
 
515
                        }
 
516
                        
471
517
                        switch (Caret.Mode) {
472
518
                        case CaretMode.Insert:
473
 
                                if (caretX < this.XOffset || caretClipRectangle == Gdk.Rectangle.Zero)
474
 
                                        return EmptyRectangle;
475
519
                                win.DrawLine (caretGc, caretX, caretY, caretX, caretY + LineHeight - 1);
476
520
                                break;
477
521
                        case CaretMode.Block:
478
 
                                if (caretX + this.charWidth < this.XOffset)
479
 
                                        return EmptyRectangle;
480
522
                                win.DrawRectangle (caretGc, true, new Gdk.Rectangle (caretX, caretY, this.charWidth, LineHeight));
481
523
                                /*                                      textRenderer.BeginDraw (win);
482
524
//                              textRenderer.SetClip (clipRectangle);
486
528
                                        textRenderer.EndDraw ();*/
487
529
                                break;
488
530
                        case CaretMode.Underscore:
489
 
                                if (caretX + this.charWidth < this.XOffset)
490
 
                                        return EmptyRectangle;
491
531
                                int bottom = caretY + lineHeight;
492
532
                                win.DrawLine (caretGc, caretX, bottom, caretX + this.charWidth, bottom);
493
 
                                        break;
 
533
                                break;
494
534
                        }
495
 
                        return caretClipRectangle;
496
535
                }
497
536
 
498
537
                public Gdk.Rectangle GetCaretRectangle (Mono.TextEditor.CaretMode mode)
685
724
 
686
725
                public void RemoveCachedLine (LineSegment line)
687
726
                {
 
727
                        if (line == null)
 
728
                                return;
688
729
                        LayoutDescriptor descriptor;
689
730
                        if (layoutDict.TryGetValue (line, out descriptor)) {
690
731
                                descriptor.Dispose ();
815
856
                        return Encoding.UTF8.GetString (bytes, 0, index).Length;
816
857
                }
817
858
        
818
 
                class LayoutWrapper : IDisposable
 
859
                public class LayoutWrapper : IDisposable
819
860
                {
820
861
                        public Pango.Layout Layout {
821
862
                                get;
867
908
                        }
868
909
                }
869
910
                
870
 
                LayoutWrapper CreateLinePartLayout (SyntaxMode mode, LineSegment line, int offset, int length, int selectionStart, int selectionEnd)
 
911
                public LayoutWrapper CreateLinePartLayout (SyntaxMode mode, LineSegment line, int offset, int length, int selectionStart, int selectionEnd)
871
912
                {
872
913
                        return GetCachedLayout (line, offset, length, selectionStart, selectionEnd, delegate(LayoutWrapper wrapper) {
873
914
                                wrapper.Layout.Alignment = Pango.Alignment.Left;
900
941
                                while ((firstSearch = GetFirstSearchResult (o, offset + length)) != null) {
901
942
                                        HandleSelection (line, selectionStart, selectionEnd, firstSearch.Offset, firstSearch.EndOffset, delegate(int start, int end) {
902
943
                                                Pango.AttrBackground backGround = new Pango.AttrBackground (ColorStyle.SearchTextBg.Red, ColorStyle.SearchTextBg.Green, ColorStyle.SearchTextBg.Blue);
903
 
                                                backGround.StartIndex = TranslateToUTF8Index (lineChars, (uint)(start - offset), ref curIndex, ref byteIndex);
904
 
                                                backGround.EndIndex = TranslateToUTF8Index (lineChars, (uint)(end - offset), ref curIndex, ref byteIndex);
905
 
                                                wrapper.Add (backGround);
 
944
                                                uint startIndex = (uint)(start - offset);
 
945
                                                uint endIndex = (uint)(end - offset);
 
946
                                                if (startIndex < endIndex && endIndex < lineChars.Length) {
 
947
                                                        backGround.StartIndex = TranslateToUTF8Index (lineChars, startIndex, ref curIndex, ref byteIndex);
 
948
                                                        backGround.EndIndex = TranslateToUTF8Index (lineChars, endIndex, ref curIndex, ref byteIndex);
 
949
                                                        wrapper.Add (backGround);
 
950
                                                }
906
951
                                        }, null);
907
952
 
908
953
                                        o = System.Math.Max (firstSearch.EndOffset, o + 1);
936
981
                                                        foreGround.EndIndex = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex);
937
982
                                                        wrapper.Add (foreGround);
938
983
 
939
 
                                                        if (!chunkStyle.TransparentBackround) {
 
984
                                                        if (!chunkStyle.TransparentBackround && GetPixel (ColorStyle.Default.BackgroundColor) != GetPixel (chunkStyle.BackgroundColor)) {
940
985
                                                                Pango.AttrBackground backGround = new Pango.AttrBackground (chunkStyle.BackgroundColor.Red, chunkStyle.BackgroundColor.Green, chunkStyle.BackgroundColor.Blue);
941
986
                                                                backGround.StartIndex = foreGround.StartIndex;
942
987
                                                                backGround.EndIndex = foreGround.EndIndex;
1026
1071
                                }
1027
1072
                        }
1028
1073
                }
1029
 
 
 
1074
                
1030
1075
                void DecorateMatchingBracket (Gdk.Drawable win, Pango.Layout layout, int offset, int length, int xPos, int y, int selectionStart, int selectionEnd)
1031
1076
                {
1032
1077
                        uint curIndex = 0, byteIndex = 0;
1034
1079
                        if (offset <= highlightBracketOffset && highlightBracketOffset <= offset + length) {
1035
1080
                                int index = highlightBracketOffset - offset;
1036
1081
                                Pango.Rectangle rect = layout.IndexToPos ((int)TranslateToUTF8Index (lineText.ToCharArray (), (uint)index, ref curIndex, ref byteIndex));
1037
 
 
 
1082
                                
1038
1083
                                Gdk.Rectangle bracketMatch = new Gdk.Rectangle (xPos + (int)(rect.X / Pango.Scale.PangoScale), y, (int)(rect.Width / Pango.Scale.PangoScale) - 1, (int)(rect.Height / Pango.Scale.PangoScale) - 1);
1039
 
                                win.DrawRectangle (GetGC (this.ColorStyle.BracketHighlightRectangle.BackgroundColor), true, bracketMatch);
 
1084
                                if (BackgroundRenderer == null)
 
1085
                                        win.DrawRectangle (GetGC (this.ColorStyle.BracketHighlightRectangle.BackgroundColor), true, bracketMatch);
 
1086
                                
1040
1087
                                win.DrawRectangle (GetGC (this.ColorStyle.BracketHighlightRectangle.Color), false, bracketMatch);
1041
1088
                        }
1042
1089
                }
1043
 
 
1044
 
 
 
1090
                
1045
1091
                void DrawLinePart (Gdk.Drawable win, LineSegment line, int offset, int length, ref int xPos, int y, int maxX)
1046
1092
                {
1047
1093
                        SyntaxMode mode = Document.SyntaxMode != null && textEditor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : SyntaxMode.Default;
1048
1094
                        int selectionStart;
1049
1095
                        int selectionEnd;
1050
 
                        GetSelectionOffsets (line, out selectionStart, out selectionEnd);
 
1096
                        if (BackgroundRenderer != null)  {
 
1097
                                selectionStart = selectionEnd = -1;
 
1098
                        } else {
 
1099
                                GetSelectionOffsets (line, out selectionStart, out selectionEnd);
 
1100
                        }
1051
1101
 
1052
1102
                        // ---- new renderer
1053
1103
                        LayoutWrapper layout = CreateLinePartLayout (mode, line, offset, length, selectionStart, selectionEnd);
1229
1279
                                                textEditor.ClearSelection ();
1230
1280
                                                Caret.Location = clickLocation;
1231
1281
                                        }
1232
 
                                        ResetCaretBlink ();
 
1282
                                        textEditor.RequestResetCaretBlink ();
1233
1283
                                }
1234
1284
                        }
1235
1285
 
1581
1631
                
1582
1632
                void DrawRectangleWithRuler (Gdk.Drawable win, int x, Gdk.Rectangle area, Gdk.Color color, bool drawDefaultBackground)
1583
1633
                {
 
1634
                        if (BackgroundRenderer != null)
 
1635
                                return;
1584
1636
                        bool isDefaultColor = (color.Red == defaultBgColor.Red && color.Green == defaultBgColor.Green && color.Blue == defaultBgColor.Blue);
1585
1637
                        if (isDefaultColor && !drawDefaultBackground)
1586
1638
                                return;
1669
1721
                        // Draw the default back color for the whole line. Colors other than the default
1670
1722
                        // background will be drawn when rendering the text chunks.
1671
1723
                        
1672
 
                        if (textEditor.Options.HighlightCaretLine && Caret.Line == lineNr)
 
1724
                        if (BackgroundRenderer != null)
 
1725
                                BackgroundRenderer.Draw (win, area, line, x, y);
 
1726
                        
 
1727
                        if ((HighlightCaretLine || textEditor.Options.HighlightCaretLine) && Caret.Line == lineNr)
1673
1728
                                defaultBgColor = ColorStyle.LineMarker;
1674
1729
                        else
1675
1730
                                defaultBgColor = ColorStyle.Default.BackgroundColor;
1712
1767
                                        markerLayout.GetPixelSize (out width, out height);
1713
1768
                                        bool isFoldingSelected = textEditor.IsSomethingSelected && textEditor.SelectionRange.Contains (folding);
1714
1769
                                        Rectangle foldingRectangle = new Rectangle (xPos, y, width - 1, this.LineHeight - 1);
1715
 
                                        win.DrawRectangle (GetGC (isFoldingSelected ? ColorStyle.Selection.BackgroundColor : defaultBgColor), true, foldingRectangle);
 
1770
                                        if (BackgroundRenderer == null)
 
1771
                                                win.DrawRectangle (GetGC (isFoldingSelected ? ColorStyle.Selection.BackgroundColor : defaultBgColor), true, foldingRectangle);
 
1772
                                        /*
 
1773
                                        using (Cairo.Context cr = Gdk.CairoHelper.Create (win)) {
 
1774
                                                cr.Color = Mono.TextEditor.Highlighting.Style.ToCairoColor (isFoldingSelected ? ColorStyle.Selection.Color : ColorStyle.FoldLine.Color);
 
1775
                                                cr.LineWidth = textEditor.Options.Zoom;
 
1776
                                                FoldingScreenbackgroundRenderer.DrawRoundRectangle (cr, true, true, 
 
1777
                                                                                                    foldingRectangle.X, 
 
1778
                                                                                                    foldingRectangle.Y, 
 
1779
                                                                                                    textEditor.LineHeight / 2, 
 
1780
                                                                                                    foldingRectangle.Width, 
 
1781
                                                                                                    foldingRectangle.Height);
 
1782
                                                cr.Stroke ();
 
1783
                                        }*/
1716
1784
                                        win.DrawRectangle (GetGC (isFoldingSelected ? ColorStyle.Selection.Color : ColorStyle.FoldLine.Color), false, foldingRectangle);
1717
1785
                                        win.DrawLayout (GetGC (isFoldingSelected ? ColorStyle.Selection.Color : ColorStyle.FoldLine.Color), xPos, y, markerLayout);
1718
1786
                                        
1800
1868
                        }
1801
1869
                        lastLineRenderWidth = xPos;
1802
1870
                }
 
1871
                
 
1872
                internal IBackgroundRenderer BackgroundRenderer {
 
1873
                        get;
 
1874
                        set;
 
1875
                } 
 
1876
                
1803
1877
                internal int lastLineRenderWidth = 0;
1804
1878
                
1805
1879
                
1806
1880
                void SetClip (Gdk.Rectangle rect)
1807
1881
                {
1808
1882
                        clipRectangle = rect;
 
1883
                        EnsureCaretGc ();
 
1884
                        caretGc.ClipRectangle = rect;
1809
1885
                        foreach (Gdk.GC gc in gcDictionary.Values)
1810
1886
                                gc.ClipRectangle = rect;
1811
1887
                }