~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/Mono.Texteditor/Mono.TextEditor/Gui/FoldingScreenbackgroundRenderer.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
25
// THE SOFTWARE.
26
 
 
27
26
using System;
28
27
using System.Collections.Generic;
29
28
using Mono.TextEditor.Highlighting;
30
29
 
31
30
namespace Mono.TextEditor
32
31
{
33
 
        
34
 
        
35
 
        public class FoldingScreenbackgroundRenderer : IBackgroundRenderer
 
32
        public class FoldingScreenbackgroundRenderer : IBackgroundRenderer, IDisposable
36
33
        {
37
34
                TextEditor editor;
38
35
                List<FoldSegment> foldSegments;
39
 
                Roles[] roles;
40
36
                [Flags]
41
37
                enum Roles
42
38
                {
48
44
                        get { return editor.Document; }
49
45
                }
50
46
 
 
47
                readonly DateTime startTime;
 
48
                uint timeout;
 
49
                const uint animationLength = 250;
 
50
                public bool AnimationFinished {
 
51
                        get {
 
52
                                var age = (DateTime.Now - startTime).TotalMilliseconds;
 
53
                                return age >= animationLength;
 
54
                        }
 
55
                }
 
56
 
51
57
                public FoldingScreenbackgroundRenderer (TextEditor editor, IEnumerable<FoldSegment> foldSegments)
52
58
                {
53
59
                        this.editor = editor;
54
60
                        this.foldSegments = new List<FoldSegment> (foldSegments);
55
 
                        this.roles = new Roles[this.foldSegments.Count];
 
61
                        startTime = DateTime.Now;
 
62
                        timeout = GLib.Timeout.Add (30, delegate {
 
63
                                editor.QueueDraw ();
 
64
                                var cont = (DateTime.Now - startTime).TotalMilliseconds < animationLength;
 
65
                                if (!cont)
 
66
                                        timeout = 0;
 
67
                                return cont;
 
68
                        });
56
69
                }
57
70
 
58
 
                public void Draw (Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, double x, double y, double lineHeight)
 
71
                HslColor GetColor (int i, double brightness, int colorCount)
59
72
                {
60
 
                        int foundSegment = -1;
61
 
                        if (lineSegment != null) {
62
 
                                for (int i = 0; i < foldSegments.Count; i++) {
63
 
                                        FoldSegment segment = foldSegments [i];
64
 
                                        if (segment.StartLine.Offset <= lineSegment.Offset && lineSegment.EndOffsetIncludingDelimiter <= segment.EndLine.EndOffsetIncludingDelimiter) {
65
 
                                                foundSegment = i;
66
 
                                                roles [i] = Roles.Between;
67
 
                                                if (segment.StartLine.Offset == lineSegment.Offset) {
68
 
                                                        roles [i] |= Roles.Start;
69
 
                                                        if (segment.IsFolded)
70
 
                                                                roles [i] |= Roles.End;
71
 
                                                }
72
 
                                                if (segment.EndLine.Offset == lineSegment.Offset) 
73
 
                                                        roles [i] |= Roles.End;
74
 
                                        }
75
 
                                }
 
73
                        HslColor hslColor = new HslColor (editor.ColorStyle.PlainText.Background);
 
74
                        int colorPosition = i + 1;
 
75
                        if (i == foldSegments.Count - 1)
 
76
                                return hslColor;
 
77
                        if (brightness < 0.5) {
 
78
                                hslColor.L = hslColor.L * 0.81 + hslColor.L * 0.25 * (colorCount - colorPosition) / colorCount;
 
79
                        } else {
 
80
                                hslColor.L = hslColor.L * 0.86 + hslColor.L * 0.1 * colorPosition / colorCount;
76
81
                        }
 
82
                        return hslColor;
 
83
                }
 
84
                
 
85
                public void Draw (Cairo.Context cr, Cairo.Rectangle area)
 
86
                {
77
87
                        TextViewMargin textViewMargin = editor.TextViewMargin;
78
88
                        ISyntaxMode mode = Document.SyntaxMode != null && editor.Options.EnableSyntaxHighlighting ? Document.SyntaxMode : new SyntaxMode (Document);
79
 
                        
80
 
                        //      Gdk.Rectangle lineArea = new Gdk.Rectangle (textViewMargin.XOffset, y, editor.Allocation.Width - textViewMargin.XOffset, editor.LineHeight);
81
 
                        //      Gdk.GC gc = new Gdk.GC (drawable);
 
89
 
82
90
                        TextViewMargin.LayoutWrapper lineLayout = null;
83
 
                        double brightness = HslColor.Brightness (editor.ColorStyle.Default.BackgroundColor);
84
 
                        
 
91
                        double brightness = HslColor.Brightness (editor.ColorStyle.PlainText.Background);
 
92
 
85
93
                        int colorCount = foldSegments.Count + 2;
86
 
                        for (int segment = -1; segment <= foundSegment; segment++) {
87
 
                                HslColor hslColor = new HslColor (editor.ColorStyle.Default.BackgroundColor);
88
 
                                int colorPosition = segment + 1;
89
 
                                if (segment == foldSegments.Count - 1)
90
 
                                        colorPosition += 2;
91
 
                                if (brightness < 0.5) {
92
 
                                        hslColor.L = hslColor.L * 0.81 + hslColor.L * 0.25 * (colorCount - colorPosition) / colorCount;
93
 
                                } else {
94
 
                                        hslColor.L = hslColor.L * 0.86 + hslColor.L * 0.1 * colorPosition / colorCount;
95
 
                                }
96
 
                                
97
 
                                Roles role = Roles.Between;
 
94
                        cr.Color = GetColor (-1, brightness, colorCount);
 
95
                        cr.Rectangle (area);
 
96
                        cr.Fill ();
 
97
                        var rectangles = new Cairo.Rectangle[foldSegments.Count];
 
98
                        const int xPadding = 4;
 
99
                        const int yPadding = 2;
 
100
                        const int rightMarginPadding = 16;
 
101
                        for (int i = foldSegments.Count - 1; i >= 0 ; i--) {
 
102
                                var segment = foldSegments [i];
 
103
                                var segmentStartLine = segment.StartLine;
 
104
                                var segmentEndLine = segment.EndLine;
 
105
 
 
106
                                int curWidth = 0;
 
107
                                var endLine = segmentEndLine.NextLine;
 
108
                                var y = editor.LineToY (segmentStartLine.LineNumber);
 
109
                                if (y < editor.VAdjustment.Value) {
 
110
                                        segmentStartLine = editor.GetLine (editor.YToLine (editor.VAdjustment.Value));
 
111
                                        y = editor.LineToY (segmentStartLine.LineNumber);
 
112
                                }
 
113
 
 
114
                                for (var curLine = segmentStartLine; curLine != endLine && y < editor.VAdjustment.Value + editor.Allocation.Height; curLine = curLine.NextLine) {
 
115
                                        var curLayout = textViewMargin.CreateLinePartLayout (mode, curLine, curLine.Offset, curLine.Length, -1, -1);
 
116
                                        var width = (int)(curLayout.PangoWidth / Pango.Scale.PangoScale);
 
117
                                        curWidth = System.Math.Max (curWidth, width);
 
118
                                        y += editor.GetLineHeight (curLine);
 
119
                                }
 
120
 
98
121
                                double xPos = textViewMargin.XOffset;
99
 
                                double rectangleWidth = editor.Allocation.Width - xPos;
100
 
                                if (segment >= 0) {
101
 
                                        DocumentLine segmentStartLine = foldSegments [segment].StartLine;
102
 
                                        lineLayout = textViewMargin.CreateLinePartLayout (mode, segmentStartLine, segmentStartLine.Offset, segmentStartLine.Length, -1, -1);
103
 
                                        Pango.Rectangle rectangle = lineLayout.Layout.IndexToPos (GetFirstNonWsIdx (lineLayout.Layout.Text));
104
 
                                        xPos = System.Math.Max (textViewMargin.XOffset, (textViewMargin.XOffset + rectangle.X / Pango.Scale.PangoScale - editor.HAdjustment.Value));
105
 
                                        
106
 
                                        DocumentLine segmentEndLine = foldSegments [segment].EndLine;
107
 
                                        lineLayout = textViewMargin.CreateLinePartLayout (mode, segmentEndLine, segmentEndLine.Offset, segmentEndLine.Length, -1, -1);
108
 
                                        rectangle = lineLayout.Layout.IndexToPos (GetFirstNonWsIdx (lineLayout.Layout.Text));
109
 
                                        xPos = System.Math.Min (xPos, System.Math.Max (textViewMargin.XOffset, (textViewMargin.XOffset + rectangle.X / Pango.Scale.PangoScale - editor.HAdjustment.Value)));
110
 
                                        
111
 
                                        int width = editor.Allocation.Width;
112
 
                                        if (editor.HAdjustment.Upper > width) {
113
 
                                                width = (int)(textViewMargin.XOffset + editor.HAdjustment.Upper - editor.HAdjustment.Value);
114
 
                                        }
115
 
                                        rectangleWidth = (int)(width - xPos - 6 * (segment + 1));
116
 
                                        role = roles [segment];
117
 
                                }
118
 
                                DrawRoundRectangle (cr, (role & Roles.Start) == Roles.Start, (role & Roles.End) == Roles.End, xPos, y, editor.LineHeight / 2, rectangleWidth, lineHeight);
119
 
                                cr.Color = ColorScheme.ToCairoColor (hslColor);
 
122
                                double rectangleWidth = 0, rectangleHeight = 0;
 
123
                                
 
124
                                lineLayout = textViewMargin.CreateLinePartLayout (mode, segmentStartLine, segmentStartLine.Offset, segmentStartLine.Length, -1, -1);
 
125
                                var rectangleStart = lineLayout.Layout.IndexToPos (GetFirstNonWsIdx (lineLayout.Layout.Text));
 
126
                                xPos = System.Math.Max (textViewMargin.XOffset, (textViewMargin.XOffset + textViewMargin.TextStartPosition + rectangleStart.X / Pango.Scale.PangoScale) - xPadding);
 
127
 
 
128
                                lineLayout = textViewMargin.CreateLinePartLayout (mode, segmentEndLine, segmentEndLine.Offset, segmentEndLine.Length, -1, -1);
 
129
                                
 
130
                                var rectangleEnd = lineLayout.Layout.IndexToPos (GetFirstNonWsIdx (lineLayout.Layout.Text));
 
131
                                xPos = System.Math.Min (xPos, System.Math.Max (textViewMargin.XOffset, (textViewMargin.XOffset + textViewMargin.TextStartPosition + rectangleEnd.X / Pango.Scale.PangoScale) - xPadding));
 
132
 
 
133
                                rectangleWidth = textViewMargin.XOffset + textViewMargin.TextStartPosition + curWidth - xPos + xPadding * 2;
 
134
 
 
135
                                if (i < foldSegments.Count - 1) {
 
136
                                        rectangleWidth = System.Math.Max ((rectangles [i + 1].X + rectangles[i + 1].Width + rightMarginPadding) - xPos, rectangleWidth);
 
137
                                }
 
138
 
 
139
                                y = editor.LineToY (segment.StartLine.LineNumber);
 
140
                                var yEnd = editor.LineToY (segment.EndLine.LineNumber + 1);
 
141
                                if (yEnd == 0)
 
142
                                        yEnd = editor.VAdjustment.Upper;
 
143
                                rectangleHeight = yEnd - y;
 
144
 
 
145
                                rectangles[i] = new Cairo.Rectangle (xPos, y - yPadding, rectangleWidth, rectangleHeight + yPadding * 2);
 
146
                        }
 
147
 
 
148
                        for (int i = 0; i < foldSegments.Count; i++) {
 
149
                                var rect = rectangles[i];
 
150
 
 
151
                                if (i == foldSegments.Count - 1) {
 
152
/*                                      var radius = (int)(editor.Options.Zoom * 2);
 
153
                                        int w = 2 * radius;
 
154
                                        using (var shadow = new Blur (
 
155
                                                System.Math.Min ((int)rect.Width + w * 2, editor.Allocation.Width),
 
156
                                                System.Math.Min ((int)rect.Height + w * 2, editor.Allocation.Height), 
 
157
                                                radius)) {
 
158
                                                using (var gctx = shadow.GetContext ()) {
 
159
                                                        gctx.Color = new Cairo.Color (0, 0, 0, 0);
 
160
                                                        gctx.Fill ();
 
161
 
 
162
                                                        var a = 0;
 
163
                                                        var b = 0;
 
164
                                                        DrawRoundRectangle (gctx, true, true, w - a, w - b, editor.LineHeight / 4, rect.Width + a * 2, rect.Height + a * 2);
 
165
                                                        var bg = editor.ColorStyle.Default.CairoColor;
 
166
                                                        gctx.Color = new Cairo.Color (bg.R, bg.G, bg.B, 0.6);
 
167
                                                        gctx.Fill ();
 
168
                                                }
 
169
 
 
170
                                                cr.Save ();
 
171
                                                cr.Translate (rect.X - w - editor.HAdjustment.Value, rect.Y - editor.VAdjustment.Value - w);
 
172
                                                shadow.Draw (cr);
 
173
                                                cr.Restore ();
 
174
                                        }*/
 
175
 
 
176
                                        var curPadSize = 1;
 
177
 
 
178
                                        var age = (DateTime.Now - startTime).TotalMilliseconds;
 
179
                                        var alpha = 0.1;
 
180
                                        if (age < animationLength) {
 
181
                                                var animationState = age / (double)animationLength;
 
182
                                                curPadSize = (int)(3 + System.Math.Sin (System.Math.PI * animationState) * 3);
 
183
                                                alpha = 0.1 + (1.0 - animationState) / 5;
 
184
                                        }
 
185
 
 
186
                                        var bg = editor.ColorStyle.PlainText.Foreground;
 
187
                                        cr.Color = new Cairo.Color (bg.R, bg.G, bg.B, alpha);
 
188
                                        DrawRoundRectangle (cr, true, true, rect.X - editor.HAdjustment.Value - curPadSize , rect.Y - editor.VAdjustment.Value - curPadSize, editor.LineHeight / 2, rect.Width + curPadSize * 2, rect.Height + curPadSize * 2);
 
189
                                        cr.Fill ();
 
190
 
 
191
                                        if (age < animationLength) {
 
192
                                                var animationState = age / (double)animationLength;
 
193
                                                curPadSize = (int)(2 + System.Math.Sin (System.Math.PI * animationState) * 2);
 
194
                                                DrawRoundRectangle (cr, true, true, rect.X - editor.HAdjustment.Value - curPadSize, rect.Y - editor.VAdjustment.Value - curPadSize, editor.LineHeight / 2, rect.Width + curPadSize * 2, rect.Height + curPadSize * 2);
 
195
                                                cr.Color = GetColor (i, brightness, colorCount);
 
196
                                                cr.Fill ();
 
197
 
 
198
                                                continue;
 
199
                                        }
 
200
                                }
 
201
 
 
202
                                DrawRoundRectangle (cr, true, true, rect.X - editor.HAdjustment.Value, rect.Y - editor.VAdjustment.Value, editor.LineHeight / 2, rect.Width, rect.Height);
 
203
                                
 
204
                                cr.Color = GetColor (i, brightness, colorCount);
120
205
                                cr.Fill ();
121
 
                                /*              if (segment == foldSegments.Count - 1) {
122
 
                                        cr.Color = new Cairo.Color (0.5, 0.5, 0.5, 1);
123
 
                                        cr.Stroke ();
124
 
                                }*/
125
 
                                if (lineLayout != null && lineLayout.IsUncached) {
126
 
                                        lineLayout.Dispose ();
127
 
                                        lineLayout = null;
128
 
                                }
129
206
                        }
130
 
                        //              gc.Dispose ();
131
207
                }
132
208
 
133
209
                public static void DrawRoundRectangle (Cairo.Context cr, bool upperRound, bool lowerRound, double x, double y, double r, double w, double h)
135
211
                        DrawRoundRectangle (cr, upperRound, upperRound, lowerRound, lowerRound, x, y, r, w, h);
136
212
                }
137
213
                
138
 
                public static void DrawRoundRectangle (Cairo.Context cr, bool topLeftRound, bool topRightRound, bool bottomLeftRound, bool bottomRightRound,  double x, double y, double r, double w, double h)
 
214
                public static void DrawRoundRectangle (Cairo.Context cr, bool topLeftRound, bool topRightRound, bool bottomLeftRound, bool bottomRightRound, double x, double y, double r, double w, double h)
139
215
                {
140
216
                        //  UA****BQ
141
217
                        //  H      C
174
250
                        if (bottomLeftRound) {
175
251
                                cr.LineTo (x + r, y + h);                      // Line to F
176
252
                                cr.CurveTo (x, y + h, 
177
 
                                            x, y + h , 
 
253
                                            x, y + h, 
178
254
                                            x, y + h - r); // Curve to G
179
255
                        } else {
180
256
                                cr.LineTo (x, y + h); // Line to T
183
259
                        if (topLeftRound) {
184
260
                                cr.LineTo (x, y + r);              // Line to H
185
261
                                cr.CurveTo (x, y, 
186
 
                                            x , y, 
 
262
                                            x, y, 
187
263
                                            x + r, y); // Curve to A
188
264
                        } else {
189
265
                                cr.LineTo (x, y); // Line to U
194
270
                int GetFirstNonWsIdx (string text)
195
271
                {
196
272
                        for (int i = 0; i < text.Length; i++) {
197
 
                                if (!Char.IsWhiteSpace (text[i]))
 
273
                                if (!Char.IsWhiteSpace (text [i]))
198
274
                                        return i;
199
275
                        }
200
276
                        return 0;
201
277
                }
202
278
                
 
279
                #region IDisposable implementation
 
280
                void IDisposable.Dispose ()
 
281
                {
 
282
                        if (timeout != 0) {
 
283
                                GLib.Source.Remove (timeout);
 
284
                                timeout = 0;
 
285
                        }
 
286
                }
 
287
                #endregion
203
288
        }
204
289
}