198 lines
5.4 KiB
Ruby
198 lines
5.4 KiB
Ruby
|
# 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(256)
|
||
|
|
||
|
@pixbuf_loader.write(buf)
|
||
|
|
||
|
if @image_stream.eof?
|
||
|
@image_stream.close
|
||
|
@image_stream = nil
|
||
|
|
||
|
@pixbuf_loader.close
|
||
|
@pixbuf_loader = nil
|
||
|
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
|
||
|
@pixbuf_loader.close if @pixbuf_loader
|
||
|
@pixbuf_loader = nil
|
||
|
if @load_timeout != 0
|
||
|
Gtk.timeout_remove(@load_timeout)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|