1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
/* 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;
}
}
}
|