ext/tk/lib/tkcanvas.rb


DEFINITIONS

This source file includes following functions.


   1  #
   2  #               tkcanvas.rb - Tk canvas classes
   3  #                       $Date: 2002/06/28 14:40:25 $
   4  #                       by Yukihiro Matsumoto <matz@caelum.co.jp>
   5  #                       $Date: 2002/06/28 14:40:25 $
   6  #                       by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
   7  
   8  require "tk"
   9  require 'tkfont'
  10  
  11  module TkTreatCItemFont
  12    include TkTreatItemFont
  13  
  14    ItemCMD = ['itemconfigure', TkComm::None]
  15    def __conf_cmd(idx)
  16      ItemCMD[idx]
  17    end
  18  
  19    def __item_pathname(tagOrId)
  20      if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag)
  21        self.path + ';' + tagOrId.id.to_s
  22      else
  23        self.path + ';' + tagOrId.to_s
  24      end
  25    end
  26  end
  27  
  28  class TkCanvas<TkWindow
  29    include TkTreatCItemFont
  30    include Scrollable
  31  
  32    WidgetClassName = 'Canvas'.freeze
  33    WidgetClassNames[WidgetClassName] = self
  34    def self.to_eval
  35      WidgetClassName
  36    end
  37  
  38    def create_self(keys)
  39      if keys and keys != None
  40        tk_call 'canvas', @path, *hash_kv(keys)
  41      else
  42        tk_call 'canvas', @path
  43      end
  44    end
  45  
  46    def tagid(tag)
  47      if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag)
  48        tag.id
  49      else
  50        tag
  51      end
  52    end
  53    private :tagid
  54  
  55    def addtag(tag, mode, *args)
  56      tk_send 'addtag', tagid(tag), mode, *args
  57    end
  58    def addtag_above(tagOrId, target)
  59      addtag(tagOrId, 'above', tagid(target))
  60    end
  61    def addtag_all(tagOrId)
  62      addtag(tagOrId, 'all')
  63    end
  64    def addtag_below(tagOrId, target)
  65      addtag(tagOrId, 'below', tagid(target))
  66    end
  67    def addtag_closest(tagOrId, x, y, halo=None, start=None)
  68      addtag(tagOrId, 'closest', x, y, halo, start)
  69    end
  70    def addtag_enclosed(tagOrId, x1, y1, x2, y2)
  71      addtag(tagOrId, 'enclosed', x1, y1, x2, y2)
  72    end
  73    def addtag_overlapping(tagOrId, x1, y1, x2, y2)
  74      addtag(tagOrId, 'overlapping', x1, y1, x2, y2)
  75    end
  76    def addtag_withtag(tagOrId, tag)
  77      addtag(tagOrId, 'withtag', tagid(tag))
  78    end
  79  
  80    def bbox(tagOrId, *tags)
  81      list(tk_send('bbox', tagid(tagOrId), *tags.collect{|t| tagid(t)}))
  82    end
  83  
  84    def itembind(tag, context, cmd=Proc.new, args=nil)
  85      _bind([path, "bind", tagid(tag)], context, cmd, args)
  86    end
  87  
  88    def itembind_append(tag, context, cmd=Proc.new, args=nil)
  89      _bind_append([path, "bind", tagid(tag)], context, cmd, args)
  90    end
  91  
  92    def itembindinfo(tag, context=nil)
  93      _bindinfo([path, "bind", tagid(tag)], context)
  94    end
  95  
  96    def canvasx(x, *args)
  97      tk_tcl2ruby(tk_send('canvasx', x, *args))
  98    end
  99    def canvasy(y, *args)
 100      tk_tcl2ruby(tk_send('canvasy', y, *args))
 101    end
 102  
 103    def coords(tag, *args)
 104      if args == []
 105        tk_split_list(tk_send('coords', tagid(tag)))
 106      else
 107        tk_send('coords', tagid(tag), *args)
 108      end
 109    end
 110  
 111    def dchars(tag, first, last=None)
 112      tk_send 'dchars', tagid(tag), first, last
 113    end
 114  
 115    def delete(*args)
 116      tk_send 'delete', *args.collect{|t| tagid(t)}
 117    end
 118    alias remove delete
 119  
 120    def dtag(tag, tag_to_del=None)
 121      tk_send 'dtag', tagid(tag), tag_to_del
 122    end
 123  
 124    def find(mode, *args)
 125      list(tk_send('find', mode, *args)).collect!{|id| 
 126        TkcItem.id2obj(self, id)
 127      }
 128    end
 129    def find_above(target)
 130      find('above', tagid(target))
 131    end
 132    def find_all
 133      find('all')
 134    end
 135    def find_below(target)
 136      find('below', tagid(target))
 137    end
 138    def find_closest(x, y, halo=None, start=None)
 139      find('closest', x, y, halo, start)
 140    end
 141    def find_enclosed(x1, y1, x2, y2)
 142      find('enclosed', x1, y1, x2, y2)
 143    end
 144    def find_overlapping(x1, y1, x2, y2)
 145      find('overlapping', x1, y1, x2, y2)
 146    end
 147    def find_withtag(tag)
 148      find('withtag', tag)
 149    end
 150  
 151    def itemfocus(tagOrId=nil)
 152      if tagOrId
 153        tk_send 'focus', tagid(tagOrId)
 154      else
 155        ret = tk_send('focus')
 156        if ret == ""
 157          nil
 158        else
 159          TkcItem.id2obj(self, ret)
 160        end
 161      end
 162    end
 163  
 164    def gettags(tagOrId)
 165      list(tk_send('gettags', tagid(tagOrId))).collect{|tag|
 166        TkcTag.id2obj(self, tag)
 167      }
 168    end
 169  
 170    def icursor(tagOrId, index)
 171      tk_send 'icursor', tagid(tagOrId), index
 172    end
 173  
 174    def index(tagOrId, index)
 175      tk_send 'index', tagid(tagOrId), index
 176    end
 177  
 178    def insert(tagOrId, index, string)
 179      tk_send 'insert', tagid(tagOrId), index, string
 180    end
 181  
 182    def itemcget(tagOrId, option)
 183      case option.to_s
 184      when 'dash', 'activedash', 'disableddash'
 185        conf = tk_send('itemcget', tagid(tagOrId), "-#{option}")
 186        if conf =~ /^[0-9]/
 187          list(conf)
 188        else
 189          conf
 190        end
 191      when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
 192        tk_send 'itemcget', tagid(tagOrId), "-#{option}"
 193      else
 194        tk_tcl2ruby tk_send('itemcget', tagid(tagOrId), "-#{option}")
 195      end
 196    end
 197  
 198    def itemconfigure(tagOrId, key, value=None)
 199      if key.kind_of? Hash
 200        key = _symbolkey2str(key)
 201        if ( key['font'] || key['kanjifont'] \
 202            || key['latinfont'] || key['asciifont'] )
 203          tagfont_configure(tagOrId, key.dup)
 204        else
 205          tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
 206        end
 207  
 208      else
 209        if ( key == 'font' || key == :font || 
 210             key == 'kanjifont' || key == :kanjifont || 
 211             key == 'latinfont' || key == :latinfont || 
 212             key == 'asciifont' || key == :asciifont )
 213          tagfont_configure(tagid(tagOrId), {key=>value})
 214        else
 215          tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
 216        end
 217      end
 218    end
 219  #  def itemconfigure(tagOrId, key, value=None)
 220  #    if key.kind_of? Hash
 221  #      tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
 222  #    else
 223  #      tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
 224  #    end
 225  #  end
 226  #  def itemconfigure(tagOrId, keys)
 227  #    tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys)
 228  #  end
 229  
 230    def itemconfiginfo(tagOrId, key=nil)
 231      if key
 232        case key.to_s
 233        when 'dash', 'activedash', 'disableddash'
 234          conf = tk_split_simplelist(tk_send('itemconfigure', 
 235                                             tagid(tagOrId), "-#{key}"))
 236          if conf[3] && conf[3] =~ /^[0-9]/
 237            conf[3] = list(conf[3])
 238          end
 239          if conf[4] && conf[4] =~ /^[0-9]/
 240            conf[4] = list(conf[4])
 241          end
 242        when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
 243          conf = tk_split_simplelist(tk_send('itemconfigure', 
 244                                             tagid(tagOrId), "-#{key}"))
 245        else
 246          conf = tk_split_list(tk_send('itemconfigure', 
 247                                       tagid(tagOrId), "-#{key}"))
 248        end
 249        conf[0] = conf[0][1..-1]
 250        conf
 251      else
 252        tk_split_simplelist(tk_send('itemconfigure', 
 253                                    tagid(tagOrId))).collect{|conflist|
 254          conf = tk_split_simplelist(conflist)
 255          conf[0] = conf[0][1..-1]
 256          case conf[0]
 257          when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'
 258          when 'dash', 'activedash', 'disableddash'
 259            if conf[3] && conf[3] =~ /^[0-9]/
 260              conf[3] = list(conf[3])
 261            end
 262            if conf[4] && conf[4] =~ /^[0-9]/
 263              conf[4] = list(conf[4])
 264            end
 265          else
 266            if conf[3]
 267              if conf[3].index('{')
 268                conf[3] = tk_split_list(conf[3]) 
 269              else
 270                conf[3] = tk_tcl2ruby(conf[3]) 
 271              end
 272            end
 273            if conf[4]
 274              if conf[4].index('{')
 275                conf[4] = tk_split_list(conf[4]) 
 276              else
 277                conf[4] = tk_tcl2ruby(conf[4]) 
 278              end
 279            end
 280          end
 281          conf
 282        }
 283      end
 284    end
 285  
 286    def lower(tag, below=None)
 287      tk_send 'lower', tagid(tag), tagid(below)
 288    end
 289  
 290    def move(tag, x, y)
 291      tk_send 'move', tagid(tag), x, y
 292    end
 293  
 294    def postscript(keys)
 295      tk_send "postscript", *hash_kv(keys)
 296    end
 297  
 298    def raise(tag, above=None)
 299      tk_send 'raise', tagid(tag), tagid(above)
 300    end
 301  
 302    def scale(tag, x, y, xs, ys)
 303      tk_send 'scale', tagid(tag), x, y, xs, ys
 304    end
 305  
 306    def scan_mark(x, y)
 307      tk_send 'scan', 'mark', x, y
 308    end
 309    def scan_dragto(x, y)
 310      tk_send 'scan', 'dragto', x, y
 311    end
 312  
 313    def select(mode, *args)
 314      tk_send 'select', mode, *args
 315    end
 316    def select_adjust(tagOrId, index)
 317      select('adjust', tagid(tagOrId), index)
 318    end
 319    def select_clear
 320      select('clear')
 321    end
 322    def select_from(tagOrId, index)
 323      select('from', tagid(tagOrId), index)
 324    end
 325    def select_item
 326      select('item')
 327    end
 328    def select_to(tagOrId, index)
 329      select('to', tagid(tagOrId), index)
 330    end
 331  
 332    def itemtype(tag)
 333      TkcItem.type2class(tk_send('type', tagid(tag)))
 334    end
 335  end
 336  
 337  module TkcTagAccess
 338    include TkComm
 339    include TkTreatTagFont
 340  
 341    def addtag(tag)
 342      @c.addtag(tag, 'with', @id)
 343    end
 344  
 345    def bbox
 346      @c.bbox(@id)
 347    end
 348  
 349    def bind(seq, cmd=Proc.new, args=nil)
 350      @c.itembind @id, seq, cmd, args
 351    end
 352  
 353    def bindinfo(seq=nil)
 354      @c.itembindinfo @id, seq
 355    end
 356  
 357    def cget(option)
 358      @c.itemcget @id, option
 359    end
 360  
 361    def configure(key, value=None)
 362      @c.itemconfigure @id, key, value
 363    end
 364  #  def configure(keys)
 365  #    @c.itemconfigure @id, keys
 366  #  end
 367  
 368    def configinfo(key=nil)
 369      @c.itemconfiginfo @id, key
 370    end
 371  
 372    def coords(*args)
 373      @c.coords @id, *args
 374    end
 375  
 376    def dchars(first, last=None)
 377      @c.dchars @id, first, last
 378    end
 379  
 380    def dtag(tag_to_del=None)
 381      @c.dtag @id, tag_to_del
 382    end
 383  
 384    def find
 385      @c.find 'withtag', @id
 386    end
 387    alias list find
 388  
 389    def focus
 390      @c.itemfocus @id
 391    end
 392  
 393    def gettags
 394      @c.gettags @id
 395    end
 396  
 397    def icursor(index)
 398      @c.icursor @id, index
 399    end
 400  
 401    def index(index)
 402      @c.index @id, index
 403    end
 404  
 405    def insert(beforethis, string)
 406      @c.insert @id, beforethis, string
 407    end
 408  
 409    def lower(belowthis=None)
 410      @c.lower @id, belowthis
 411    end
 412  
 413    def move(xamount, yamount)
 414      @c.move @id, xamount, yamount
 415    end
 416  
 417    def raise(abovethis=None)
 418      @c.raise @id, abovethis
 419    end
 420  
 421    def scale(xorigin, yorigin, xscale, yscale)
 422      @c.scale @id, xorigin, yorigin, xscale, yscale
 423    end
 424  
 425    def select_adjust(index)
 426      @c.select('adjust', @id, index)
 427    end
 428    def select_from(index)
 429      @c.select('from', @id, index)
 430    end
 431    def select_to(index)
 432      @c.select('to', @id, index)
 433    end
 434  
 435    def itemtype
 436      @c.itemtype @id
 437    end
 438  
 439    # Following operators support logical expressions of canvas tags
 440    # (for Tk8.3+).
 441    # If tag1.path is 't1' and tag2.path is 't2', then
 442    #      ltag = tag1 & tag2; ltag.path => "(t1)&&(t2)"
 443    #      ltag = tag1 | tag2; ltag.path => "(t1)||(t2)"
 444    #      ltag = tag1 ^ tag2; ltag.path => "(t1)^(t2)"
 445    #      ltag = - tag1;      ltag.path => "!(t1)"
 446    def & (tag)
 447      if tag.kind_of? TkObject
 448        TkcTagString.new(@c, '(' + @id + ')&&(' + tag.path + ')')
 449      else
 450        TkcTagString.new(@c, '(' + @id + ')&&(' + tag.to_s + ')')
 451      end
 452    end
 453  
 454    def | (tag)
 455      if tag.kind_of? TkObject
 456        TkcTagString.new(@c, '(' + @id + ')||(' + tag.path + ')')
 457      else
 458        TkcTagString.new(@c, '(' + @id + ')||(' + tag.to_s + ')')
 459      end
 460    end
 461  
 462    def ^ (tag)
 463      if tag.kind_of? TkObject
 464        TkcTagString.new(@c, '(' + @id + ')^(' + tag.path + ')')
 465      else
 466        TkcTagString.new(@c, '(' + @id + ')^(' + tag.to_s + ')')
 467      end
 468    end
 469  
 470    def -@
 471      TkcTagString.new(@c, '!(' + @id + ')')
 472    end
 473  end
 474  
 475  class TkcTag<TkObject
 476    include TkcTagAccess
 477  
 478    CTagID_TBL = {}
 479    Tk_CanvasTag_ID = ['ctag0000']
 480  
 481    def TkcTag.id2obj(canvas, id)
 482      cpath = canvas.path
 483      return id unless CTagID_TBL[cpath]
 484      CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id
 485    end
 486  
 487    def initialize(parent, mode=nil, *args)
 488      if not parent.kind_of?(TkCanvas)
 489        fail format("%s need to be TkCanvas", parent.inspect)
 490      end
 491      @c = parent
 492      @cpath = parent.path
 493      @path = @id = Tk_CanvasTag_ID[0]
 494      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
 495      CTagID_TBL[@cpath][@id] = self
 496      Tk_CanvasTag_ID[0] = Tk_CanvasTag_ID[0].succ
 497      if mode
 498        tk_call @c.path, "addtag", @id, mode, *args
 499      end
 500    end
 501    def id
 502      return @id
 503    end
 504  
 505    def delete
 506      @c.delete @id
 507      CTagID_TBL[@cpath][@id] = nil if CTagID_TBL[@cpath]
 508    end
 509    alias remove  delete
 510    alias destroy delete
 511  
 512    def set_to_above(target)
 513      @c.addtag_above(@id, target)
 514    end
 515    alias above set_to_above
 516  
 517    def set_to_all
 518      @c.addtag_all(@id)
 519    end
 520    alias all set_to_all
 521  
 522    def set_to_below(target)
 523      @c.addtag_below(@id, target)
 524    end
 525    alias below set_to_below
 526  
 527    def set_to_closest(x, y, halo=None, start=None)
 528      @c.addtag_closest(@id, x, y, halo, start)
 529    end
 530    alias closest set_to_closest
 531  
 532    def set_to_enclosed(x1, y1, x2, y2)
 533      @c.addtag_enclosed(@id, x1, y1, x2, y2)
 534    end
 535    alias enclosed set_to_enclosed
 536  
 537    def set_to_overlapping(x1, y1, x2, y2)
 538      @c.addtag_overlapping(@id, x1, y1, x2, y2)
 539    end
 540    alias overlapping set_to_overlapping
 541  
 542    def set_to_withtag(target)
 543      @c.addtag_withtag(@id, target)
 544    end
 545    alias withtag set_to_withtag
 546  end
 547  
 548  class TkcTagString<TkcTag
 549    def self.new(parent, name, *args)
 550      if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name]
 551        return CTagID_TBL[parent.path][name]
 552      else
 553        super(parent, name, *args)
 554      end
 555    end
 556  
 557    def initialize(parent, name, mode=nil, *args)
 558      if not parent.kind_of?(TkCanvas)
 559        fail format("%s need to be TkCanvas", parent.inspect)
 560      end
 561      @c = parent
 562      @cpath = parent.path
 563      @path = @id = name
 564      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
 565      CTagID_TBL[@cpath][@id] = self
 566      if mode
 567        tk_call @c.path, "addtag", @id, mode, *args
 568      end
 569    end
 570  end
 571  TkcNamedTag = TkcTagString
 572  
 573  class TkcTagAll<TkcTag
 574    def initialize(parent)
 575      if not parent.kind_of?(TkCanvas)
 576        fail format("%s need to be TkCanvas", parent.inspect)
 577      end
 578      @c = parent
 579      @cpath = parent.path
 580      @path = @id = 'all'
 581      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
 582      CTagID_TBL[@cpath][@id] = self
 583    end
 584  end
 585  
 586  class TkcTagCurrent<TkcTag
 587    def initialize(parent)
 588      if not parent.kind_of?(TkCanvas)
 589        fail format("%s need to be TkCanvas", parent.inspect)
 590      end
 591      @c = parent
 592      @cpath = parent.path
 593      @path = @id = 'current'
 594      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
 595      CTagID_TBL[@cpath][@id] = self
 596    end
 597  end
 598  
 599  class TkcGroup<TkcTag
 600    Tk_cGroup_ID = ['tkcg00000']
 601    def create_self(parent, *args)
 602      if not parent.kind_of?(TkCanvas)
 603        fail format("%s need to be TkCanvas", parent.inspect)
 604      end
 605      @c = parent
 606      @cpath = parent.path
 607      @path = @id = Tk_cGroup_ID[0]
 608      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
 609      CTagID_TBL[@cpath][@id] = self
 610      Tk_cGroup_ID[0] = Tk_cGroup_ID[0].succ
 611      add(*args) if args != []
 612    end
 613    
 614    def include(*tags)
 615      for i in tags
 616        i.addtag @id
 617      end
 618    end
 619  
 620    def exclude(*tags)
 621      for i in tags
 622        i.delete @id
 623      end
 624    end
 625  end
 626  
 627  class TkcItem<TkObject
 628    include TkcTagAccess
 629  
 630    CItemTypeToClass = {}
 631    CItemID_TBL = {}
 632  
 633    def TkcItem.type2class(type)
 634      CItemTypeToClass[type]
 635    end
 636  
 637    def TkcItem.id2obj(canvas, id)
 638      cpath = canvas.path
 639      return id unless CItemID_TBL[cpath]
 640      CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id
 641    end
 642  
 643    def initialize(parent, *args)
 644      if not parent.kind_of?(TkCanvas)
 645        fail format("%s need to be TkCanvas", parent.inspect)
 646      end
 647      @parent = @c = parent
 648      @path = parent.path
 649      fontkeys = {}
 650      if args.size == 1 && args[0].kind_of?(Hash)
 651        args[0] = _symbolkey2str(args[0])
 652        coords = args[0].delete('coords')
 653        if not coords.kind_of?(Array)
 654          fail "coords parameter must be given by an Array"
 655        end
 656        args[0,0] = coords.flatten
 657      end
 658      if args[-1].kind_of? Hash
 659        keys = _symbolkey2str(args.pop)
 660        ['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|
 661          fontkeys[key] = keys.delete(key) if keys.key?(key)
 662        }
 663        args += hash_kv(keys)
 664      end
 665      @id = create_self(*args).to_i ;# 'canvas item id' is integer number
 666      CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
 667      CItemID_TBL[@path][@id] = self
 668      font_configure(fontkeys) unless fontkeys.empty?
 669  
 670  ######## old version
 671  #    if args[-1].kind_of? Hash
 672  #      keys = args.pop
 673  #    end
 674  #    @id = create_self(*args).to_i ;# 'canvas item id' is integer number
 675  #    CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
 676  #    CItemID_TBL[@path][@id] = self
 677  #    if keys
 678  #      # tk_call @path, 'itemconfigure', @id, *hash_kv(keys)
 679  #      configure(keys) if keys
 680  #    end
 681  ########
 682    end
 683    def create_self(*args); end
 684    private :create_self
 685    def id
 686      return @id
 687    end
 688  
 689    def delete
 690      @c.delete @id
 691      CItemID_TBL[@path][@id] = nil if CItemID_TBL[@path]
 692    end
 693    alias remove  delete
 694    alias destroy delete
 695  end
 696  
 697  class TkcArc<TkcItem
 698    CItemTypeToClass['arc'] = self
 699    def create_self(*args)
 700      tk_call(@path, 'create', 'arc', *args)
 701    end
 702  end
 703  class TkcBitmap<TkcItem
 704    CItemTypeToClass['bitmap'] = self
 705    def create_self(*args)
 706      tk_call(@path, 'create', 'bitmap', *args)
 707    end
 708  end
 709  class TkcImage<TkcItem
 710    CItemTypeToClass['image'] = self
 711    def create_self(*args)
 712      tk_call(@path, 'create', 'image', *args)
 713    end
 714  end
 715  class TkcLine<TkcItem
 716    CItemTypeToClass['line'] = self
 717    def create_self(*args)
 718      tk_call(@path, 'create', 'line', *args)
 719    end
 720  end
 721  class TkcOval<TkcItem
 722    CItemTypeToClass['oval'] = self
 723    def create_self(*args)
 724      tk_call(@path, 'create', 'oval', *args)
 725    end
 726  end
 727  class TkcPolygon<TkcItem
 728    CItemTypeToClass['polygon'] = self
 729    def create_self(*args)
 730      tk_call(@path, 'create', 'polygon', *args)
 731    end
 732  end
 733  class TkcRectangle<TkcItem
 734    CItemTypeToClass['rectangle'] = self
 735    def create_self(*args)
 736      tk_call(@path, 'create', 'rectangle', *args)
 737    end
 738  end
 739  class TkcText<TkcItem
 740    CItemTypeToClass['text'] = self
 741    def create_self(*args)
 742      tk_call(@path, 'create', 'text', *args)
 743    end
 744  end
 745  class TkcWindow<TkcItem
 746    CItemTypeToClass['window'] = self
 747    def create_self(*args)
 748      tk_call(@path, 'create', 'window', *args)
 749    end
 750  end
 751  
 752  class TkImage<TkObject
 753    include Tk
 754  
 755    Tk_IMGTBL = {}
 756  
 757    Tk_Image_ID = ['i00000']
 758    def initialize(keys=nil)
 759      @path = Tk_Image_ID[0]
 760      Tk_Image_ID[0] = Tk_Image_ID[0].succ
 761      tk_call 'image', 'create', @type, @path, *hash_kv(keys)
 762      Tk_IMGTBL[@path] = self
 763    end
 764  
 765    def delete
 766      Tk_IMGTBL[@id] = nil if @id
 767      tk_call('image', 'delete', @path)
 768    end
 769    def height
 770      number(tk_call('image', 'height', @path))
 771    end
 772    def inuse
 773      bool(tk_call('image', 'inuse', @path))
 774    end
 775    def itemtype
 776      tk_call('image', 'type', @path)
 777    end
 778    def width
 779      number(tk_call('image', 'width', @path))
 780    end
 781  
 782    def TkImage.names
 783      Tk.tk_call('image', 'names').split.collect!{|id|
 784        (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id
 785      }
 786    end
 787  
 788    def TkImage.types
 789      Tk.tk_call('image', 'types').split
 790    end
 791  end
 792  
 793  class TkBitmapImage<TkImage
 794    def initialize(*args)
 795      @type = 'bitmap'
 796      super
 797    end
 798  end
 799  
 800  class TkPhotoImage<TkImage
 801    def initialize(*args)
 802      @type = 'photo'
 803      super
 804    end
 805  
 806    def blank
 807      tk_send 'blank'
 808    end
 809  
 810    def cget(option)
 811      case option.to_s
 812      when 'data', 'file'
 813        tk_send 'cget', option
 814      else
 815        tk_tcl2ruby tk_send('cget', option)
 816      end
 817    end
 818  
 819    def copy(source, *opts)
 820      args = opts.collect{|term|
 821        if term.kind_of?(String) && term.include?(?\s)
 822          term.split
 823        else
 824          term
 825        end
 826      }.flatten
 827  
 828      tk_send 'copy', source, *args
 829    end
 830  
 831    def data(keys=nil)
 832      tk_send 'data', *hash_kv(keys)
 833    end
 834  
 835    def get(x, y)
 836      tk_send 'get', x, y
 837    end
 838  
 839    def put(data, *to)
 840      if to == []
 841        tk_send 'put', data
 842      else
 843        tk_send 'put', data, '-to', *to
 844      end
 845    end
 846  
 847    def read(file, *opts)
 848      args = opts.collect{|term|
 849        if term.kind_of?(String) && term.include?(?\s)
 850          term.split
 851        else
 852          term
 853        end
 854      }.flatten
 855    
 856      tk_send 'read', file, *args
 857    end
 858  
 859    def redither
 860      tk_send 'redither'
 861    end
 862  
 863    def write(file, *opts)
 864      args = opts.collect{|term|
 865        if term.kind_of?(String) && term.include?(?\s)
 866          term.split
 867        else
 868          term
 869        end
 870      }.flatten
 871    
 872      tk_send 'write', file, *args
 873    end
 874  end