平松です。

[ruby-list:16048]で原田さんが、menu_specを使って

[hoge]----[hoge1]
       |--[hoge2]---[submenu1]
       |          |-[submenu2]

といったメニュー階層を作りたいと発言していました。これが気になっていた
ので、tkmenubar.rbを真似して「仕事の間の気晴らしに」作ってみました。

# って、原田さんにはもう遅いですか……。

$file = [['Open', proc{puts 'open'}, {'underline' => '0', 'foregrount'=>'blue'}],
         ['Save', proc{puts 'save'}, {'accelerator' => 'Ctrl+S'}],
         '---',
         ['Quit', proc{exit}]]

$manual = [['Tutorial', proc{puts 'tutorial'}],
           ['User Guide', proc{puts 'user guide'}],
           ['Reference', proc{puts 'reference'}]]
$help = [['Manual', $manual],
         ['About', proc{puts 'about'}]]

add_menu [['File', $file, {'underline' => 0}], ['Help', $help]], {'tearoff'=>false}

のようにすると、トップレベルのウィンドウにサブメニューを持ったメニュー
バーが付きます。以下がその add_menu 関数のソースです。Tcl/Tkのバージョ
ン8.0以上でないと動かないと思います。

def make_menu(menu_info, parent, args)
  menu = TkMenu.new(parent, args)
  for m in menu_info
    if m[1].kind_of?(Array)
      options = Hash.new
      options['label'] = m[0]
      options['menu'] = make_menu(m[1], menu, args)
      options.update(m[2]) if m[2]
      menu.add('cascade', options)
    elsif m[1].kind_of?(Proc)
      options = Hash.new
      options['label'] = m[0]
      options['command'] = m[1]
      options.update(m[2]) if m[2]
      menu.add('command', options)
    elsif /^-+$/ =~ m
      menu.add('separator')
    else
      menu.add('command', 'label' => m)
    end
  end    
  return menu
end

def add_menu(menu_info, option = nil)
  root = Tk.root
  mbar = make_menu menu_info, root, option
  root.configure 'menu', mbar
end

-- 
// Linux Japan編集部
// 平松祥史(Hiramatsu, Yoshifumi) Mail: hiramatsu / linuxjapan.com
// 〒101-0021 東京都千代田区外神田5-6-12 コーワビル3 3階 
// Tel: 03-5818-6608   Fax: 03-5818-6613