mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
This commit was manufactured by cvs2svn to create branch 'ruby_1_8'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7050e0c745
commit
84bca111f8
3 changed files with 350 additions and 0 deletions
243
ext/tk/lib/tk/menuspec.rb
Normal file
243
ext/tk/lib/tk/menuspec.rb
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
#
|
||||||
|
# tk/menuspec.rb
|
||||||
|
# Hidethoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||||
|
#
|
||||||
|
# based on tkmenubar.rb :
|
||||||
|
# Copyright (C) 1998 maeda shugo. All rights reserved.
|
||||||
|
# This file can be distributed under the terms of the Ruby.
|
||||||
|
#
|
||||||
|
# The format of the menu_spec is:
|
||||||
|
# [ menu_info, menu_info, ... ]
|
||||||
|
#
|
||||||
|
# And the format of the menu_info is:
|
||||||
|
# [
|
||||||
|
# [text, underline, configs], # menu button/entry (*1)
|
||||||
|
# [label, command, underline, accelerator, configs], # command entry
|
||||||
|
# [label, TkVar_obj, underline, accelerator, configs], # checkbutton entry
|
||||||
|
# [label, [TkVar_obj, value],
|
||||||
|
# underline, accelerator, configs], # radiobutton entry
|
||||||
|
# [label, [[...menu_info...], [...menu_info...], ...],
|
||||||
|
# underline, accelerator, configs], # cascade entry
|
||||||
|
# '---', # separator
|
||||||
|
# ...
|
||||||
|
# ]
|
||||||
|
#
|
||||||
|
# underline, accelerator, and configs are optional pearameters.
|
||||||
|
# Hashes are OK instead of Arrays. Then the entry type ('command',
|
||||||
|
# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key
|
||||||
|
# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info
|
||||||
|
# is acceptable for 'menu' key (then, create sub-menu).
|
||||||
|
#
|
||||||
|
# NOTE: (*1)
|
||||||
|
# If you want to make special menus (*.help for UNIX, *.system for Win,
|
||||||
|
# and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX,
|
||||||
|
# 'system' for Win, and 'apple' for Mac) option to the configs hash of
|
||||||
|
# menu button/entry information.
|
||||||
|
|
||||||
|
module TkMenuSpec
|
||||||
|
def _create_menu(parent, menu_info, menu_name = nil,
|
||||||
|
tearoff = false, default_opts = nil)
|
||||||
|
if tearoff.kind_of?(Hash)
|
||||||
|
default_opts = tearoff
|
||||||
|
tearoff = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if menu_name.kind_of?(Hash)
|
||||||
|
default_opts = menu_name
|
||||||
|
menu_name = nil
|
||||||
|
tearoff = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if default_opts.kind_of?(Hash)
|
||||||
|
orig_opts = _symbolkey2str(default_opts)
|
||||||
|
else
|
||||||
|
orig_opts = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')
|
||||||
|
|
||||||
|
if menu_name
|
||||||
|
menu = TkMenu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
|
||||||
|
else
|
||||||
|
menu = TkMenu.new(parent, :tearoff=>tearoff)
|
||||||
|
end
|
||||||
|
|
||||||
|
for item_info in menu_info
|
||||||
|
if item_info.kind_of?(Hash)
|
||||||
|
options = orig_opts.dup
|
||||||
|
options.update(_symbolkey2str(item_info))
|
||||||
|
item_type = (options.delete('type') || 'command').to_s
|
||||||
|
menu_name = options.delete('menu_name')
|
||||||
|
menu_opts = orig_opts.dup
|
||||||
|
menu_opts.update(_symbolkey2str(options.delete('menu_config') || {}))
|
||||||
|
if item_type == 'cascade' && options['menu'].kind_of?(Array)
|
||||||
|
# create cascade menu
|
||||||
|
submenu = _create_menu(menu, options['menu'], menu_name,
|
||||||
|
tearoff, menu_opts)
|
||||||
|
options['menu'] = submenu
|
||||||
|
end
|
||||||
|
menu.add(item_type, options)
|
||||||
|
|
||||||
|
elsif item_info.kind_of?(Array)
|
||||||
|
options = orig_opts.dup
|
||||||
|
|
||||||
|
options['label'] = item_info[0] if item_info[0]
|
||||||
|
|
||||||
|
case item_info[1]
|
||||||
|
when TkVariable
|
||||||
|
# checkbutton
|
||||||
|
item_type = 'checkbutton'
|
||||||
|
options['variable'] = item_info[1]
|
||||||
|
options['onvalue'] = true
|
||||||
|
options['offvalue'] = false
|
||||||
|
|
||||||
|
when Array
|
||||||
|
# radiobutton or cascade
|
||||||
|
if item_info[1][0].kind_of?(TkVariable)
|
||||||
|
# radiobutton
|
||||||
|
item_type = 'radiobutton'
|
||||||
|
options['variable'] = item_info[1][0]
|
||||||
|
options['value'] = item_info[1][1] if item_info[1][1]
|
||||||
|
|
||||||
|
else
|
||||||
|
# cascade
|
||||||
|
item_type = 'cascade'
|
||||||
|
menu_opts = orig_opts.dup
|
||||||
|
if item_info[4] && item_info[4].kind_of?(Hash)
|
||||||
|
opts = _symbolkey2str(item_info[4])
|
||||||
|
menu_name = opts.delete('menu_name')
|
||||||
|
menu_config = opts.delete('menu_config') || {}
|
||||||
|
menu_opts.update(_symbolkey2str(menu_config))
|
||||||
|
end
|
||||||
|
submenu = _create_menu(menu, item_info[1], menu_name,
|
||||||
|
tearoff, menu_opts)
|
||||||
|
options['menu'] = submenu
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
# command
|
||||||
|
item_type = 'command'
|
||||||
|
options['command'] = item_info[1] if item_info[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
options['underline'] = item_info[2] if item_info[2]
|
||||||
|
options['accelerator'] = item_info[3] if item_info[3]
|
||||||
|
if item_info[4] && item_info[4].kind_of?(Hash)
|
||||||
|
opts = _symbolkey2str(item_info[4])
|
||||||
|
if item_type == 'cascade'
|
||||||
|
opts.delete('menu_name')
|
||||||
|
opts.delete('menu_config')
|
||||||
|
end
|
||||||
|
options.update(opts)
|
||||||
|
end
|
||||||
|
menu.add(item_type, options)
|
||||||
|
|
||||||
|
elsif /^-+$/ =~ item_info
|
||||||
|
menu.add('separator')
|
||||||
|
|
||||||
|
else
|
||||||
|
menu.add('command', 'label' => item_info)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
menu
|
||||||
|
end
|
||||||
|
private :_create_menu
|
||||||
|
|
||||||
|
def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil)
|
||||||
|
btn_info = menu_info[0]
|
||||||
|
|
||||||
|
if tearoff.kind_of?(Hash)
|
||||||
|
default_opts = tearoff
|
||||||
|
tearoff = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if default_opts.kind_of?(Hash)
|
||||||
|
keys = _symbolkey2str(default_opts)
|
||||||
|
else
|
||||||
|
keys = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
tearoff = keys.delete('tearoff') if keys.key?('tearoff')
|
||||||
|
|
||||||
|
if parent.kind_of?(TkRoot) || parent.kind_of?(TkToplevel)
|
||||||
|
# menubar by menu entries
|
||||||
|
unless (mbar = parent.menu).kind_of?(TkMenu)
|
||||||
|
mbar = TkMenu.new(parent, :tearoff=>false)
|
||||||
|
parent.menu(mbar)
|
||||||
|
end
|
||||||
|
|
||||||
|
menu_name = nil
|
||||||
|
|
||||||
|
if btn_info.kind_of?(Hash)
|
||||||
|
keys.update(_symbolkey2str(btn_info))
|
||||||
|
menu_name = keys.delete('menu_name')
|
||||||
|
keys['label'] = keys.delete('text') if keys.key?('text')
|
||||||
|
elsif btn_info.kind_of?(Array)
|
||||||
|
keys['label'] = btn_info[0] if btn_info[0]
|
||||||
|
keys['underline'] = btn_info[1] if btn_info[1]
|
||||||
|
if btn_info[2]&&btn_info[2].kind_of?(Hash)
|
||||||
|
keys.update(_symbolkey2str(btn_info[2]))
|
||||||
|
menu_name = keys.delete('menu_name')
|
||||||
|
end
|
||||||
|
else
|
||||||
|
keys = {:label=>btn_info}
|
||||||
|
end
|
||||||
|
|
||||||
|
menu = _create_menu(mbar, menu_info[1..-1], menu_name,
|
||||||
|
tearoff, default_opts)
|
||||||
|
menu.tearoff(tearoff)
|
||||||
|
|
||||||
|
keys['menu'] = menu
|
||||||
|
mbar.add('cascade', keys)
|
||||||
|
|
||||||
|
[mbar, menu]
|
||||||
|
|
||||||
|
else
|
||||||
|
# menubar by menubuttons
|
||||||
|
mbtn = TkMenubutton.new(parent)
|
||||||
|
|
||||||
|
menu_name = nil
|
||||||
|
|
||||||
|
if btn_info.kind_of?(Hash)
|
||||||
|
keys.update(_symbolkey2str(btn_info))
|
||||||
|
menu_name = keys.delete('menu_name')
|
||||||
|
keys['text'] = keys.delete('label') if keys.key?('label')
|
||||||
|
mbtn.configure(keys)
|
||||||
|
elsif btn_info.kind_of?(Array)
|
||||||
|
mbtn.configure('text', btn_info[0]) if btn_info[0]
|
||||||
|
mbtn.configure('underline', btn_info[1]) if btn_info[1]
|
||||||
|
# mbtn.configure('accelerator', btn_info[2]) if btn_info[2]
|
||||||
|
if btn_info[2]&&btn_info[2].kind_of?(Hash)
|
||||||
|
keys.update(_symbolkey2str(btn_info[2]))
|
||||||
|
menu_name = keys.delete('menu_name')
|
||||||
|
mbtn.configure(keys)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
mbtn.configure('text', btn_info)
|
||||||
|
end
|
||||||
|
|
||||||
|
mbtn.pack('side' => 'left')
|
||||||
|
|
||||||
|
menu = _create_menu(mbtn, menu_info[1..-1], menu_name,
|
||||||
|
tearoff, default_opts)
|
||||||
|
|
||||||
|
mbtn.menu(menu)
|
||||||
|
|
||||||
|
[mbtn, menu]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :_create_menubutton
|
||||||
|
|
||||||
|
def _get_cascade_menus(menu)
|
||||||
|
menus = []
|
||||||
|
(0..(menu.index('last'))).each{|idx|
|
||||||
|
if menu.menutype(idx) == 'cascade'
|
||||||
|
submenu = menu.entrycget(idx, 'menu')
|
||||||
|
menus << [submenu, _get_cascade_menus(submenu)]
|
||||||
|
end
|
||||||
|
}
|
||||||
|
menus
|
||||||
|
end
|
||||||
|
private :_get_cascade_menus
|
||||||
|
end
|
51
ext/tk/sample/menubar1.rb
Normal file
51
ext/tk/sample/menubar1.rb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#
|
||||||
|
# menubar sample 1 : use frame and menubuttons
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'tk'
|
||||||
|
|
||||||
|
radio_var = TkVariable.new('y')
|
||||||
|
|
||||||
|
menu_spec = [
|
||||||
|
[['File', 0],
|
||||||
|
{:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0},
|
||||||
|
'---',
|
||||||
|
['Check_A', TkVariable.new(true), 6],
|
||||||
|
{:type=>'checkbutton', :label=>'Check_B',
|
||||||
|
:variable=>TkVariable.new, :underline=>6},
|
||||||
|
'---',
|
||||||
|
['Radio_X', [radio_var, 'x'], 6, '', {:foreground=>'black'}],
|
||||||
|
['Radio_Y', [radio_var, 'y'], 6],
|
||||||
|
['Radio_Z', [radio_var, 'z'], 6],
|
||||||
|
'---',
|
||||||
|
['cascade', [
|
||||||
|
['sss', proc{p 'sss'}, 0],
|
||||||
|
['ttt', proc{p 'ttt'}, 0],
|
||||||
|
['uuu', proc{p 'uuu'}, 0],
|
||||||
|
['vvv', proc{p 'vvv'}, 0],
|
||||||
|
],
|
||||||
|
0, '',
|
||||||
|
{:font=>'Courier 16 italic',
|
||||||
|
:menu_config=>{:font=>'Times -18 bold', :foreground=>'black'}}],
|
||||||
|
'---',
|
||||||
|
['Quit', proc{exit}, 0]],
|
||||||
|
|
||||||
|
[['Edit', 0],
|
||||||
|
['Cut', proc{puts('Cut clicked')}, 2],
|
||||||
|
['Copy', proc{puts('Copy clicked')}, 0],
|
||||||
|
['Paste', proc{puts('Paste clicked')}, 0]],
|
||||||
|
|
||||||
|
[['Help', 0, {:menu_name=>'help'}],
|
||||||
|
['About This', proc{puts('Ruby/Tk menubar sample 1')}, 6]]
|
||||||
|
]
|
||||||
|
|
||||||
|
menubar = TkMenubar.new(nil, menu_spec,
|
||||||
|
'tearoff'=>false,
|
||||||
|
'foreground'=>'grey40',
|
||||||
|
'activeforeground'=>'red',
|
||||||
|
'font'=>'Helvetia 12 bold')
|
||||||
|
menubar.pack('side'=>'top', 'fill'=>'x')
|
||||||
|
|
||||||
|
TkText.new(:wrap=>'word').pack.insert('1.0', 'Please read the sample source, and check how to override default configure options of menu entries on a menu_spec. Maybe, on windows, this menubar does not work properly about keyboard shortcuts. Then, please use "menu" option of root/toplevel widget (see sample/menubar2.rb).')
|
||||||
|
|
||||||
|
Tk.mainloop
|
56
ext/tk/sample/menubar2.rb
Normal file
56
ext/tk/sample/menubar2.rb
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#
|
||||||
|
# menubar sample 2 : use 'menu' option of root/toplevel widget
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'tk'
|
||||||
|
|
||||||
|
radio_var = TkVariable.new('y')
|
||||||
|
|
||||||
|
menu_spec = [
|
||||||
|
[['File', 0],
|
||||||
|
{:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0},
|
||||||
|
'---',
|
||||||
|
['Check_A', TkVariable.new(true), 6],
|
||||||
|
{:type=>'checkbutton', :label=>'Check_B',
|
||||||
|
:variable=>TkVariable.new, :underline=>6},
|
||||||
|
'---',
|
||||||
|
['Radio_X', [radio_var, 'x'], 6, '', {:foreground=>'black'}],
|
||||||
|
['Radio_Y', [radio_var, 'y'], 6],
|
||||||
|
['Radio_Z', [radio_var, 'z'], 6],
|
||||||
|
'---',
|
||||||
|
['cascade', [
|
||||||
|
['sss', proc{p 'sss'}, 0],
|
||||||
|
['ttt', proc{p 'ttt'}, 0],
|
||||||
|
['uuu', proc{p 'uuu'}, 0],
|
||||||
|
['vvv', proc{p 'vvv'}, 0],
|
||||||
|
],
|
||||||
|
0, '',
|
||||||
|
{:font=>'Courier 16 italic',
|
||||||
|
:menu_config=>{:font=>'Times -18 bold', :foreground=>'black'}}],
|
||||||
|
'---',
|
||||||
|
['Quit', proc{exit}, 0]],
|
||||||
|
|
||||||
|
[['Edit', 0],
|
||||||
|
['Cut', proc{puts('Cut clicked')}, 2],
|
||||||
|
['Copy', proc{puts('Copy clicked')}, 0],
|
||||||
|
['Paste', proc{puts('Paste clicked')}, 0]],
|
||||||
|
|
||||||
|
[['Help', 0, {:menu_name=>'help'}],
|
||||||
|
['About This', proc{puts('Ruby/Tk menubar sample 2')}, 6]]
|
||||||
|
]
|
||||||
|
|
||||||
|
mbar = Tk.root.add_menubar(menu_spec,
|
||||||
|
# followings are default configure options
|
||||||
|
'tearoff'=>'false',
|
||||||
|
'foreground'=>'grey40',
|
||||||
|
'activeforeground'=>'red',
|
||||||
|
'font'=>'Helvetia 12 bold')
|
||||||
|
# This (default configure options) is NOT same the following.
|
||||||
|
#
|
||||||
|
# mbar = Tk.root.add_menubar(menu_spec)
|
||||||
|
# mbar.configure('foreground'=>'grey40', 'activeforeground'=>'red',
|
||||||
|
# 'font'=>'Helvetia 12 bold')
|
||||||
|
|
||||||
|
TkText.new(:wrap=>'word').pack.insert('1.0', 'Please read the sample source, and check how to override default configure options of menu entries on a menu_spec.')
|
||||||
|
|
||||||
|
Tk.mainloop
|
Loading…
Add table
Add a link
Reference in a new issue