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 168 169 170 171 172 173 174 175 176
|
# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
# This program is licenced under the same licence as Ruby-GNOME2.
#
# $Id: pixbufs.rb,v 1.5 2005/02/12 23:02:43 kzys Exp $
=begin
= Pixbufs
A Gdk::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 Gtk::DrawingArea to do a simple animation.
Look at the Image demo for additional pixbuf usage examples.
=end
require 'common'
module Demo
class Pixbufs < BasicWindow
FRAME_DELAY = 50
BACKGROUND_NAME = 'background.jpg'
IMAGE_NAMES = [
'apple-red.png',
'gnome-applets.png',
'gnome-calendar.png',
'gnome-foot.png',
'gnome-gmush.png',
'gnome-gimp.png',
'gnome-gsame.png',
'gnu-keys.png',
'ruby-gnome2-logo.png'
]
CYCLE_LEN = 60
def initialize
super('Pixbufs')
set_resizable(false)
@background = nil
@frame = nil
@frame_num = 0
@images = []
begin
load_pixbufs
set_size_request(@background.width, @background.height)
@frame = Gdk::Pixbuf.new(Gdk::Pixbuf::COLORSPACE_RGB,
false, 8,
@background.width, @background.height)
@da = Gtk::DrawingArea.new
@da.signal_connect('expose_event') do |w, e|
expose_cb(w, e)
end
add(@da)
timeout_id = Gtk.timeout_add(FRAME_DELAY) do
timeout
end
signal_connect('destroy') do
Gtk.timeout_remove(timeout_id)
end
rescue
dialog = Gtk::MessageDialog.new(self,
Gtk::Dialog::DESTROY_WITH_PARENT,
Gtk::MessageDialog::ERROR,
Gtk::MessageDialog::BUTTONS_CLOSE,
"Failed to load an image: #{$!.message}")
dialog.signal_connect('response') do
dialog.destroy
end
dialog.show
end
end
def load_pixbufs
# Loads the images for the demo
if @background
return # already loaded earlier
end
# demo_find_file() looks in the the current directory first,
# so you can run gtk-demo without installing GTK, then looks
# in the location where the file is installed.
#
filename = Demo.find_file(BACKGROUND_NAME)
@background = Gdk::Pixbuf.new(filename)
IMAGE_NAMES.each_with_index do |basename, i|
filename = Demo.find_file(basename)
@images[i] = Gdk::Pixbuf.new(filename)
end
end
def expose_cb(widget, event)
rowstride = @frame.rowstride
pixels = @frame.pixels
pixels[0, rowstride * event.area.y + event.area.x * 3] = ''
Gdk::RGB.draw_rgb_image(widget.window,
widget.style.black_gc,
event.area.x, event.area.y,
event.area.width, event.area.height,
Gdk::RGB::Dither::NORMAL,
pixels, rowstride,
event.area.x, event.area.y)
true
end
# Timeout handler to regenerate the frame
def timeout
@background.copy_area(0, 0, @background.width, @background.height,
@frame, 0, 0)
f = Float(@frame_num % CYCLE_LEN) / CYCLE_LEN;
xmid = @background.width / 2.0
ymid = @background.height / 2.0
radius = [xmid, ymid].min / 2.0
@images.each_with_index do |image, i|
ang = 2.0 * Math::PI * Float(i) / IMAGE_NAMES.length - f * 2.0 * Math::PI
r = radius + (radius / 3.0) * Math.sin(f * 2.0 * Math::PI)
xpos = (xmid + r * Math.cos(ang) - image.width / 2.0 + 0.5).floor
ypos = (ymid + r * Math.sin(ang) - image.height / 2.0 + 0.5).floor
k = if (i & 1) == 1
Math.sin(f * 2.0 * Math::PI)
else
Math.cos(f * 2.0 * Math::PI)
end
k = [0.25, 2.0 * k * k].max
r1 = Gdk::Rectangle.new(xpos, ypos, image.width * k, image.height * k)
r2 = Gdk::Rectangle.new(0, 0, @background.width, @background.height)
dest = r1.intersect(r2)
if dest
@frame.composite!(image, dest.x, dest.y, dest.width, dest.height,
xpos, ypos, k, k, Gdk::Pixbuf::INTERP_NEAREST,
if (i & 1) == 1
[
127,
(255 * Math.sin(f * 2.0 * Math::PI)).abs
].max
else
[
127,
(255 * Math.cos(f * 2.0 * Math::PI)).abs
].max
end)
end
end
@da.queue_draw
@frame_num += 1
true
end
end
end
|