1 #
2 # tk/canvas.rb - Tk canvas classes
3 # by Yukihiro Matsumoto <matz@caelum.co.jp>
4 #
5 require 'tk'
6 require 'tk/canvastag'
7 require 'tk/itemconfig'
8 require 'tk/scrollable'
9
10 module TkCanvasItemConfig
11 include TkItemConfigMethod
12
13 def __item_strval_optkeys(id)
14 # maybe need to override
15 super(id) + [
16 'fill', 'activefill', 'disabledfill',
17 'outline', 'activeoutline', 'disabledoutline'
18 ]
19 end
20 private :__item_strval_optkeys
21
22 def __item_methodcall_optkeys(id)
23 {'coords'=>'coords'}
24 end
25 private :__item_methodcall_optkeys
26
27 def __item_val2ruby_optkeys(id) # { key=>proc, ... }
28 super(id).update('window'=>proc{|i, v| window(v)})
29 end
30 private :__item_val2ruby_optkeys
31
32 def __item_pathname(tagOrId)
33 if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag)
34 self.path + ';' + tagOrId.id.to_s
35 else
36 self.path + ';' + tagOrId.to_s
37 end
38 end
39 private :__item_pathname
40 end
41
42 class Tk::Canvas<TkWindow
43 include TkCanvasItemConfig
44 include Tk::Scrollable
45
46 TkCommandNames = ['canvas'.freeze].freeze
47 WidgetClassName = 'Canvas'.freeze
48 WidgetClassNames[WidgetClassName] = self
49
50 def __destroy_hook__
51 TkcItem::CItemID_TBL.delete(@path)
52 end
53
54 #def create_self(keys)
55 # if keys and keys != None
56 # tk_call_without_enc('canvas', @path, *hash_kv(keys, true))
57 # else
58 # tk_call_without_enc('canvas', @path)
59 # end
60 #end
61 #private :create_self
62
63 def __numval_optkeys
64 super() + ['closeenough']
65 end
66 private :__numval_optkeys
67
68 def __boolval_optkeys
69 super() + ['confine']
70 end
71 private :__boolval_optkeys
72
73 def tagid(tag)
74 if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag)
75 tag.id
76 else
77 tag # maybe an Array of configure paramters
78 end
79 end
80 private :tagid
81
82
83 # create a canvas item without creating a TkcItem object
84 def create(type, *args)
85 type.create(self, *args)
86 end
87
88
89 def addtag(tag, mode, *args)
90 mode = mode.to_s
91 if args[0] && mode =~ /^(above|below|with(tag)?)$/
92 args[0] = tagid(args[0])
93 end
94 tk_send_without_enc('addtag', tagid(tag), mode, *args)
95 self
96 end
97 def addtag_above(tagOrId, target)
98 addtag(tagOrId, 'above', tagid(target))
99 end
100 def addtag_all(tagOrId)
101 addtag(tagOrId, 'all')
102 end
103 def addtag_below(tagOrId, target)
104 addtag(tagOrId, 'below', tagid(target))
105 end
106 def addtag_closest(tagOrId, x, y, halo=None, start=None)
107 addtag(tagOrId, 'closest', x, y, halo, start)
108 end
109 def addtag_enclosed(tagOrId, x1, y1, x2, y2)
110 addtag(tagOrId, 'enclosed', x1, y1, x2, y2)
111 end
112 def addtag_overlapping(tagOrId, x1, y1, x2, y2)
113 addtag(tagOrId, 'overlapping', x1, y1, x2, y2)
114 end
115 def addtag_withtag(tagOrId, tag)
116 addtag(tagOrId, 'withtag', tagid(tag))
117 end
118
119 def bbox(tagOrId, *tags)
120 list(tk_send_without_enc('bbox', tagid(tagOrId),
121 *tags.collect{|t| tagid(t)}))
122 end
123
124 #def itembind(tag, context, cmd=Proc.new, *args)
125 # _bind([path, "bind", tagid(tag)], context, cmd, *args)
126 # self
127 #end
128 def itembind(tag, context, *args)
129 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
130 if TkComm._callback_entry?(args[0]) || !block_given?
131 cmd = args.shift
132 else
133 cmd = Proc.new
134 end
135 _bind([path, "bind", tagid(tag)], context, cmd, *args)
136 self
137 end
138
139 #def itembind_append(tag, context, cmd=Proc.new, *args)
140 # _bind_append([path, "bind", tagid(tag)], context, cmd, *args)
141 # self
142 #end
143 def itembind_append(tag, context, *args)
144 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
145 if TkComm._callback_entry?(args[0]) || !block_given?
146 cmd = args.shift
147 else
148 cmd = Proc.new
149 end
150 _bind_append([path, "bind", tagid(tag)], context, cmd, *args)
151 self
152 end
153
154 def itembind_remove(tag, context)
155 _bind_remove([path, "bind", tagid(tag)], context)
156 self
157 end
158
159 def itembindinfo(tag, context=nil)
160 _bindinfo([path, "bind", tagid(tag)], context)
161 end
162
163 def canvasx(screen_x, *args)
164 #tk_tcl2ruby(tk_send_without_enc('canvasx', screen_x, *args))
165 number(tk_send_without_enc('canvasx', screen_x, *args))
166 end
167 def canvasy(screen_y, *args)
168 #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args))
169 number(tk_send_without_enc('canvasy', screen_y, *args))
170 end
171 alias canvas_x canvasx
172 alias canvas_y canvasy
173
174 def coords(tag, *args)
175 if args == []
176 tk_split_list(tk_send_without_enc('coords', tagid(tag)))
177 else
178 tk_send_without_enc('coords', tagid(tag), *(args.flatten))
179 self
180 end
181 end
182
183 def dchars(tag, first, last=None)
184 tk_send_without_enc('dchars', tagid(tag),
185 _get_eval_enc_str(first), _get_eval_enc_str(last))
186 self
187 end
188
189 def delete(*args)
190 tbl = nil
191 TkcItem::CItemID_TBL.mutex.synchronize{
192 tbl = TkcItem::CItemID_TBL[self.path]
193 }
194 if tbl
195 args.each{|tag|
196 find('withtag', tag).each{|item|
197 if item.kind_of?(TkcItem)
198 TkcItem::CItemID_TBL.mutex.synchronize{
199 tbl.delete(item.id)
200 }
201 end
202 }
203 }
204 end
205 tk_send_without_enc('delete', *args.collect{|t| tagid(t)})
206 self
207 end
208 alias remove delete
209
210 def dtag(tag, tag_to_del=None)
211 tk_send_without_enc('dtag', tagid(tag), tagid(tag_to_del))
212 self
213 end
214 alias deltag dtag
215
216 def find(mode, *args)
217 list(tk_send_without_enc('find', mode, *args)).collect!{|id|
218 TkcItem.id2obj(self, id)
219 }
220 end
221 def find_above(target)
222 find('above', tagid(target))
223 end
224 def find_all
225 find('all')
226 end
227 def find_below(target)
228 find('below', tagid(target))
229 end
230 def find_closest(x, y, halo=None, start=None)
231 find('closest', x, y, halo, start)
232 end
233 def find_enclosed(x1, y1, x2, y2)
234 find('enclosed', x1, y1, x2, y2)
235 end
236 def find_overlapping(x1, y1, x2, y2)
237 find('overlapping', x1, y1, x2, y2)
238 end
239 def find_withtag(tag)
240 find('withtag', tag)
241 end
242
243 def itemfocus(tagOrId=nil)
244 if tagOrId
245 tk_send_without_enc('focus', tagid(tagOrId))
246 self
247 else
248 ret = tk_send_without_enc('focus')
249 if ret == ""
250 nil
251 else
252 TkcItem.id2obj(self, ret)
253 end
254 end
255 end
256
257 def gettags(tagOrId)
258 list(tk_send_without_enc('gettags', tagid(tagOrId))).collect{|tag|
259 TkcTag.id2obj(self, tag)
260 }
261 end
262
263 def icursor(tagOrId, index)
264 tk_send_without_enc('icursor', tagid(tagOrId), index)
265 self
266 end
267
268 def index(tagOrId, idx)
269 number(tk_send_without_enc('index', tagid(tagOrId), idx))
270 end
271
272 def insert(tagOrId, index, string)
273 tk_send_without_enc('insert', tagid(tagOrId), index,
274 _get_eval_enc_str(string))
275 self
276 end
277
278 =begin
279 def itemcget(tagOrId, option)
280 case option.to_s
281 when 'dash', 'activedash', 'disableddash'
282 conf = tk_send_without_enc('itemcget', tagid(tagOrId), "-#{option}")
283 if conf =~ /^[0-9]/
284 list(conf)
285 else
286 conf
287 end
288 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
289 _fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId), "-#{option}"))
290 when 'font', 'kanjifont'
291 #fnt = tk_tcl2ruby(tk_send('itemcget', tagid(tagOrId), "-#{option}"))
292 fnt = tk_tcl2ruby(_fromUTF8(tk_send_with_enc('itemcget', tagid(tagOrId), '-font')))
293 unless fnt.kind_of?(TkFont)
294 fnt = tagfontobj(tagid(tagOrId), fnt)
295 end
296 if option.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/
297 # obsolete; just for compatibility
298 fnt.kanji_font
299 else
300 fnt
301 end
302 else
303 tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId),
304 "-#{option}")))
305 end
306 end
307
308 def itemconfigure(tagOrId, key, value=None)
309 if key.kind_of? Hash
310 key = _symbolkey2str(key)
311 coords = key.delete('coords')
312 self.coords(tagOrId, coords) if coords
313
314 if ( key['font'] || key['kanjifont'] \
315 || key['latinfont'] || key['asciifont'] )
316 tagfont_configure(tagid(tagOrId), key.dup)
317 else
318 _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),
319 *hash_kv(key, true)))
320 end
321
322 else
323 if ( key == 'coords' || key == :coords )
324 self.coords(tagOrId, value)
325 elsif ( key == 'font' || key == :font ||
326 key == 'kanjifont' || key == :kanjifont ||
327 key == 'latinfont' || key == :latinfont ||
328 key == 'asciifont' || key == :asciifont )
329 if value == None
330 tagfontobj(tagid(tagOrId))
331 else
332 tagfont_configure(tagid(tagOrId), {key=>value})
333 end
334 else
335 _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),
336 "-#{key}", _get_eval_enc_str(value)))
337 end
338 end
339 self
340 end
341 # def itemconfigure(tagOrId, key, value=None)
342 # if key.kind_of? Hash
343 # tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
344 # else
345 # tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
346 # end
347 # end
348 # def itemconfigure(tagOrId, keys)
349 # tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys)
350 # end
351
352 def itemconfiginfo(tagOrId, key=nil)
353 if TkComm::GET_CONFIGINFO_AS_ARRAY
354 if key
355 case key.to_s
356 when 'coords'
357 return ['coords', '', '', '', self.coords(tagOrId)]
358 when 'dash', 'activedash', 'disableddash'
359 conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))
360 if conf[3] && conf[3] =~ /^[0-9]/
361 conf[3] = list(conf[3])
362 end
363 if conf[4] && conf[4] =~ /^[0-9]/
364 conf[4] = list(conf[4])
365 end
366 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
367 conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}")))
368 when 'font', 'kanjifont'
369 conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),"-#{key}")))
370 conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4])
371 else
372 conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}")))
373 end
374 conf[0] = conf[0][1..-1]
375 conf
376 else
377 ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).collect{|conflist|
378 conf = tk_split_simplelist(conflist)
379 conf[0] = conf[0][1..-1]
380 case conf[0]
381 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
382 when 'dash', 'activedash', 'disableddash'
383 if conf[3] && conf[3] =~ /^[0-9]/
384 conf[3] = list(conf[3])
385 end
386 if conf[4] && conf[4] =~ /^[0-9]/
387 conf[4] = list(conf[4])
388 end
389 else
390 if conf[3]
391 if conf[3].index('{')
392 conf[3] = tk_split_list(conf[3])
393 else
394 conf[3] = tk_tcl2ruby(conf[3])
395 end
396 end
397 if conf[4]
398 if conf[4].index('{')
399 conf[4] = tk_split_list(conf[4])
400 else
401 conf[4] = tk_tcl2ruby(conf[4])
402 end
403 end
404 end
405 conf[1] = conf[1][1..-1] if conf.size == 2 # alias info
406 conf
407 }
408
409 fontconf = ret.assoc('font')
410 if fontconf
411 ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
412 fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4])
413 ret.push(fontconf)
414 end
415
416 ret << ['coords', '', '', '', self.coords(tagOrId)]
417 end
418 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
419 if key
420 case key.to_s
421 when 'coords'
422 {'coords' => ['', '', '', self.coords(tagOrId)]}
423 when 'dash', 'activedash', 'disableddash'
424 conf = tk_split_simplelist(tk_send_without_enc('itemconfigure',
425 tagid(tagOrId),
426 "-#{key}"))
427 if conf[3] && conf[3] =~ /^[0-9]/
428 conf[3] = list(conf[3])
429 end
430 if conf[4] && conf[4] =~ /^[0-9]/
431 conf[4] = list(conf[4])
432 end
433 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
434 conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}")))
435 when 'font', 'kanjifont'
436 conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),"-#{key}")))
437 conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4])
438 else
439 conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}")))
440 end
441 key = conf.shift[1..-1]
442 { key => conf }
443 else
444 ret = {}
445 tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).each{|conflist|
446 conf = tk_split_simplelist(conflist)
447 key = conf.shift[1..-1]
448 case key
449 when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
450 when 'dash', 'activedash', 'disableddash'
451 if conf[2] && conf[2] =~ /^[0-9]/
452 conf[2] = list(conf[2])
453 end
454 if conf[3] && conf[3] =~ /^[0-9]/
455 conf[3] = list(conf[3])
456 end
457 else
458 if conf[2]
459 if conf[2].index('{')
460 conf[2] = tk_split_list(conf[2])
461 else
462 conf[2] = tk_tcl2ruby(conf[2])
463 end
464 end
465 if conf[3]
466 if conf[3].index('{')
467 conf[3] = tk_split_list(conf[3])
468 else
469 conf[3] = tk_tcl2ruby(conf[3])
470 end
471 end
472 end
473 if conf.size == 1
474 ret[key] = conf[0][1..-1] # alias info
475 else
476 ret[key] = conf
477 end
478 }
479
480 fontconf = ret['font']
481 if fontconf
482 ret.delete('font')
483 ret.delete('kanjifont')
484 fontconf[3] = tagfont_configinfo(tagid(tagOrId), fontconf[3])
485 ret['font'] = fontconf
486 end
487
488 ret['coords'] = ['', '', '', self.coords(tagOrId)]
489
490 ret
491 end
492 end
493 end
494
495 def current_itemconfiginfo(tagOrId, key=nil)
496 if TkComm::GET_CONFIGINFO_AS_ARRAY
497 if key
498 conf = itemconfiginfo(tagOrId, key)
499 {conf[0] => conf[4]}
500 else
501 ret = {}
502 itemconfiginfo(tagOrId).each{|conf|
503 ret[conf[0]] = conf[4] if conf.size > 2
504 }
505 ret
506 end
507 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
508 ret = {}
509 itemconfiginfo(tagOrId, key).each{|k, conf|
510 ret[k] = conf[-1] if conf.kind_of?(Array)
511 }
512 ret
513 end
514 end
515 =end
516
517 def lower(tag, below=nil)
518 if below
519 tk_send_without_enc('lower', tagid(tag), tagid(below))
520 else
521 tk_send_without_enc('lower', tagid(tag))
522 end
523 self
524 end
525
526 def move(tag, x, y)
527 tk_send_without_enc('move', tagid(tag), x, y)
528 self
529 end
530
531 def postscript(keys)
532 tk_send("postscript", *hash_kv(keys))
533 end
534
535 def raise(tag, above=nil)
536 if above
537 tk_send_without_enc('raise', tagid(tag), tagid(above))
538 else
539 tk_send_without_enc('raise', tagid(tag))
540 end
541 self
542 end
543
544 def scale(tag, x, y, xs, ys)
545 tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)
546 self
547 end
548
549 def scan_mark(x, y)
550 tk_send_without_enc('scan', 'mark', x, y)
551 self
552 end
553 def scan_dragto(x, y, gain=None)
554 tk_send_without_enc('scan', 'dragto', x, y, gain)
555 self
556 end
557
558 def select(mode, *args)
559 r = tk_send_without_enc('select', mode, *args)
560 (mode == 'item')? TkcItem.id2obj(self, r): self
561 end
562 def select_adjust(tagOrId, index)
563 select('adjust', tagid(tagOrId), index)
564 end
565 def select_clear
566 select('clear')
567 end
568 def select_from(tagOrId, index)
569 select('from', tagid(tagOrId), index)
570 end
571 def select_item
572 select('item')
573 end
574 def select_to(tagOrId, index)
575 select('to', tagid(tagOrId), index)
576 end
577
578 def itemtype(tag)
579 TkcItem.type2class(tk_send('type', tagid(tag)))
580 end
581 end
582
583 #TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas
584 Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
585
586
587 class TkcItem<TkObject
588 extend Tk
589 include TkcTagAccess
590 extend TkItemFontOptkeys
591 extend TkItemConfigOptkeys
592
593 CItemTypeName = nil
594 CItemTypeToClass = {}
595
596 CItemID_TBL = TkCore::INTERP.create_table
597
598 TkCore::INTERP.init_ip_env{
599 CItemID_TBL.mutex.synchronize{ CItemID_TBL.clear }
600 }
601
602 def TkcItem.type2class(type)
603 CItemTypeToClass[type]
604 end
605
606 def TkcItem.id2obj(canvas, id)
607 cpath = canvas.path
608 CItemID_TBL.mutex.synchronize{
609 if CItemID_TBL[cpath]
610 CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id
611 else
612 id
613 end
614 }
615 end
616
617 ########################################
618 def self._parse_create_args(args)
619 fontkeys = {}
620 methodkeys = {}
621 if args[-1].kind_of? Hash
622 keys = _symbolkey2str(args.pop)
623 if args.size == 0
624 args = keys.delete('coords')
625 unless args.kind_of?(Array)
626 fail "coords parameter must be given by an Array"
627 end
628 end
629
630 #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|
631 # fontkeys[key] = keys.delete(key) if keys.key?(key)
632 #}
633 __item_font_optkeys(nil).each{|key|
634 fkey = key.to_s
635 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
636
637 fkey = "kanji#{key}"
638 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
639
640 fkey = "latin#{key}"
641 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
642
643 fkey = "ascii#{key}"
644 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)
645 }
646
647 __item_optkey_aliases(nil).each{|alias_name, real_name|
648 alias_name = alias_name.to_s
649 if keys.has_key?(alias_name)
650 keys[real_name.to_s] = keys.delete(alias_name)
651 end
652 }
653
654 __item_methodcall_optkeys(nil).each{|key|
655 key = key.to_s
656 methodkeys[key] = keys.delete(key) if keys.key?(key)
657 }
658
659 __item_ruby2val_optkeys(nil).each{|key, method|
660 key = key.to_s
661 keys[key] = method.call(keys[key]) if keys.has_key?(key)
662 }
663
664 #args = args.flatten.concat(hash_kv(keys))
665 args = args.flatten.concat(itemconfig_hash_kv(nil, keys))
666 else
667 args = args.flatten
668 end
669
670 [args, fontkeys]
671 end
672 private_class_method :_parse_create_args
673
674 def self.create(canvas, *args)
675 unless self::CItemTypeName
676 fail RuntimeError, "#{self} is an abstract class"
677 end
678 args, fontkeys = _parse_create_args(args)
679 idnum = tk_call_without_enc(canvas.path, 'create',
680 self::CItemTypeName, *args)
681 canvas.itemconfigure(idnum, fontkeys) unless fontkeys.empty?
682 idnum.to_i # 'canvas item id' is an integer number
683 end
684 ########################################
685
686 def initialize(parent, *args)
687 #unless parent.kind_of?(Tk::Canvas)
688 # fail ArgumentError, "expect Tk::Canvas for 1st argument"
689 #end
690 @parent = @c = parent
691 @path = parent.path
692
693 @id = create_self(*args) # an integer number as 'canvas item id'
694 CItemID_TBL.mutex.synchronize{
695 CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
696 CItemID_TBL[@path][@id] = self
697 }
698 end
699 def create_self(*args)
700 self.class.create(@c, *args) # return an integer number as 'canvas item id'
701 end
702 private :create_self
703
704 def id
705 @id
706 end
707
708 def exist?
709 if @c.find_withtag(@id)
710 true
711 else
712 false
713 end
714 end
715
716 def delete
717 @c.delete @id
718 CItemID_TBL.mutex.synchronize{
719 CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]
720 }
721 self
722 end
723 alias remove delete
724 alias destroy delete
725 end
726
727 class TkcArc<TkcItem
728 CItemTypeName = 'arc'.freeze
729 CItemTypeToClass[CItemTypeName] = self
730 end
731
732 class TkcBitmap<TkcItem
733 CItemTypeName = 'bitmap'.freeze
734 CItemTypeToClass[CItemTypeName] = self
735 end
736
737 class TkcImage<TkcItem
738 CItemTypeName = 'image'.freeze
739 CItemTypeToClass[CItemTypeName] = self
740 end
741
742 class TkcLine<TkcItem
743 CItemTypeName = 'line'.freeze
744 CItemTypeToClass[CItemTypeName] = self
745 end
746
747 class TkcOval<TkcItem
748 CItemTypeName = 'oval'.freeze
749 CItemTypeToClass[CItemTypeName] = self
750 end
751
752 class TkcPolygon<TkcItem
753 CItemTypeName = 'polygon'.freeze
754 CItemTypeToClass[CItemTypeName] = self
755 end
756
757 class TkcRectangle<TkcItem
758 CItemTypeName = 'rectangle'.freeze
759 CItemTypeToClass[CItemTypeName] = self
760 end
761
762 class TkcText<TkcItem
763 CItemTypeName = 'text'.freeze
764 CItemTypeToClass[CItemTypeName] = self
765 def self.create(canvas, *args)
766 if args[-1].kind_of?(Hash)
767 keys = _symbolkey2str(args.pop)
768 txt = keys['text']
769 keys['text'] = _get_eval_enc_str(txt) if txt
770 args.push(keys)
771 end
772 super(canvas, *args)
773 end
774 end
775
776 class TkcWindow<TkcItem
777 CItemTypeName = 'window'.freeze
778 CItemTypeToClass[CItemTypeName] = self
779 def self.create(canvas, *args)
780 if args[-1].kind_of?(Hash)
781 keys = _symbolkey2str(args.pop)
782 win = keys['window']
783 # keys['window'] = win.epath if win.kind_of?(TkWindow)
784 keys['window'] = _epath(win) if win
785 args.push(keys)
786 end
787 super(canvas, *args)
788 end
789 end