1 #
2 # tk/image.rb : treat Tk image objects
3 #
4
5 require 'tk'
6
7 class TkImage<TkObject
8 include Tk
9
10 TkCommandNames = ['image'.freeze].freeze
11
12 Tk_IMGTBL = TkCore::INTERP.create_table
13
14 (Tk_Image_ID = ['i'.freeze, '00000'.taint]).instance_eval{
15 @mutex = Mutex.new
16 def mutex; @mutex; end
17 freeze
18 }
19
20 TkCore::INTERP.init_ip_env{
21 Tk_IMGTBL.mutex.synchronize{ Tk_IMGTBL.clear }
22 }
23
24 def self.new(keys=nil)
25 if keys.kind_of?(Hash)
26 name = nil
27 if keys.key?(:imagename)
28 name = keys[:imagename]
29 elsif keys.key?('imagename')
30 name = keys['imagename']
31 end
32 if name
33 if name.kind_of?(TkImage)
34 obj = name
35 else
36 name = _get_eval_string(name)
37 obj = nil
38 Tk_IMGTBL.mutex.synchronize{
39 obj = Tk_IMGTBL[name]
40 }
41 end
42 if obj
43 if !(keys[:without_creating] || keys['without_creating'])
44 keys = _symbolkey2str(keys)
45 keys.delete('imagename')
46 keys.delete('without_creating')
47 obj.instance_eval{
48 tk_call_without_enc('image', 'create',
49 @type, @path, *hash_kv(keys, true))
50 }
51 end
52 return obj
53 end
54 end
55 end
56 (obj = self.allocate).instance_eval{
57 Tk_IMGTBL.mutex.synchronize{
58 initialize(keys)
59 Tk_IMGTBL[@path] = self
60 }
61 }
62 obj
63 end
64
65 def initialize(keys=nil)
66 @path = nil
67 without_creating = false
68 if keys.kind_of?(Hash)
69 keys = _symbolkey2str(keys)
70 @path = keys.delete('imagename')
71 without_creating = keys.delete('without_creating')
72 end
73 unless @path
74 Tk_Image_ID.mutex.synchronize{
75 # @path = Tk_Image_ID.join('')
76 @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_)
77 Tk_Image_ID[1].succ!
78 }
79 end
80 unless without_creating
81 tk_call_without_enc('image', 'create',
82 @type, @path, *hash_kv(keys, true))
83 end
84 end
85
86 def delete
87 Tk_IMGTBL.mutex.synchronize{
88 Tk_IMGTBL.delete(@id) if @id
89 }
90 tk_call_without_enc('image', 'delete', @path)
91 self
92 end
93 def height
94 number(tk_call_without_enc('image', 'height', @path))
95 end
96 def inuse
97 bool(tk_call_without_enc('image', 'inuse', @path))
98 end
99 def itemtype
100 tk_call_without_enc('image', 'type', @path)
101 end
102 def width
103 number(tk_call_without_enc('image', 'width', @path))
104 end
105
106 def TkImage.names
107 Tk_IMGTBL.mutex.synchronize{
108 Tk.tk_call_without_enc('image', 'names').split.collect!{|id|
109 (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id
110 }
111 }
112 end
113
114 def TkImage.types
115 Tk.tk_call_without_enc('image', 'types').split
116 end
117 end
118
119 class TkBitmapImage<TkImage
120 def __strval_optkeys
121 super() + ['maskdata', 'maskfile']
122 end
123 private :__strval_optkeys
124
125 def initialize(*args)
126 @type = 'bitmap'
127 super(*args)
128 end
129 end
130
131 class TkPhotoImage<TkImage
132 NullArgOptionKeys = [ "shrink", "grayscale" ]
133
134 def _photo_hash_kv(keys)
135 keys = _symbolkey2str(keys)
136 NullArgOptionKeys.collect{|opt|
137 if keys[opt]
138 keys[opt] = None
139 else
140 keys.delete(opt)
141 end
142 }
143 keys.collect{|k,v|
144 ['-' << k, v]
145 }.flatten
146 end
147 private :_photo_hash_kv
148
149 def initialize(*args)
150 @type = 'photo'
151 super(*args)
152 end
153
154 def blank
155 tk_send_without_enc('blank')
156 self
157 end
158
159 def cget_strict(option)
160 case option.to_s
161 when 'data', 'file'
162 tk_send 'cget', '-' << option.to_s
163 else
164 tk_tcl2ruby(tk_send('cget', '-' << option.to_s))
165 end
166 end
167 def cget(option)
168 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
169 cget_strict(option)
170 else
171 begin
172 cget_strict(option)
173 rescue => e
174 if current_configinfo.has_key?(option.to_s)
175 # error on known option
176 fail e
177 else
178 # unknown option
179 nil
180 end
181 end
182 end
183 end
184
185 def copy(src, *opts)
186 if opts.size == 0
187 tk_send('copy', src)
188 elsif opts.size == 1 && opts[0].kind_of?(Hash)
189 tk_send('copy', src, *_photo_hash_kv(opts[0]))
190 else
191 # for backward compatibility
192 args = opts.collect{|term|
193 if term.kind_of?(String) && term.include?(?\s)
194 term.split
195 else
196 term
197 end
198 }.flatten
199 tk_send('copy', src, *args)
200 end
201 self
202 end
203
204 def data(keys={})
205 #tk_send('data', *_photo_hash_kv(keys))
206 tk_split_list(tk_send('data', *_photo_hash_kv(keys)))
207 end
208
209 def get(x, y)
210 tk_send('get', x, y).split.collect{|n| n.to_i}
211 end
212
213 def put(data, *opts)
214 if opts == []
215 tk_send('put', data)
216 elsif opts.size == 1 && opts[0].kind_of?(Hash)
217 tk_send('put', data, *_photo_hash_kv(opts[0]))
218 else
219 # for backward compatibility
220 tk_send('put', data, '-to', *opts)
221 end
222 self
223 end
224
225 def read(file, *opts)
226 if opts.size == 0
227 tk_send('read', file)
228 elsif opts.size == 1 && opts[0].kind_of?(Hash)
229 tk_send('read', file, *_photo_hash_kv(opts[0]))
230 else
231 # for backward compatibility
232 args = opts.collect{|term|
233 if term.kind_of?(String) && term.include?(?\s)
234 term.split
235 else
236 term
237 end
238 }.flatten
239 tk_send('read', file, *args)
240 end
241 self
242 end
243
244 def redither
245 tk_send 'redither'
246 self
247 end
248
249 def get_transparency(x, y)
250 bool(tk_send('transparency', 'get', x, y))
251 end
252 def set_transparency(x, y, st)
253 tk_send('transparency', 'set', x, y, st)
254 self
255 end
256
257 def write(file, *opts)
258 if opts.size == 0
259 tk_send('write', file)
260 elsif opts.size == 1 && opts[0].kind_of?(Hash)
261 tk_send('write', file, *_photo_hash_kv(opts[0]))
262 else
263 # for backward compatibility
264 args = opts.collect{|term|
265 if term.kind_of?(String) && term.include?(?\s)
266 term.split
267 else
268 term
269 end
270 }.flatten
271 tk_send('write', file, *args)
272 end
273 self
274 end
275 end