File: images.rb

package info (click to toggle)
ruby-gnome2 0.15.0-1.1etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 7,704 kB
  • ctags: 8,558
  • sloc: ansic: 69,912; ruby: 19,511; makefile: 97; xml: 35; sql: 13
file content (197 lines) | stat: -rw-r--r-- 5,461 bytes parent folder | download | duplicates (2)
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