From d464704f111d211c1f1ff9ef23ef1d755054be00 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Wed, 15 Aug 2007 19:08:43 +0000 Subject: add tag v1_8_5_54 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_5_54@12952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ruby_1_8_5/ext/tk/lib/tk/menuspec.rb | 269 +++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 ruby_1_8_5/ext/tk/lib/tk/menuspec.rb (limited to 'ruby_1_8_5/ext/tk/lib/tk/menuspec.rb') diff --git a/ruby_1_8_5/ext/tk/lib/tk/menuspec.rb b/ruby_1_8_5/ext/tk/lib/tk/menuspec.rb new file mode 100644 index 0000000000..118a4f42b1 --- /dev/null +++ b/ruby_1_8_5/ext/tk/lib/tk/menuspec.rb @@ -0,0 +1,269 @@ +# +# 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 (*2) +# '---', # 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. +# +# NOTE: (*2) +# If you want to configure a cascade menu, add :menu_config=>{...configs..} +# to the configs of the cascade entry. + +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 _use_menubar?(parent) + use_menubar = false + if parent.kind_of?(TkRoot) || parent.kind_of?(TkToplevel) + return true + else + begin + parent.cget('menu') + return true + rescue + end + end + false + end + private :_use_menubar? + + def _create_menu_for_menubar(parent) + unless (mbar = parent.menu).kind_of?(TkMenu) + mbar = TkMenu.new(parent, :tearoff=>false) + parent.menu(mbar) + end + mbar + end + private :_create_menu_for_menubar + + 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 _use_menubar?(parent) + # menubar by menu entries + + mbar = _create_menu_for_menubar(parent) + + 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 -- cgit v1.2.3