114
void HandleRealized (object sender, EventArgs e)
116
editor.Realized -= HandleRealized;
120
Gtk.Adjustment vAdjustment;
121
Gtk.Adjustment hAdjustment;
110
122
protected void ListenToEvents ()
112
editor.VAdjustment.ValueChanged += HandleEditorVAdjustmentValueChanged;
113
editor.HAdjustment.ValueChanged += HandleEditorHAdjustmentValueChanged;
114
vValue = editor.VAdjustment.Value;
115
hValue = editor.HAdjustment.Value;
124
if (vAdjustment == null) {
125
vAdjustment = editor.VAdjustment;
126
hAdjustment = editor.HAdjustment;
128
vAdjustment.ValueChanged += HandleEditorVAdjustmentValueChanged;
129
hAdjustment.ValueChanged += HandleEditorHAdjustmentValueChanged;
131
vValue = vAdjustment.Value;
132
hValue = hAdjustment.Value;
118
135
protected override void OnShown ()
224
/// Tooltip that "bounces", then fades away.
226
public abstract class BounceFadePopupWidget : Gtk.Widget
228
Stage<BounceFadePopupWidget> stage = new Stage<BounceFadePopupWidget> ();
229
Gdk.Pixbuf textImage = null;
232
protected double scale = 0.0;
233
protected double opacity = 1.0;
235
public BounceFadePopupWidget (TextEditor editor)
238
throw new InvalidOperationException ("Only works with composited screen. Check Widget.IsComposited.");
240
throw new ArgumentNullException ("Editor");
241
WidgetFlags |= Gtk.WidgetFlags.NoWindow;
242
this.editor = editor;
243
Events = EventMask.ExposureMask;
247
BounceEasing = Easing.Sine;
249
var rgbaColormap = Screen.RgbaColormap;
250
if (rgbaColormap == null)
252
Colormap = rgbaColormap;
254
stage.ActorStep += OnAnimationActorStep;
255
stage.Iteration += OnAnimationIteration;
256
stage.UpdateFrequency = 10;
259
protected TextEditor Editor { get { return editor; } }
261
/// <summary>Duration of the animation, in milliseconds.</summary>
262
public uint Duration { get; set; }
264
/// <summary>The number of pixels by which the window's width will expand</summary>
265
public uint ExpandWidth { get; set; }
267
/// <summary>The number of pixels by which the window's height will expand</summary>
268
public uint ExpandHeight { get; set; }
270
/// <summary>The easing used for the bounce part of the animation.</summary>
271
public Easing BounceEasing { get; set; }
273
int xExpandedOffset, yExpandedOffset;
274
Cairo.Rectangle userspaceArea;
275
Cairo.Rectangle bounds;
277
public virtual void Popup ()
279
if (editor.GdkWindow == null){
280
editor.Realized += HandleRealized;
284
bounds = CalculateInitialBounds ();
286
//GTK uses integer position coords, so round fractions down, we'll add them back later as draw offsets
287
int x = (int) System.Math.Floor (bounds.X);
288
int y = (int) System.Math.Floor (bounds.Y);
290
//capture any lost fractions to pass as an offset to Draw
291
userspaceArea = new Cairo.Rectangle (bounds.X - x, bounds.Y - y, bounds.Width, bounds.Height);
293
//lose half-pixels on the expansion, it's not a big deal
294
xExpandedOffset = (int) (System.Math.Floor (ExpandWidth / 2d));
295
yExpandedOffset = (int) (System.Math.Floor (ExpandHeight / 2d));
297
//round the width/height up to make sure we have room for restored fractions
298
int width = System.Math.Max (1, (int) (System.Math.Ceiling (bounds.Width) + ExpandWidth));
299
int height = System.Math.Max (1, (int) (System.Math.Ceiling (bounds.Height) + ExpandHeight));
300
this.SetSizeRequest (width, height);
301
editor.TextArea.AddTopLevelWidget (this, x - xExpandedOffset, y - yExpandedOffset);
303
stage.AddOrReset (this, Duration);
308
void HandleRealized (object sender, EventArgs e)
310
editor.Realized -= HandleRealized;
314
void OnAnimationIteration (object sender, EventArgs args)
319
protected virtual bool OnAnimationActorStep (Actor<BounceFadePopupWidget> actor)
322
OnAnimationCompleted ();
326
// for the first half, use an easing
327
if (actor.Percent < 0.5) {
328
scale = Choreographer.Compose (actor.Percent * 2, BounceEasing);
331
//for the second half, vary opacity linearly from 1 to 0.
333
scale = Choreographer.Compose (1.0, BounceEasing);
334
opacity = 1 - 2 * (actor.Percent - 0.5);
339
protected override bool OnExposeEvent (EventExpose evnt)
342
var alloc = Allocation;
343
using (var cr = CairoHelper.Create (evnt.Window)) {
344
cr.Translate (alloc.X, alloc.Y);
345
cr.Translate (xExpandedOffset * (1 - scale), yExpandedOffset * (1 - scale));
346
var scaleX = (alloc.Width / userspaceArea.Width - 1) * scale + 1;
347
var scaleY = (alloc.Height / userspaceArea.Height - 1) * scale + 1;
348
cr.Scale (scaleX, scaleY);
349
Draw (cr, userspaceArea);
351
} catch (Exception e) {
352
Console.WriteLine ("Exception in animation:" + e);
357
protected abstract void Draw (Cairo.Context context, Cairo.Rectangle area);
359
protected virtual void OnAnimationCompleted ()
364
protected override void OnDestroyed ()
370
internal virtual void StopPlaying ()
372
stage.Playing = false;
374
if (textImage != null) {
375
textImage.Dispose ();
380
protected abstract Cairo.Rectangle CalculateInitialBounds ();