File: tk/menu.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Tk
  class: Menu#46
extends
  TkMenuSpec   
includes
  TkMenuEntryConfig   
  Wm ( Tk )
inherits from
  TkWindow   
has properties
constant: TkCommandNames #51
constant: WidgetClassName #52
method: __strval_optkeys #64
method: __boolval_optkeys #69
class method: new_menuspec / 4 #74
method: tagid / 1 #92
method: activate / 1 #97
method: add / 2 #101
method: add_cascade / 1 #105
method: add_checkbutton / 1 #108
method: add_command / 1 #111
method: add_radiobutton / 1 #114
method: add_separator / 1 #117
method: clone_menu / 1 #121
method: index / 1 #150
method: invoke / 1 #154
method: insert / 3 #157
method: delete / 2 #162
method: popup / 3 #171
method: post / 2 #180
method: postcascade / 1 #183
method: postcommand / 1 #187
method: set_focus #191
method: tearoffcommand / 1 #195
method: menutype / 1 #199
method: unpost #202
method: xposition / 1 #206
method: yposition / 1 #209
  class: MenuClone#392
inherits from
  Menu ( Tk )
has properties
method: initialize / 2 #410
method: source_menu #442
  module: SystemMenu#451
has properties
method: initialize / 2 #452
  class: SysMenu_Help#477
includes
  SystemMenu ( Tk )
inherits from
  Menu ( Tk )
has properties
constant: SYSMENU_NAME #480
  class: SysMenu_System#486
includes
  SystemMenu ( Tk )
inherits from
  Menu ( Tk )
has properties
constant: SYSMENU_NAME #489
  class: SysMenu_Apple#495
includes
  SystemMenu ( Tk )
inherits from
  Menu ( Tk )
has properties
constant: SYSMENU_NAME #498
  class: Menubutton#504
inherits from
  Label ( Tk )
has properties
constant: TkCommandNames #505
constant: WidgetClassName #506
method: create_self / 1 #508
method: __boolval_optkeys #535
  class: OptionMenubutton#547
inherits from
  Menubutton ( Tk )
has properties
constant: TkCommandNames #548
method: initialize / 1 #558
method: value #602
method: value= / 1 #606
method: activate / 1 #610
method: add / 1 #614
method: index / 1 #619
method: invoke / 1 #622
method: insert / 2 #625
method: delete / 2 #630
method: xposition / 1 #634
method: yposition / 1 #637
method: menu #640
method: menucget / 1 #643
method: menucget_strict / 1 #646
method: menuconfigure / 2 #649
method: menuconfiginfo / 1 #653
method: current_menuconfiginfo / 1 #656
method: entrycget / 2 #659
method: entrycget_strict / 2 #662
method: entryconfigure / 3 #665
method: entryconfiginfo / 2 #669
method: current_entryconfiginfo / 2 #672
  class: OptionMenu#550
inherits from
  TkMenu   
has properties
method: initialize / 1 #551
  module: TkMenuEntryConfig#8
includes
  TkItemConfigMethod   
has properties
method: __item_cget_cmd / 1 #11
method: __item_config_cmd / 1 #16
method: __item_strval_optkeys / 1 #21
method: __item_listval_optkeys / 1 #26
method: __item_val2ruby_optkeys / 1 #31
alias: entrycget itemcget #36
alias: entrycget_strict itemcget_strict #37
alias: entryconfigure itemconfigure #38
alias: entryconfiginfo itemconfiginfo #39
alias: current_entryconfiginfo current_itemconfiginfo #40

Class Hierarchy

Object ( Builtin-Module )
TkKernel
TkObject
TkWindow
Label ( Tk )
Menubutton ( Tk ) — #504
  OptionMenubutton    #547
Menu ( Tk ) — #46
  MenuClone    #392
  SysMenu_Help    #477
  SysMenu_System    #486
  SysMenu_Apple    #495
TkMenu

