GtkSharp/sample/GtkDemo/DemoPixbuf.cs
Bertrand Lorentz 3a2f01c534 sample: Port all existing GtkDemo samples to the new APIs
The following samples crash because of an issue with the new Drawn
handler: ColorSelection, DrawingArea and Pixbuf.
The rest seem to work OK.
2011-06-18 19:21:21 +02:00

167 lines
3.8 KiB
C#

/* Pixbufs
*
* A Pixbuf represents an image, normally in RGB or RGBA format.
* Pixbufs are normally used to load files from disk and perform
* image scaling.
*
* This demo is not all that educational, but looks cool. It was written
* by Extreme Pixbuf Hacker Federico Mena Quintero. It also shows
* off how to use DrawingArea to do a simple animation.
*
* Look at the Image demo for additional pixbuf usage examples.
*
*/
using Gdk;
using Gtk;
using System;
using System.Runtime.InteropServices; // for Marshal.Copy
namespace GtkDemo
{
[Demo ("Pixbuf", "DemoPixbuf.cs")]
public class DemoPixbuf : Gtk.Window
{
const int FrameDelay = 50;
const int CycleLen = 60;
const string BackgroundName = "background.jpg";
static string[] ImageNames = {
"apple-red.png",
"gnome-applets.png",
"gnome-calendar.png",
"gnome-foot.png",
"gnome-gmush.png",
"gnome-gimp.png",
"gnome-gsame.png",
"gnu-keys.png"
};
// background image
static Pixbuf background;
static int backWidth, backHeight;
// images
static Pixbuf[] images;
// current frame
Pixbuf frame;
int frameNum;
// drawing area
DrawingArea drawingArea;
uint timeoutId;
static DemoPixbuf ()
{
// Load the images for the demo
background = Gdk.Pixbuf.LoadFromResource (BackgroundName);
backWidth = background.Width;
backHeight = background.Height;
images = new Pixbuf[ImageNames.Length];
int i = 0;
foreach (string im in ImageNames)
images[i++] = Gdk.Pixbuf.LoadFromResource (im);
}
// Expose callback for the drawing area
void DrawnCallback (object o, DrawnArgs args)
{
Cairo.Context cr = args.Cr;
Gdk.CairoHelper.SetSourcePixbuf (cr, frame, 0, 0);
cr.Paint ();
args.RetVal = true;
}
// timeout handler to regenerate the frame
bool timeout ()
{
background.CopyArea (0, 0, backWidth, backHeight, frame, 0, 0);
double f = (double) (frameNum % CycleLen) / CycleLen;
int xmid = backWidth / 2;
int ymid = backHeight / 2;
double radius = Math.Min (xmid, ymid) / 2;
for (int i = 0; i < images.Length; i++) {
double ang = 2 * Math.PI * (double) i / images.Length - f * 2 * Math.PI;
int iw = images[i].Width;
int ih = images[i].Height;
double r = radius + (radius / 3) * Math.Sin (f * 2 * Math.PI);
int xpos = (int) Math.Floor (xmid + r * Math.Cos (ang) -
iw / 2.0 + 0.5);
int ypos = (int) Math.Floor (ymid + r * Math.Sin (ang) -
ih / 2.0 + 0.5);
double k = (i % 2 == 1) ? Math.Sin (f * 2 * Math.PI) :
Math.Cos (f * 2 * Math.PI);
k = 2 * k * k;
k = Math.Max (0.25, k);
Rectangle r1, r2, dest;
r1 = new Rectangle (xpos, ypos, (int) (iw * k), (int) (ih * k));
r2 = new Rectangle (0, 0, backWidth, backHeight);
dest = Rectangle.Intersect (r1, r2);
if (!dest.IsEmpty) {
images[i].Composite (frame, dest.X, dest.Y,
dest.Width, dest.Height,
xpos, ypos, k, k,
InterpType.Nearest,
(int) ((i % 2 == 1) ?
Math.Max (127, Math.Abs (255 * Math.Sin (f * 2 * Math.PI))) :
Math.Max (127, Math.Abs (255 * Math.Cos (f * 2 * Math.PI)))));
}
}
drawingArea.QueueDraw ();
frameNum++;
return true;
}
public DemoPixbuf () : base ("Pixbufs")
{
Resizable = false;
SetSizeRequest (backWidth, backHeight);
frame = new Pixbuf (Colorspace.Rgb, false, 8, backWidth, backHeight);
drawingArea = new DrawingArea ();
drawingArea.Drawn += new DrawnHandler (DrawnCallback);
Add (drawingArea);
timeoutId = GLib.Timeout.Add (FrameDelay, new GLib.TimeoutHandler(timeout));
ShowAll ();
}
protected override void OnDestroyed ()
{
if (timeoutId != 0) {
GLib.Source.Remove (timeoutId);
timeoutId = 0;
}
}
protected override bool OnDeleteEvent (Gdk.Event evt)
{
Destroy ();
return true;
}
}
}