36
36
public class MessageBubbleHighlightPopupWindow : BounceFadePopupWindow
38
38
MessageBubbleTextMarker marker;
40
41
public MessageBubbleHighlightPopupWindow (SourceEditorView view, MessageBubbleTextMarker marker)
41
: base (view.TextEditor, marker.ErrorTextBounds)
42
: base (view.TextEditor)
43
44
this.marker = marker;
47
48
BounceEasing = Easing.Sine;
51
protected override Gdk.Pixbuf RenderInitialPixbuf (Gdk.Window parentwindow, Gdk.Rectangle bounds)
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);
60
return Gdk.Pixbuf.FromDrawable (pixmap, Colormap, 0, 0, 0, 0, bounds.Width, bounds.Height);
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)'
69
// MessageBubbleHighlightPopupWindow.cs
72
// Mike KrĆ¼ger <mkrueger@novell.com>
74
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
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:
83
// The above copyright notice and this permission notice shall be included in
84
// all copies or substantial portions of the Software.
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
96
using MonoDevelop.Ide;
97
using MonoDevelop.Components;
98
using Mono.TextEditor;
99
using Mono.TextEditor.Theatrics;
102
namespace MonoDevelop.SourceEditor
104
public class MessageBubbleHighlightPopupWindow : Gtk.Window
106
MessageBubbleTextMarker marker;
107
SourceEditorView view;
109
public MessageBubbleHighlightPopupWindow (SourceEditorView view, MessageBubbleTextMarker marker) : base (WindowType.Popup)
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;
119
Stage<MessageBubbleHighlightPopupWindow> stage = new Stage<MessageBubbleHighlightPopupWindow> ();
123
var rgbaColormap = Screen.RgbaColormap;
124
if (rgbaColormap == null)
126
Colormap = rgbaColormap;
128
Gdk.Rectangle currentBounds = marker.ErrorTextBounds;
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);
136
stage.ActorStep += OnAnimationActorStep;
137
stage.Iteration += OnAnimationIteration;
138
stage.UpdateFrequency = 10;
139
stage.Add (this, 250);
144
double Percent = 0.0;
146
void OnAnimationIteration (object sender, EventArgs args)
151
bool isComing = true;
152
bool isFading = false;
154
bool OnAnimationActorStep (Actor<MessageBubbleHighlightPopupWindow> actor)
157
Percent = actor.Percent;
164
} else if (isFading) {
165
Percent = 1.0 - actor.Percent;
172
Percent = 1.0 - actor.Percent;
181
protected override void OnDestroyed ()
184
stage.Playing = false;
52
protected override Gdk.Rectangle CalculateInitialBounds ()
54
int spaceX = marker.ErrorTextBounds.Width / 2;
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));
62
protected override void OnAnimationCompleted ()
187
67
protected override bool OnExposeEvent (Gdk.EventExpose evnt)
189
using (var g = Gdk.CairoHelper.Create (evnt.Window)) {
190
g.SetSourceRGBA (1, 1, 1, 0);
191
g.Operator = Cairo.Operator.Source;
194
int i = (int)(12.0 * Percent);
195
int j = (int)(2.0 * Percent);
196
if (!isFading && !isComing) {
69
using (var cr = Gdk.CairoHelper.Create (evnt.Window)) {
70
cr.SetSourceRGBA (1, 1, 1, 0);
71
cr.Operator = Cairo.Operator.Source;
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;
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);
208
g.LineTo (x, Allocation.Height - y);
210
g.LineTo (Allocation.Width - x, Allocation.Height - y);
211
g.LineTo (Allocation.Width - x, y);
213
Mono.TextEditor.HslColor hsl = marker.colorMatrix[0, 0, 0, 0, 0];
216
delta = 1 + 2 - Percent;
217
} else if (isFading) {
82
cr.MoveTo (x + Editor.LineHeight / 2, y);
84
cr.LineTo (x + Editor.LineHeight / 2, marker.ErrorTextBounds.Height / 2);
86
cr.MoveTo (x, -marker.ErrorTextBounds.Height / 2);
87
cr.LineTo (x, marker.ErrorTextBounds.Height / 2);
89
cr.LineTo (x + marker.ErrorTextBounds.Width, marker.ErrorTextBounds.Height / 2);
90
cr.LineTo (x + marker.ErrorTextBounds.Width, y);
93
Mono.TextEditor.HslColor hsl = marker.colorMatrix [0, 0, 0, 0, 0];
94
double delta = 1 + 2 - scale;
225
g.Color = marker.colorMatrix [0, 0, 2, 0, 0];
96
var color = (Cairo.Color)hsl;
100
color = marker.colorMatrix [0, 0, 2, 0, 0];
104
int errorCounterWidth = 0;
228
106
if (marker.Errors.Count > 1) {
229
int rY = y + view.TextEditor.LineHeight / 6;
107
double rY = y + Editor.LineHeight / 6;
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;
235
113
int rW = errorCounterWidth - 2;
236
int rH = view.TextEditor.LineHeight * 3 / 4;
238
BookmarkMarker.DrawRoundRectangle (g, rX, rY, 8, rW, rH);
239
g.Color = new Cairo.Color (0.5, 0.5, 0.5);
242
if (marker.CollapseExtendedErrors) {
114
double rH = Editor.LineHeight * 3 / 4;
116
BookmarkMarker.DrawRoundRectangle (cr, rX, rY, 8, rW, rH);
117
cr.Color = new Cairo.Color (0.5, 0.5, 0.5);
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);
125
cr.Color = new Cairo.Color (1, 1, 1);
129
cr.Color = new Cairo.Color (0, 0, 0);
130
marker.EnsureLayoutCreated (base.Editor);
132
int layoutWidth, layoutHeight;
133
marker.Layouts [0].Layout.GetPixelSize (out layoutWidth, out layoutHeight);
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);
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);
150
x2 = x + marker.ErrorTextBounds.Width - layoutWidth - errorCounterWidth;
152
x2 = x + MessageBubbleTextMarker.border;
154
if (marker.FitsInSameLine)
155
x2 += Editor.LineHeight / 2;
156
cr.Translate (x2, ly);
157
cr.ShowLayout (marker.Layouts [i].Layout);
159
ly += Editor.LineHeight;
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);
250
g.Color = new Cairo.Color (1, 1, 1);
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 ();