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 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
# Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
# This program is licenced under the same licence as Ruby-GNOME2.
#
# $Id: images.rb,v 1.5 2006/04/08 12:30:03 mutoh Exp $
=begin
= Images
Gtk::Image is used to display an image; the image can be in a number of formats.
Typically, you load an image into a Gdk::Pixbuf, then display the pixbuf.
This demo code shows some of the more obscure cases, in the simple
case a call to Gtk::Image.new is all you need.
If you want to put image data in your program as a String variable,
use the make-inline-pixbuf program that comes with GTK+.
This way you won't need to depend on loading external files, your
application binary can be self-contained.
=end
require 'common'
module Demo
class Images < BasicWindow
def initialize
@pixbuf_loader = nil
@load_timeout = 0
@image_stream = nil
super('Images')
signal_connect('destroy') do
cleanup_callback
end
self.border_width = 8
vbox = Gtk::VBox.new(false, 8)
vbox.border_width = 8
add(vbox)
label = Gtk::Label.new
label.set_markup('<u>Image loaded from a file</u>')
vbox.pack_start(label, false, false, 0)
frame = Gtk::Frame.new
frame.shadow_type = Gtk::SHADOW_IN
# The alignment keeps the frame from growing when users resize
# the window
align = Gtk::Alignment.new(0.5, 0.5, 0, 0)
align.add(frame)
vbox.pack_start(align, false, false, 0)
# 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.
pixbuf = nil
begin
filename = Demo.find_file('gtk-logo-rgb.gif')
pixbuf = Gdk::Pixbuf.new(filename)
rescue
# This code shows off error handling. You can just use
# Gtk::Image.new instead if you don't want to report
# errors to the user. If the file doesn't load when using
# Gtk::Image.new, a 'missing image' icon will
# be displayed instead.
dialog = Gtk::MessageDialog.new(self,
Gtk::Dialog::DESTROY_WITH_PARENT,
Gtk::MessageDialog::ERROR,
Gtk::MessageDialog::BUTTONS_CLOSE,
"Unable to open image file 'gtk-logo-rgb.gif': #{$1}")
dialog.signal_connect('response') do |widget, data|
widget.destroy
end
dialog.show
end
image = Gtk::Image.new(pixbuf)
frame.add(image)
# Animation
label = Gtk::Label.new
label.set_markup('<u>Animation loaded from a file</u>')
vbox.pack_start(label, false, false, 0)
frame = Gtk::Frame.new
frame.shadow_type = Gtk::SHADOW_IN
# The alignment keeps the frame from growing when users resize
# the window
align = Gtk::Alignment.new(0.5, 0.5, 0, 0)
align.add(frame)
vbox.pack_start(align, false, false, 0)
filename = Demo.find_file('floppybuddy.gif')
image = Gtk::Image.new(filename)
frame.add(image)
# Progressive
label = Gtk::Label.new
label.set_markup('<u>Progressive image loading</u>')
vbox.pack_start(label, false, false, 0)
frame = Gtk::Frame.new(nil)
frame.shadow_type = Gtk::SHADOW_IN
# The alignment keeps the frame from growing when users resize
# the window
align = Gtk::Alignment.new(0.5, 0.5, 0, 0)
align.add(frame)
vbox.pack_start(align, false, false, 0)
# Create an empty image for now; the progressive loader
# will create the pixbuf and fill it in.
image = Gtk::Image.new
frame.add(image)
start_progressive_loading(image)
# Sensitivity control
button = Gtk::ToggleButton.new('_Insensitive', true)
vbox.pack_start(button, false, false, 0)
button.signal_connect('toggled') do |widget|
vbox.children.each do |widget|
if widget != button
widget.sensitive = ! button.active?
end
end
end
end
def start_progressive_loading(image)
@load_timeout = Gtk.timeout_add(150) do
progressive_timeout(image)
end
end
def progressive_timeout(image)
if @image_stream
buf = @image_stream.read(1024)
@pixbuf_loader.write(buf)
if @image_stream.eof?
@image_stream.close
@image_stream = nil
@pixbuf_loader.close
@pixbuf_loader = nil
return false
end
else
filename = Demo.find_file('alphatest.png')
@image_stream = File.open(filename, 'rb')
if @pixbuf_loader != nil
@pixbuf_loader.close
@pixbuf_loader = nil
end
@pixbuf_loader = Gdk::PixbufLoader.new
@pixbuf_loader.signal_connect('area_prepared') do |loader|
pixbuf = loader.pixbuf
# Avoid displaying random memory contents, since the pixbuf
# isn't filled in yet.
pixbuf.fill!(0xaaaaaaff)
image.pixbuf = pixbuf
end
@pixbuf_loader.signal_connect('area_updated') do
# We know the pixbuf inside the Gtk::Image has changed, but the image
# itself doesn't know this; so queue a redraw. If we wanted to be
# really efficient, we could use a drawing area or something
# instead of a Gtk::Image, so we could control the exact position of
# the pixbuf on the display, then we could queue a draw for only
# the updated area of the image.
image.queue_draw
end
end
# leave timeout installed
return true
end
def cleanup_callback
if @load_timeout != 0
Gtk.timeout_remove(@load_timeout)
end
end
end
end
|