~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/MessageBubbleHighlightPopupWindow.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
        public class MessageBubbleHighlightPopupWindow : BounceFadePopupWindow
37
37
        {
38
38
                MessageBubbleTextMarker marker;
 
39
                Gdk.Rectangle bounds;
39
40
                
40
41
                public MessageBubbleHighlightPopupWindow (SourceEditorView view, MessageBubbleTextMarker marker)
41
 
                        : base (view.TextEditor, marker.ErrorTextBounds)
 
42
                        : base (view.TextEditor)
42
43
                {
43
44
                        this.marker = marker;
44
45
                        
45
46
                        ExpandWidth = 36;
46
47
                        ExpandHeight = 2;
47
48
                        BounceEasing = Easing.Sine;
48
 
                        Duration = 600;
49
 
                }
50
 
                
51
 
                protected override Gdk.Pixbuf RenderInitialPixbuf (Gdk.Window parentwindow, Gdk.Rectangle bounds)
52
 
                {
53
 
                        //FIXME add a drop shadow on the pixmap, and expand the bounds to include this
54
 
                        using (Gdk.Pixmap pixmap = new Gdk.Pixmap (parentwindow, bounds.Width, bounds.Height)) {
55
 
                                using (var bgGc = new Gdk.GC(pixmap)) {
56
 
                                        bgGc.RgbFgColor = CairoExtensions.CairoColorToGdkColor (marker.colorMatrix[0, 0, 0, 0, 0]);
57
 
                                        pixmap.DrawRectangle (bgGc, true, 0, 0, bounds.Width, bounds.Height);
58
 
                                        pixmap.DrawLayout (marker.gc, 4, (bounds.Height - marker.Layouts[0].Height) / 2, marker.Layouts[0].Layout);
59
 
                                }
60
 
                                return Gdk.Pixbuf.FromDrawable (pixmap, Colormap, 0, 0, 0, 0, bounds.Width, bounds.Height);
61
 
                        }
62
 
                }
63
 
        }
64
 
}
65
 
 
66
 