Code

   1  #
   2  # tk/menu.rb : treat menu and menubutton
   3  #
   4  require 'tk'
   5  require 'tk/itemconfig'
   6  require 'tk/menuspec'
   7 
   8  module TkMenuEntryConfig
   9    include TkItemConfigMethod
  10 
  11    def __item_cget_cmd(id)
  12      [self.path, 'entrycget', id]
  13    end
  14    private :__item_cget_cmd
  15 
  16    def __item_config_cmd(id)
  17      [self.path, 'entryconfigure', id]
  18    end
  19    private :__item_config_cmd
  20 
  21    def __item_strval_optkeys(id)
  22      super(id) << 'selectcolor'
  23    end
  24    private :__item_strval_optkeys
  25 
  26    def __item_listval_optkeys(id)
  27      []
  28    end
  29    private :__item_listval_optkeys
  30 
  31    def __item_val2ruby_optkeys(id)  # { key=>proc, ... }
  32      super(id).update('menu'=>proc{|i, v| window(v)})
  33    end
  34    private :__item_val2ruby_optkeys
  35 
  36    alias entrycget itemcget
  37    alias entrycget_strict itemcget_strict
  38    alias entryconfigure itemconfigure
  39    alias entryconfiginfo itemconfiginfo
  40    alias current_entryconfiginfo current_itemconfiginfo
  41 
  42    private :itemcget, :itemcget_strict
  43    private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
  44  end
  45 
  46  class Tk::Menu<TkWindow
  47    include Wm
  48    include TkMenuEntryConfig
  49    extend TkMenuSpec
  50 
  51    TkCommandNames = ['menu'.freeze].freeze
  52    WidgetClassName = 'Menu'.freeze
  53    WidgetClassNames[WidgetClassName] = self
  54 
  55    #def create_self(keys)
  56    #  if keys and keys != None
  57    #    tk_call_without_enc('menu', @path, *hash_kv(keys, true))
  58    #  else
  59    #    tk_call_without_enc('menu', @path)
  60    #  end
  61    #end
  62    #private :create_self
  63 
  64    def __strval_optkeys
  65      super() << 'selectcolor' << 'title'
  66    end
  67    private :__strval_optkeys
  68 
  69    def __boolval_optkeys
  70      super() << 'tearoff'
  71    end
  72    private :__boolval_optkeys
  73 
  74    def self.new_menuspec(menu_spec, parent = nil, tearoff = false, keys = nil)
  75      if parent.kind_of?(Hash)
  76        keys = _symbolkey2str(parent)
  77        parent = keys.delete('parent')
  78        tearoff = keys.delete('tearoff')
  79      elsif tearoff.kind_of?(Hash)
  80        keys = _symbolkey2str(tearoff)
  81        tearoff = keys.delete('tearoff')
  82      elsif keys
  83        keys = _symbolkey2str(keys)
  84      else
  85        keys = {}
  86      end
  87 
  88      widgetname = keys.delete('widgetname')
  89      _create_menu(parent, menu_spec, widgetname, tearoff, keys)
  90    end
  91 
  92    def tagid(id)
  93      #id.to_s
  94      _get_eval_string(id)
  95    end
  96 
  97    def activate(index)
  98      tk_send_without_enc('activate', _get_eval_enc_str(index))
  99      self
 100    end
 101    def add(type, keys=nil)
 102      tk_send_without_enc('add', type, *hash_kv(keys, true))
 103      self
 104    end
 105    def add_cascade(keys=nil)
 106      add('cascade', keys)
 107    end
 108    def add_checkbutton(keys=nil)
 109      add('checkbutton', keys)
 110    end
 111    def add_command(keys=nil)
 112      add('command', keys)
 113    end
 114    def add_radiobutton(keys=nil)
 115      add('radiobutton', keys)
 116    end
 117    def add_separator(keys=nil)
 118      add('separator', keys)
 119    end
 120 
 121    def clone_menu(*args)
 122      if args[0].kind_of?(TkWindow)
 123        parent = args.shift
 124      else
 125        parent = self
 126      end
 127 
 128      if args[0].kind_of?(String) || args[0].kind_of?(Symbol) # menu type
 129        type = args.shift
 130      else
 131        type = None # 'normal'
 132      end
 133 
 134      if args[0].kind_of?(Hash)
 135        keys = _symbolkey2str(args.shift)
 136      else
 137        keys = {}
 138      end
 139 
 140      parent = keys.delete('parent') if keys.has_key?('parent')
 141      type = keys.delete('type') if keys.has_key?('type')
 142 
 143      if keys.empty?
 144        Tk::MenuClone.new(self, parent, type)
 145      else
 146        Tk::MenuClone.new(self, parent, type, keys)
 147      end
 148    end
 149 
 150    def index(idx)
 151      ret = tk_send_without_enc('index', _get_eval_enc_str(idx))
 152      (ret == 'none')? nil: number(ret)
 153    end
 154    def invoke(index)
 155      _fromUTF8(tk_send_without_enc('invoke', _get_eval_enc_str(index)))
 156    end
 157    def insert(index, type, keys=nil)
 158      tk_send_without_enc('insert', _get_eval_enc_str(index), 
 159                          type, *hash_kv(keys, true))
 160      self
 161    end
 162    def delete(first, last=nil)
 163      if last
 164        tk_send_without_enc('delete', _get_eval_enc_str(first), 
 165                            _get_eval_enc_str(last))
 166      else
 167        tk_send_without_enc('delete', _get_eval_enc_str(first))
 168      end
 169      self
 170    end
 171    def popup(x, y, index=nil)
 172      if index
 173        tk_call_without_enc('tk_popup', path, x, y, 
 174                            _get_eval_enc_str(index))
 175      else
 176        tk_call_without_enc('tk_popup', path, x, y)
 177      end
 178      self
 179    end
 180    def post(x, y)
 181      _fromUTF8(tk_send_without_enc('post', x, y))
 182    end
 183    def postcascade(index)
 184      tk_send_without_enc('postcascade', _get_eval_enc_str(index))
 185      self
 186    end
 187    def postcommand(cmd=Proc.new)
 188      configure_cmd 'postcommand', cmd
 189      self
 190    end
 191    def set_focus
 192      tk_call_without_enc('tk_menuSetFocus', path)
 193      self
 194    end
 195    def tearoffcommand(cmd=Proc.new)
 196      configure_cmd 'tearoffcommand', cmd
 197      self
 198    end
 199    def menutype(index)
 200      tk_send_without_enc('type', _get_eval_enc_str(index))
 201    end
 202    def unpost
 203      tk_send_without_enc('unpost')
 204      self
 205    end
 206    def xposition(index)
 207      number(tk_send_without_enc('xposition', _get_eval_enc_str(index)))
 208    end
 209    def yposition(index)
 210      number(tk_send_without_enc('yposition', _get_eval_enc_str(index)))
 211    end
 212 
 213  =begin
 214    def entrycget(index, key)
 215      case key.to_s
 216      when 'text', 'label', 'show'
 217        _fromUTF8(tk_send_without_enc('entrycget', 
 218                                      _get_eval_enc_str(index), "-#{key}"))
 219      when 'font', 'kanjifont'
 220        #fnt = tk_tcl2ruby(tk_send('entrycget', index, "-#{key}"))
 221        fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), '-font')))
 222        unless fnt.kind_of?(TkFont)
 223          fnt = tagfontobj(index, fnt)
 224        end
 225        if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/
 226          # obsolete; just for compatibility
 227          fnt.kanji_font
 228        else
 229          fnt
 230        end
 231      else
 232        tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), "-#{key}")))
 233      end
 234    end
 235    def entryconfigure(index, key, val=None)
 236      if key.kind_of? Hash
 237        if (key['font'] || key[:font] || 
 238            key['kanjifont'] || key[:kanjifont] || 
 239            key['latinfont'] || key[:latinfont] || 
 240            key['asciifont'] || key[:asciifont])
 241          tagfont_configure(index, _symbolkey2str(key))
 242        else
 243          tk_send_without_enc('entryconfigure', _get_eval_enc_str(index), 
 244                              *hash_kv(key, true))
 245        end
 246 
 247      else
 248        if (key == 'font' || key == :font || 
 249            key == 'kanjifont' || key == :kanjifont || 
 250            key == 'latinfont' || key == :latinfont || 
 251            key == 'asciifont' || key == :asciifont )
 252          if val == None
 253            tagfontobj(index)
 254          else
 255            tagfont_configure(index, {key=>val})
 256          end
 257        else
 258          tk_call('entryconfigure', index, "-#{key}", val)
 259        end
 260      end
 261      self
 262    end
 263 
 264    def entryconfiginfo(index, key=nil)
 265      if TkComm::GET_CONFIGINFO_AS_ARRAY
 266        if key
 267          case key.to_s
 268          when 'text', 'label', 'show'
 269            conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}")))
 270          when 'font', 'kanjifont'
 271            conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}")))
 272            conf[4] = tagfont_configinfo(index, conf[4])
 273          else
 274            conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}")))
 275          end
 276          conf[0] = conf[0][1..-1]
 277          conf
 278        else
 279          ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).collect{|conflist|
 280            conf = tk_split_simplelist(conflist)
 281            conf[0] = conf[0][1..-1]
 282            case conf[0]
 283            when 'text', 'label', 'show'
 284            else
 285              if conf[3]
 286                if conf[3].index('{')
 287                  conf[3] = tk_split_list(conf[3]) 
 288                else
 289                  conf[3] = tk_tcl2ruby(conf[3]) 
 290                end
 291              end
 292              if conf[4]
 293                if conf[4].index('{')
 294                  conf[4] = tk_split_list(conf[4]) 
 295                else
 296                  conf[4] = tk_tcl2ruby(conf[4]) 
 297                end
 298              end
 299            end
 300            conf[1] = conf[1][1..-1] if conf.size == 2 # alias info
 301            conf
 302          }
 303          if fontconf
 304            ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
 305            fontconf[4] = tagfont_configinfo(index, fontconf[4])
 306            ret.push(fontconf)
 307          else
 308            ret
 309          end
 310        end
 311      else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
 312        if key
 313          case key.to_s
 314          when 'text', 'label', 'show'
 315            conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}")))
 316          when 'font', 'kanjifont'
 317            conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}")))
 318            conf[4] = tagfont_configinfo(index, conf[4])
 319          else
 320            conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}")))
 321          end
 322          key = conf.shift[1..-1]
 323          { key => conf }
 324        else
 325          ret = {}
 326          tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).each{|conflist|
 327            conf = tk_split_simplelist(conflist)
 328            key = conf.shift[1..-1]
 329            case key
 330            when 'text', 'label', 'show'
 331            else
 332              if conf[2]
 333                if conf[2].index('{')
 334                  conf[2] = tk_split_list(conf[2]) 
 335                else
 336                  conf[2] = tk_tcl2ruby(conf[2]) 
 337                end
 338              end
 339              if conf[3]
 340                if conf[3].index('{')
 341                  conf[3] = tk_split_list(conf[3]) 
 342                else
 343                  conf[3] = tk_tcl2ruby(conf[3]) 
 344                end
 345              end
 346            end
 347            if conf.size == 1
 348              ret[key] = conf[0][1..-1]  # alias info
 349            else
 350              ret[key] = conf
 351            end
 352          }
 353          fontconf = ret['font']
 354          if fontconf
 355            ret.delete('font')
 356            ret.delete('kanjifont')
 357            fontconf[3] = tagfont_configinfo(index, fontconf[3])
 358            ret['font'] = fontconf
 359          end
 360          ret
 361        end
 362      end
 363    end
 364 
 365    def current_entryconfiginfo(index, key=nil)
 366      if TkComm::GET_CONFIGINFO_AS_ARRAY
 367        if key
 368          conf = entryconfiginfo(index, key)
 369          {conf[0] => conf[4]}
 370        else
 371          ret = {}
 372          entryconfiginfo(index).each{|conf|
 373            ret[conf[0]] = conf[4] if conf.size > 2
 374          }
 375          ret
 376        end
 377      else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
 378        ret = {}
 379        entryconfiginfo(index, key).each{|k, conf|
 380          ret[k] = conf[-1] if conf.kind_of?(Array)
 381        }
 382        ret
 383      end
 384    end
 385  =end
 386  end
 387 
 388  #TkMenu = Tk::Menu unless Object.const_defined? :TkMenu
 389  Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
 390 
 391 
 392  class Tk::MenuClone<Tk::Menu
 393  =begin
 394    def initialize(parent, type=None)
 395      widgetname = nil
 396      if parent.kind_of? Hash
 397        keys = _symbolkey2str(parent)
 398        parent = keys.delete('parent')
 399        widgetname = keys.delete('widgetname')
 400        type = keys.delete('type'); type = None unless type
 401      end
 402      #unless parent.kind_of?(TkMenu)
 403      #  fail ArgumentError, "parent must be TkMenu"
 404      #end
 405      @parent = parent
 406      install_win(@parent.path, widgetname)
 407      tk_call_without_enc(@parent.path, 'clone', @path, type)
 408    end
 409  =end
 410    def initialize(src_menu, *args)
 411      widgetname = nil
 412 
 413      if args[0].kind_of?(TkWindow)  # parent window
 414        parent = args.shift
 415      else
 416        parent = src_menu
 417      end
 418 
 419      if args[0].kind_of?(String) || args[0].kind_of?(Symbol)  # menu type
 420        type = args.shift
 421      else
 422        type = None  # 'normal'
 423      end
 424 
 425      if args[0].kind_of?(Hash)
 426        keys = _symbolkey2str(args.shift)
 427        parent = keys.delete('parent') if keys.has_key?('parent')
 428        widgetname = keys.delete('widgetname')
 429        type = keys.delete('type') if keys.has_key?('type')
 430      else
 431        keys = nil
 432      end
 433 
 434      @src_menu = src_menu
 435      @parent = parent
 436      @type = type
 437      install_win(@parent.path, widgetname)
 438      tk_call_without_enc(@src_menu.path, 'clone', @path, @type)
 439      configure(keys) if keys && !keys.empty?
 440    end
 441 
 442    def source_menu
 443      @src_menu
 444    end
 445  end
 446  Tk::CloneMenu = Tk::MenuClone
 447  #TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone
 448  #TkCloneMenu = Tk::CloneMenu unless Object.const_defined? :TkCloneMenu
 449  Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)
 450 
 451  module Tk::SystemMenu
 452    def initialize(parent, keys=nil)
 453      if parent.kind_of? Hash
 454        keys = _symbolkey2str(parent)
 455        parent = keys.delete('parent')
 456      end
 457      #unless parent.kind_of? TkMenu
 458      #  fail ArgumentError, "parent must be a TkMenu object"
 459      #end
 460      # @path = Kernel.format("%s.%s", parent.path, self.class::SYSMENU_NAME)
 461      @path = parent.path + '.' + self.class::SYSMENU_NAME
 462      #TkComm::Tk_WINDOWS[@path] = self
 463      TkCore::INTERP.tk_windows[@path] = self
 464      if self.method(:create_self).arity == 0
 465        p 'create_self has no arg' if $DEBUG
 466        create_self
 467        configure(keys) if keys
 468      else
 469        p 'create_self has an arg' if $DEBUG
 470        create_self(keys)
 471      end
 472    end
 473  end
 474  TkSystemMenu = Tk::SystemMenu
 475 
 476 
 477  class Tk::SysMenu_Help<Tk::Menu
 478    # for all platform
 479    include Tk::SystemMenu
 480    SYSMENU_NAME = 'help'
 481  end
 482  #TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help
 483  Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
 484 
 485 
 486  class Tk::SysMenu_System<Tk::Menu
 487    # for Windows
 488    include Tk::SystemMenu
 489    SYSMENU_NAME = 'system'
 490  end
 491  #TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System
 492  Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
 493 
 494 
 495  class Tk::SysMenu_Apple<Tk::Menu
 496    # for Machintosh
 497    include Tk::SystemMenu
 498    SYSMENU_NAME = 'apple'
 499  end
 500  #TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple
 501  Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
 502 
 503 
 504  class Tk::Menubutton<Tk::Label
 505    TkCommandNames = ['menubutton'.freeze].freeze
 506    WidgetClassName = 'Menubutton'.freeze
 507    WidgetClassNames[WidgetClassName] = self
 508    def create_self(keys)
 509      if keys and keys != None
 510        unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
 511          # tk_call_without_enc('menubutton', @path, *hash_kv(keys, true))
 512          tk_call_without_enc(self.class::TkCommandNames[0], @path, 
 513                              *hash_kv(keys, true))
 514        else
 515          begin
 516            tk_call_without_enc(self.class::TkCommandNames[0], @path, 
 517                                *hash_kv(keys, true))
 518          rescue
 519            tk_call_without_enc(self.class::TkCommandNames[0], @path)
 520            keys = __check_available_configure_options(keys)
 521            unless keys.empty?
 522              tk_call_without_enc('destroy', @path) rescue nil
 523              tk_call_without_enc(self.class::TkCommandNames[0], @path, 
 524                                  *hash_kv(keys, true))
 525            end
 526          end
 527        end
 528      else
 529        # tk_call_without_enc('menubutton', @path)
 530        tk_call_without_enc(self.class::TkCommandNames[0], @path)
 531      end
 532    end
 533    private :create_self
 534 
 535    def __boolval_optkeys
 536      super() << 'indicatoron'
 537    end
 538    private :__boolval_optkeys
 539 
 540  end
 541  Tk::MenuButton = Tk::Menubutton
 542  #TkMenubutton = Tk::Menubutton unless Object.const_defined? :TkMenubutton
 543  #TkMenuButton = Tk::MenuButton unless Object.const_defined? :TkMenuButton
 544  Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)
 545 
 546 
 547  class Tk::OptionMenubutton<Tk::Menubutton
 548    TkCommandNames = ['tk_optionMenu'.freeze].freeze
 549 
 550    class OptionMenu<TkMenu
 551      def initialize(path)  #==> return value of tk_optionMenu
 552        @path = path
 553        #TkComm::Tk_WINDOWS[@path] = self
 554        TkCore::INTERP.tk_windows[@path] = self
 555      end
 556    end
 557 
 558    def initialize(*args)
 559      # args :: [parent,] [var,] [value[, ...],] [keys]
 560      #    parent --> TkWindow or nil
 561      #    var    --> TkVariable or nil
 562      #    keys   --> Hash
 563      #       keys[:parent] or keys['parent']     --> parent
 564      #       keys[:variable] or keys['variable'] --> var
 565      #       keys[:values] or keys['values']     --> value, ...
 566      #       other Hash keys are menubutton options
 567      keys = {}
 568      keys = args.pop if args[-1].kind_of?(Hash)
 569      keys = _symbolkey2str(keys)
 570 
 571      parent = nil
 572      if args[0].kind_of?(TkWindow) || args[0] == nil
 573        keys.delete('parent') # ignore
 574        parent = args.shift 
 575      else
 576        parent = keys.delete('parent')
 577      end
 578 
 579      @variable = nil
 580      if args[0].kind_of?(TkVariable) || args[0] == nil
 581        keys.delete('variable') # ignore
 582        @variable = args.shift 
 583      else
 584        @variable = keys.delete('variable')
 585      end
 586      @variable = TkVariable.new unless @variable
 587 
 588      (args = keys.delete('values') || []) if args.empty?
 589      if args.empty?
 590        args << @variable.value
 591      else
 592        @variable.value = args[0]
 593      end
 594 
 595      install_win(if parent then parent.path end)
 596      @menu = OptionMenu.new(tk_call('tk_optionMenu', 
 597                                     @path, @variable.id, *args))
 598 
 599      configure(keys) if keys
 600    end
 601 
 602    def value
 603      @variable.value
 604    end
 605 
 606    def value=(val)
 607      @variable.value = val
 608    end
 609 
 610    def activate(index)
 611      @menu.activate(index)
 612      self
 613    end
 614    def add(value)
 615      @menu.add('radiobutton', 'variable'=>@variable, 
 616                'label'=>value, 'value'=>value)
 617      self
 618    end
 619    def index(index)
 620      @menu.index(index)
 621    end
 622    def invoke(index)
 623      @menu.invoke(index)
 624    end
 625    def insert(index, value)
 626      @menu.insert(index, 'radiobutton', 'variable'=>@variable, 
 627                'label'=>value, 'value'=>value)
 628      self
 629    end
 630    def delete(index, last=None)
 631      @menu.delete(index, last)
 632      self
 633    end
 634    def xposition(index)
 635      @menu.xposition(index)
 636    end
 637    def yposition(index)
 638      @menu.yposition(index)
 639    end
 640    def menu
 641      @menu
 642    end
 643    def menucget(key)
 644      @menu.cget(key)
 645    end
 646    def menucget_strict(key)
 647      @menu.cget_strict(key)
 648    end
 649    def menuconfigure(key, val=None)
 650      @menu.configure(key, val)
 651      self
 652    end
 653    def menuconfiginfo(key=nil)
 654      @menu.configinfo(key)
 655    end
 656    def current_menuconfiginfo(key=nil)
 657      @menu.current_configinfo(key)
 658    end
 659    def entrycget(index, key)
 660      @menu.entrycget(index, key)
 661    end
 662    def entrycget_strict(index, key)
 663      @menu.entrycget_strict(index, key)
 664    end
 665    def entryconfigure(index, key, val=None)
 666      @menu.entryconfigure(index, key, val)
 667      self
 668    end
 669    def entryconfiginfo(index, key=nil)
 670      @menu.entryconfiginfo(index, key)
 671    end
 672    def current_entryconfiginfo(index, key=nil)
 673      @menu.current_entryconfiginfo(index, key)
 674    end
 675  end
 676 
 677  Tk::OptionMenuButton = Tk::OptionMenubutton
 678  #TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton
 679  #TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton
 680  Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton, 
 681                              :TkOptionMenubutton, :TkOptionMenuButton)