/* * Dissolve.cs * * Copyright 2007 Novell Inc. * * Author * Larry Ewing * * See COPYING for license information. * */ using System; using Cairo; using Gtk; namespace FSpot.Widgets { public class Dissolve : ITransition { DateTime start; TimeSpan duration = new TimeSpan (0, 0, 1); ImageInfo begin; ImageInfo end; ImageInfo begin_buffer; ImageInfo end_buffer; int frames = 0; public Dissolve (ImageInfo begin, ImageInfo end) { this.begin = begin; this.end = end; } public int Frames { get { return frames; } } public bool OnEvent (Widget w) { if (begin_buffer == null) { begin_buffer = new ImageInfo (begin, w); //.Allocation); } if (end_buffer == null) { end_buffer = new ImageInfo (end, w); //.Allocation); } w.QueueDraw (); w.GdkWindow.ProcessUpdates (false); TimeSpan elapsed = DateTime.UtcNow - start; double fraction = elapsed.Ticks / (double) duration.Ticks; return fraction < 1.0; } public bool OnExpose (Context ctx, Gdk.Rectangle allocation) { if (frames == 0) start = DateTime.UtcNow; frames ++; TimeSpan elapsed = DateTime.UtcNow - start; double fraction = elapsed.Ticks / (double) duration.Ticks; double opacity = Math.Sin (Math.Min (fraction, 1.0) * Math.PI * 0.5); ctx.Operator = Operator.Source; SurfacePattern p = new SurfacePattern (begin_buffer.Surface); ctx.Matrix = begin_buffer.Fill (allocation); p.Filter = Filter.Fast; ctx.Source = p; ctx.Paint (); ctx.Operator = Operator.Over; ctx.Matrix = end_buffer.Fill (allocation); SurfacePattern sur = new SurfacePattern (end_buffer.Surface); Pattern black = new SolidPattern (new Cairo.Color (0.0, 0.0, 0.0, opacity)); //ctx.Source = black; //ctx.Fill (); sur.Filter = Filter.Fast; ctx.Source = sur; ctx.Mask (black); //ctx.Paint (); ctx.Matrix = new Matrix (); ctx.MoveTo (allocation.Width / 2.0, allocation.Height / 2.0); ctx.Source = new SolidPattern (1.0, 0, 0); #if debug ctx.ShowText (String.Format ("{0} {1} {2} {3} {4} {5} {6} {7}", frames, sur.Status, p.Status, opacity, fraction, elapsed, start, DateTime.UtcNow)); #endif sur.Destroy (); p.Destroy (); return fraction < 1.0; } public void Dispose () { if (begin_buffer != null) { begin_buffer.Dispose (); begin_buffer = null; } if (end_buffer != null) { end_buffer.Dispose (); end_buffer = null; } } } }