/* doesn't work because of a cairo quartz bug cairo-font-face.c:191: failed assertion `CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count)'
67
 
 
68
 
// 
69
 
// MessageBubbleHighlightPopupWindow.cs
70
 
//  
71
 
// Author:
72
 
//       Mike KrĆ¼ger <mkrueger@novell.com>
73
 
// 
74
 
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
75
 
// 
76
 
// Permission is hereby granted, free of charge, to any person obtaining a copy
77
 
// of this software and associated documentation files (the "Software"), to deal
78
 
// in the Software without restriction, including without limitation the rights
79
 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
80
 
// copies of the Software, and to permit persons to whom the Software is
81
 
// furnished to do so, subject to the following conditions:
82
 
// 
83
 
// The above copyright notice and this permission notice shall be included in
84
 
// all copies or substantial portions of the Software.
85
 
// 
86
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
88
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
89
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
90
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
91
 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
92
 
// THE SOFTWARE.
93
 
using System;
94
 
using System.Linq;
95
 
using Gtk;
96
 
using MonoDevelop.Ide;
97
 
using MonoDevelop.Components;
98
 
using Mono.TextEditor;
99
 
using Mono.TextEditor.Theatrics;
100
 
using Cairo;
101
 
 
102
 
namespace MonoDevelop.SourceEditor
103
 
{
104
 
        public class MessageBubbleHighlightPopupWindow : Gtk.Window
105
 
        {
106
 
                MessageBubbleTextMarker marker;
107
 
                SourceEditorView view;
108
 
                
109
 
                public MessageBubbleHighlightPopupWindow (SourceEditorView view, MessageBubbleTextMarker marker)  : base (WindowType.Popup)
110
 
                {
111
 
                        this.view = view;
112
 
                        this.marker = marker;
113
 
                        this.Decorated = false;
114
 
                        this.BorderWidth = 0;
115
 
                        this.HasFrame = true;
116
 
                        this.TransientFor = (view.SourceEditorWidget.TextEditor.Toplevel as Gtk.Window) ?? IdeApp.Workbench.RootWindow;
117
 
                }
118
 
                
119
 
                Stage<MessageBubbleHighlightPopupWindow> stage = new Stage<MessageBubbleHighlightPopupWindow> ();
120
 
 
121
 
                public void Popup ()
122
 
                {
123
 
                        var rgbaColormap = Screen.RgbaColormap;
124
 
                        if (rgbaColormap == null)
125
 
                                return;
126
 
                        Colormap = rgbaColormap;
127
 
                        
128
 
                        Gdk.Rectangle currentBounds = marker.ErrorTextBounds;
129
 
                        int i = 12;
130
 
                        int j = 2;
131
 
                        int x, y;
132
 
                        view.SourceEditorWidget.TextEditor.GdkWindow.GetOrigin (out x, out y);
133
 
                        Move (x + currentBounds.X - i, y + currentBounds.Y - j);
134
 
                        Resize (currentBounds.Width + 2 * i, view.TextEditor.LineHeight + 2 * j);
135
 
                        
136
 
                        stage.ActorStep += OnAnimationActorStep;
137
 
                        stage.Iteration += OnAnimationIteration;
138
 
                        stage.UpdateFrequency = 10;
139
 
                        stage.Add (this, 250);
140
 
                        
141
 
                        Show ();
142
 
                }
143
 
                
144
 
                double Percent = 0.0;
145
 
                
146
 
                void OnAnimationIteration (object sender, EventArgs args)
147
 
                {
148
 
                        QueueDraw ();
149
 
                }
150
 
                
151
 
                bool isComing = true;
152
 
                bool isFading = false;
153
 
                
154
 
                bool OnAnimationActorStep (Actor<MessageBubbleHighlightPopupWindow> actor)
155
 
                {
156
 
                        if (isComing) {
157
 
                                Percent = actor.Percent;
158
 
                                if (actor.Expired) {
159
 
                                        isComing = false;
160
 
                                        isFading = true;
161
 
                                        actor.Reset ();
162
 
                                        return true;
163
 
                                }
164
 
                        } else if (isFading) {
165
 
                                Percent = 1.0 - actor.Percent;
166
 
                                if (actor.Expired) {
167
 
                                        isFading = false;
168
 
                                        actor.Reset ();
169
 
                                        return true;
170
 
                                }
171
 
                        } else {
172
 
                                Percent = 1.0 - actor.Percent;
173
 
                                if (actor.Expired) {
174
 
                                        Destroy ();
175
 
                                        return false;
176
 
                                }
177
 
                        }
178
 
                        return true;
179
 
                }
180
 
 
181
 
                protected override void OnDestroyed ()
182
 
                {
183
 
                        base.OnDestroyed ();
184
 
                        stage.Playing = false;
 
49
                        Duration = 150;
 
50
                }
 
51
        
 
52
                protected override Gdk.Rectangle CalculateInitialBounds ()
 
53
                {
 
54
                        int spaceX = marker.ErrorTextBounds.Width / 2;
 
55
                        
 
56
                        return new Gdk.Rectangle (marker.ErrorTextBounds.X - spaceX,
 
57
                                (int)(marker.ErrorTextBounds.Y - Editor.LineHeight),
 
58
                                marker.ErrorTextBounds.Width + spaceX * 2,
 
59
                                (int)(marker.ErrorTextBounds.Height + Editor.LineHeight * 2));
 
60
                }
 
61
                
 
62
                protected override void OnAnimationCompleted ()
 
63
                {
 
64
                        Destroy ();
185
65
                }
186
66
                
187
67
                protected override bool OnExposeEvent (Gdk.EventExpose evnt)
188
68
                {
189
 
                        using (var g = Gdk.CairoHelper.Create (evnt.Window)) {
190
 
                                g.SetSourceRGBA (1, 1, 1, 0);
191
 
                                g.Operator = Cairo.Operator.Source;
192
 
                                g.Paint ();
193
 
                                
194
 
                                int i = (int)(12.0 * Percent);
195
 
                                int j = (int)(2.0 * Percent);
196
 
                                if (!isFading && !isComing) {
197
 
                                        i = j = 0;
198
 
                                }
199
 
                                int x = 12 - i;
200
 
                                int y = 2 - j;
 
69
                        using (var cr = Gdk.CairoHelper.Create (evnt.Window)) {
 
70
                                cr.SetSourceRGBA (1, 1, 1, 0);
 
71
                                cr.Operator = Cairo.Operator.Source; 
 
72
                                cr.Paint ();
 
73
                        }
 
74
                        
 
75
                        using (var cr = Gdk.CairoHelper.Create (evnt.Window)) {
 
76
                                cr.Translate (width / 2, height / 2);
 
77
                                cr.Scale (1 + scale / 8, 1 + scale / 8);
 
78
                                int x = -(marker.ErrorTextBounds.Width) / 2;
 
79
                                int y = -marker.ErrorTextBounds.Height / 2;
201
80
                                
202
81
                                if (marker.FitsInSameLine) {
203
 
                                        g.MoveTo (x + view.TextEditor.LineHeight / 2, y);
204
 
                                        g.LineTo (x, Allocation.Height / 2);
205
 
                                        g.LineTo (x + view.TextEditor.LineHeight / 2, Allocation.Height - y);
206
 
                                } else {
207
 
                                        g.MoveTo (x, y);
208
 
                                        g.LineTo (x, Allocation.Height - y);
209
 
                                }
210
 
                                g.LineTo (Allocation.Width - x, Allocation.Height - y);
211
 
                                g.LineTo (Allocation.Width - x, y);
212
 
                                g.ClosePath ();
213
 
                                Mono.TextEditor.HslColor hsl = marker.colorMatrix[0, 0, 0, 0, 0];
214
 
                                double delta;
215
 
                                if (isComing) {
216
 
                                        delta = 1 + 2 - Percent; 
217
 
                                } else if (isFading) {
218
 
                                        delta = 1 + Percent; 
219
 
                                } else {
220
 
                                        delta = 1 - Percent; 
221
 
                                }
 
82
                                        cr.MoveTo (x + Editor.LineHeight / 2, y);
 
83
                                        cr.LineTo (x, 0);
 
84
                                        cr.LineTo (x + Editor.LineHeight / 2, marker.ErrorTextBounds.Height / 2);
 
85
                                } else {
 
86
                                        cr.MoveTo (x, -marker.ErrorTextBounds.Height / 2);
 
87
                                        cr.LineTo (x, marker.ErrorTextBounds.Height / 2);
 
88
                                }
 
89
                                cr.LineTo (x + marker.ErrorTextBounds.Width, marker.ErrorTextBounds.Height / 2);
 
90
                                cr.LineTo (x + marker.ErrorTextBounds.Width, y);
 
91
                                cr.ClosePath ();
 
92
                                
 
93
                                Mono.TextEditor.HslColor hsl = marker.colorMatrix [0, 0, 0, 0, 0];
 
94
                                double delta = 1 + 2 - scale;
222
95
                                hsl.S += delta;
223
 
                                g.Color = hsl;
224
 
                                g.FillPreserve ();
225
 
                                g.Color = marker.colorMatrix [0, 0, 2, 0, 0];
226
 
                                g.Stroke ();
 
96
                                var color = (Cairo.Color)hsl;
 
97
                                color.A = opacity;
 
98
                                cr.Color = color;
 
99
                                cr.FillPreserve ();
 
100
                                color = marker.colorMatrix [0, 0, 2, 0, 0];
 
101
                                color.A = opacity;
 
102
                                cr.Color = color;
 
103
                                cr.Stroke ();
 
104
                                int errorCounterWidth = 0;
227
105
                                
228
106
                                if (marker.Errors.Count > 1) {
229
 
                                        int rY = y + view.TextEditor.LineHeight / 6;
 
107
                                        double rY = y + Editor.LineHeight / 6;
230
108
                                        int ew, eh;
231
109
                                        marker.errorCountLayout.GetPixelSize (out ew, out eh);
232
 
                                        int errorCounterWidth = ew + 10;
233
 
                                        int rX = Allocation.Width - errorCounterWidth - 2 - x;
 
110
                                        errorCounterWidth = ew + 10;
 
111
                                        int rX = x + marker.ErrorTextBounds.Width - errorCounterWidth;
234
112
 
235
113
                                        int rW = errorCounterWidth - 2;
236
 
                                        int rH = view.TextEditor.LineHeight * 3 / 4;
237
 
                                        
238
 
                                        BookmarkMarker.DrawRoundRectangle (g, rX, rY, 8, rW, rH);
239
 
                                        g.Color = new Cairo.Color (0.5, 0.5, 0.5);
240
 
                                        g.Fill ();
241
 
                                        
242
 
                                        if (marker.CollapseExtendedErrors) {
243
 
                                                // TODO !!!
 
114
                                        double rH = Editor.LineHeight * 3 / 4;
 
115
                                        
 
116
                                        BookmarkMarker.DrawRoundRectangle (cr, rX, rY, 8, rW, rH);
 
117
                                        cr.Color = new Cairo.Color (0.5, 0.5, 0.5);
 
118
                                        cr.Fill ();
 
119
                                        
 
120
                                        cr.MoveTo (rX + rW / 2 - rW / 4, rY + rH - rH / 4);
 
121
                                        cr.LineTo (rX + rW / 2 + rW / 4, rY + rH - rH / 4);
 
122
                                        cr.LineTo (rX + rW / 2, rY + rH / 4);
 
123
                                        cr.ClosePath ();
 
124
                                        
 
125
                                        cr.Color = new Cairo.Color (1, 1, 1);
 
126
                                        cr.Fill ();
 
127
                                }
 
128
                                
 
129
                                cr.Color = new Cairo.Color (0, 0, 0);
 
130
                                marker.EnsureLayoutCreated (base.Editor);
 
131
                                
 
132
                                int layoutWidth, layoutHeight;
 
133
                                marker.Layouts [0].Layout.GetPixelSize (out layoutWidth, out layoutHeight);
 
134
                                double ly;
 
135
                                if (marker.CollapseExtendedErrors || marker.Errors.Count == 1) {
 
136
                                        ly = 1 + y + (marker.ErrorTextBounds.Height - layoutHeight) / 2;
 
137
                                        double x2 = x + MessageBubbleTextMarker.border;
 
138
                                        if (marker.FitsInSameLine)
 
139
                                                x2 += 1 + Editor.LineHeight / 2;
 
140
                                        cr.Translate (x2, ly);
 
141
                                        cr.ShowLayout (marker.Layouts [0].Layout);
 
142
                                
 
143
                                } else {
 
144
                                        ly = 1 + y + (Editor.LineHeight - layoutHeight) / 2;
 
145
                                        for (int i = 0; i < marker.Errors.Count; i++) {
 
146
                                                marker.Layouts [i].Layout.GetPixelSize (out layoutWidth, out layoutHeight);
 
147
                                                cr.Save ();
 
148
                                                double x2;
 
149
                                                if (i == 0) {
 
150
                                                        x2 = x + marker.ErrorTextBounds.Width - layoutWidth - errorCounterWidth;
 
151
                                                } else {
 
152
                                                        x2 = x + MessageBubbleTextMarker.border;
 
153
                                                }
 
154
                                                if (marker.FitsInSameLine)
 
155
                                                        x2 += Editor.LineHeight / 2;
 
156
                                                cr.Translate (x2, ly);
 
157
                                                cr.ShowLayout (marker.Layouts [i].Layout);
 
158
                                                cr.Restore ();
 
159
                                                ly += Editor.LineHeight;
244
160
                                        }
245
 
                                        g.MoveTo (rX + rW / 2 - rW / 4, rY + rH - rH / 4);
246
 
                                        g.LineTo (rX + rW / 2 + rW / 4, rY + rH - rH / 4);
247
 
                                        g.LineTo (rX + rW / 2 , rY + rH / 4);
248
 
                                        g.ClosePath ();
249
 
                                        
250
 
                                        g.Color = new Cairo.Color (1, 1, 1);
251
 
                                        g.Fill ();
252
161
                                }
253
162
                                
254
 
                                g.SelectFontFace ("Sans", FontSlant.Normal, FontWeight.Normal);
255
 
                                g.SetFontSize (marker.Layouts[0].Layout.FontDescription.Size / Pango.Scale.PangoScale + j);
256
 
                                string typeString = "error";
257
 
                                g.Color = Mono.TextEditor.Highlighting.Style.ToCairoColor (view.TextEditor.ColorStyle.GetChunkStyle ("bubble." + typeString + ".text").Color);
258
 
                                var extends = g.TextExtents (marker.Errors[0].ErrorMessage);
259
 
                                g.MoveTo (x + 0.5 - extends.XBearing + MessageBubbleTextMarker.border + (marker.FitsInSameLine ? view.TextEditor.LineHeight / 2 : 0), (Allocation.Height - extends.Height) / 2 - extends.YBearing - 0.5);
260
 
                                g.ShowText (marker.Errors[0].ErrorMessage);
261
 
                                g.ContextFontFace.Dispose ();
 
163
                                
262
164
                        }
263
165
                        return false;
264
166
                }
265
167
        }
266
168
}
267
 
 
268
 
*/
269