mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/tcltklib/extconf.rb: [EXPERIMENTAL] MacOS X (darwin) support
* ext/tcltklib/tcltklib.c: fix thread trouble on callback proc, and eliminate warning about instance variable access * ext/tk/lib/tk/menubar.rb: improve supported menu_spec * ext/tk/lib/tk/menuspec.rb: [add] menu_spec support library * ext/tk/lib/tk/root.rb: add menu_spec support * ext/tk/lib/tk/text.rb: bug fix * ext/tk/lib/tk/toplevel.rb: add menu_spec support * ext/tk/sample/menubar?.rb: [add] sample of menu_spec usage git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6454 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
82593c058f
commit
c0271cadd7
18 changed files with 726 additions and 179 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
Sun Jun 13 00:23:04 2004 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* ext/tcltklib/extconf.rb: [EXPERIMENTAL] MacOS X (darwin) support
|
||||
|
||||
* ext/tcltklib/tcltklib.c: fix thread trouble on callback proc, and
|
||||
eliminate warning about instance variable access
|
||||
|
||||
* ext/tk/lib/tk/menubar.rb: improve supported menu_spec
|
||||
|
||||
* ext/tk/lib/tk/menuspec.rb: [add] menu_spec support library
|
||||
|
||||
* ext/tk/lib/tk/root.rb: add menu_spec support
|
||||
|
||||
* ext/tk/lib/tk/text.rb: bug fix
|
||||
|
||||
* ext/tk/lib/tk/toplevel.rb: add menu_spec support
|
||||
|
||||
* ext/tk/sample/menubar?.rb: [add] sample of menu_spec usage
|
||||
|
||||
Sat Jun 12 14:15:20 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
|
||||
|
||||
* dir.c: RDOC for File::FNM_CASEFOLD was missed.
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'mkmf'
|
||||
|
||||
is_win32 = (/mswin32|mingw|cygwin|bccwin32/ =~ RUBY_PLATFORM)
|
||||
is_macosx = (/darwin/ =~ RUBY_PLATFORM)
|
||||
|
||||
unless is_win32
|
||||
have_library("nsl", "t_open")
|
||||
|
@ -209,13 +210,19 @@ EOF
|
|||
end
|
||||
end
|
||||
|
||||
if have_header("tcl.h") && have_header("tk.h") &&
|
||||
if is_macosx ||
|
||||
(have_header("tcl.h") && have_header("tk.h") &&
|
||||
(is_win32 || find_library("X11", "XOpenDisplay",
|
||||
"/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib")) &&
|
||||
find_tcl(tcllib, stubs) &&
|
||||
find_tk(tklib, stubs)
|
||||
find_tk(tklib, stubs))
|
||||
$CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs
|
||||
$CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM
|
||||
|
||||
if is_macosx
|
||||
$CPPFLAGS += ' -I/Library/Frameworks/Tcl.framework/headers -I/Library/Frameworks/Tk.framework/Headers'
|
||||
$LDFLAGS += ' -framework Tk -framework Tcl'
|
||||
end
|
||||
|
||||
create_makefile("tcltklib") if pthread_check
|
||||
end
|
||||
|
|
|
@ -909,8 +909,11 @@ ip_set_exc_message(interp, exc)
|
|||
msg = rb_funcall(exc, ID_message, 0, 0);
|
||||
|
||||
#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)
|
||||
enc = Qnil;
|
||||
if (RTEST(rb_ivar_defined(exc, ID_at_enc))) {
|
||||
enc = rb_ivar_get(exc, ID_at_enc);
|
||||
if (NIL_P(enc)) {
|
||||
}
|
||||
if (NIL_P(enc) && RTEST(rb_ivar_defined(msg, ID_at_enc))) {
|
||||
enc = rb_ivar_get(msg, ID_at_enc);
|
||||
}
|
||||
if (NIL_P(enc)) {
|
||||
|
@ -1008,7 +1011,9 @@ ip_ruby_eval_body(arg)
|
|||
(VALUE)0);
|
||||
#else
|
||||
|
||||
rb_thread_critical = Qfalse;
|
||||
ret = rb_eval_string_protect(arg->string, &status);
|
||||
rb_thread_critical = Qtrue;
|
||||
if (status) {
|
||||
char *errtype, *buf;
|
||||
int errtype_len, len;
|
||||
|
@ -1288,9 +1293,13 @@ ip_ruby_cmd_core(arg)
|
|||
struct cmd_body_arg *arg;
|
||||
{
|
||||
VALUE ret;
|
||||
int thr_crit_bup;
|
||||
|
||||
DUMP1("call ip_ruby_cmd_core");
|
||||
thr_crit_bup = rb_thread_critical;
|
||||
rb_thread_critical = Qfalse;
|
||||
ret = rb_apply(arg->receiver, arg->method, arg->args);
|
||||
rb_thread_critical = thr_crit_bup;
|
||||
DUMP1("finish ip_ruby_cmd_core");
|
||||
|
||||
return ret;
|
||||
|
@ -3464,12 +3473,17 @@ lib_toUTF8_core(ip_obj, src, encodename)
|
|||
if (TYPE(str) == T_STRING) {
|
||||
volatile VALUE enc;
|
||||
|
||||
enc = Qnil;
|
||||
if (RTEST(rb_ivar_defined(str, ID_at_enc))) {
|
||||
enc = rb_ivar_get(str, ID_at_enc);
|
||||
}
|
||||
if (NIL_P(enc)) {
|
||||
if (NIL_P(ip_obj)) {
|
||||
encoding = (Tcl_Encoding)NULL;
|
||||
} else {
|
||||
if (RTEST(rb_ivar_defined(ip_obj, ID_at_enc))) {
|
||||
enc = rb_ivar_get(ip_obj, ID_at_enc);
|
||||
}
|
||||
if (NIL_P(enc)) {
|
||||
encoding = (Tcl_Encoding)NULL;
|
||||
} else {
|
||||
|
@ -3592,7 +3606,10 @@ lib_fromUTF8_core(ip_obj, src, encodename)
|
|||
volatile VALUE enc;
|
||||
|
||||
if (TYPE(str) == T_STRING) {
|
||||
enc = Qnil;
|
||||
if (RTEST(rb_ivar_defined(str, ID_at_enc))) {
|
||||
enc = rb_ivar_get(str, ID_at_enc);
|
||||
}
|
||||
if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) {
|
||||
rb_thread_critical = thr_crit_bup;
|
||||
return str;
|
||||
|
@ -3602,7 +3619,10 @@ lib_fromUTF8_core(ip_obj, src, encodename)
|
|||
if (NIL_P(ip_obj)) {
|
||||
encoding = (Tcl_Encoding)NULL;
|
||||
} else {
|
||||
enc = Qnil;
|
||||
if (RTEST(rb_ivar_defined(ip_obj, ID_at_enc))) {
|
||||
enc = rb_ivar_get(ip_obj, ID_at_enc);
|
||||
}
|
||||
if (NIL_P(enc)) {
|
||||
encoding = (Tcl_Encoding)NULL;
|
||||
} else {
|
||||
|
@ -3947,7 +3967,10 @@ alloc_invoke_arguments(argc, argv)
|
|||
# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0
|
||||
av[i] = Tcl_NewStringObj(s, RSTRING(v)->len);
|
||||
# else /* TCL_VERSION >= 8.1 */
|
||||
enc = Qnil;
|
||||
if (RTEST(rb_ivar_defined(v, ID_at_enc))) {
|
||||
enc = rb_ivar_get(v, ID_at_enc);
|
||||
}
|
||||
if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) {
|
||||
/* binary string */
|
||||
av[i] = Tcl_NewByteArrayObj(s, RSTRING(v)->len);
|
||||
|
@ -4461,7 +4484,11 @@ ip_set_variable(self, varname_arg, value_arg, flag_arg)
|
|||
Tcl_IncrRefCount(valobj);
|
||||
# else /* TCL_VERSION >= 8.1 */
|
||||
{
|
||||
VALUE enc = rb_ivar_get(value, ID_at_enc);
|
||||
VALUE enc = Qnil;
|
||||
|
||||
if (RTEST(rb_ivar_defined(value, ID_at_enc))) {
|
||||
enc = rb_ivar_get(value, ID_at_enc);
|
||||
}
|
||||
|
||||
if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) {
|
||||
/* binary string */
|
||||
|
@ -4581,7 +4608,11 @@ ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg)
|
|||
RSTRING(value)->len);
|
||||
# else /* TCL_VERSION >= 8.1 */
|
||||
{
|
||||
VALUE enc = rb_ivar_get(value, ID_at_enc);
|
||||
VALUE enc = Qnil;
|
||||
|
||||
if (RTEST(rb_ivar_defined(value, ID_at_enc))) {
|
||||
enc = rb_ivar_get(value, ID_at_enc);
|
||||
}
|
||||
|
||||
if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) {
|
||||
/* binary string */
|
||||
|
@ -4820,7 +4851,11 @@ lib_split_tklist_core(ip_obj, list_str)
|
|||
rb_thread_critical = Qtrue;
|
||||
|
||||
{
|
||||
VALUE enc = rb_ivar_get(list_str, ID_at_enc);
|
||||
VALUE enc = Qnil;
|
||||
|
||||
if (RTEST(rb_ivar_defined(list_str, ID_at_enc))) {
|
||||
enc = rb_ivar_get(list_str, ID_at_enc);
|
||||
}
|
||||
|
||||
if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) {
|
||||
/* binary string */
|
||||
|
|
|
@ -52,6 +52,7 @@ lib/tk/listbox.rb
|
|||
lib/tk/macpkg.rb
|
||||
lib/tk/menu.rb
|
||||
lib/tk/menubar.rb
|
||||
lib/tk/menuspec.rb
|
||||
lib/tk/message.rb
|
||||
lib/tk/mngfocus.rb
|
||||
lib/tk/msgcat.rb
|
||||
|
@ -92,6 +93,8 @@ sample/binstr_usage.rb
|
|||
sample/btn_with_frame.rb
|
||||
sample/encstr_usage.rb
|
||||
sample/iso2022-kr.txt
|
||||
sample/menubar1.rb
|
||||
sample/menubar2.rb
|
||||
sample/propagate.rb
|
||||
sample/resource.en
|
||||
sample/resource.ja
|
||||
|
|
|
@ -1324,7 +1324,8 @@ class MultiTkIp
|
|||
else
|
||||
list.push str[0..i-1]
|
||||
end
|
||||
list += _lst2ary(str[i+1..-1])
|
||||
#list += _lst2ary(str[i+1..-1])
|
||||
list.concat(_lst2ary(str[i+1..-1]))
|
||||
list
|
||||
end
|
||||
private :_lst2ary
|
||||
|
|
|
@ -114,7 +114,7 @@ module TkComm
|
|||
private :_genobj_for_tkwidget
|
||||
module_function :_genobj_for_tkwidget
|
||||
|
||||
def tk_tcl2ruby(val, enc_mode = nil)
|
||||
def tk_tcl2ruby(val, enc_mode = nil, listobj = true)
|
||||
if val =~ /^rb_out\S* (c(_\d+_)?\d+)/
|
||||
#return Tk_CMDTBL[$1]
|
||||
return TkCore::INTERP.tk_cmd_tbl[$1]
|
||||
|
@ -141,12 +141,18 @@ module TkComm
|
|||
TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val
|
||||
when /^-?\d+\.?\d*(e[-+]?\d+)?$/
|
||||
val.to_f
|
||||
when /[^\\] /
|
||||
tk_split_escstr(val).collect{|elt|
|
||||
tk_tcl2ruby(elt)
|
||||
}
|
||||
when /\\ /
|
||||
val.gsub(/\\ /, ' ')
|
||||
when /[^\\] /
|
||||
if listobj
|
||||
tk_split_escstr(val).collect{|elt|
|
||||
tk_tcl2ruby(elt, enc_mode, listobj)
|
||||
}
|
||||
elsif enc_mode
|
||||
_fromUTF8(val)
|
||||
else
|
||||
val
|
||||
end
|
||||
else
|
||||
if enc_mode
|
||||
_fromUTF8(val)
|
||||
|
@ -157,6 +163,8 @@ module TkComm
|
|||
end
|
||||
|
||||
private :tk_tcl2ruby
|
||||
module_function :tk_tcl2ruby
|
||||
private_class_method :tk_tcl2ruby
|
||||
|
||||
unless const_defined?(:USE_TCLs_LIST_FUNCTIONS)
|
||||
USE_TCLs_LIST_FUNCTIONS = true
|
||||
|
@ -171,19 +179,28 @@ if USE_TCLs_LIST_FUNCTIONS
|
|||
TkCore::INTERP._split_tklist(str)
|
||||
end
|
||||
|
||||
def tk_split_sublist(str)
|
||||
def tk_split_sublist(str, depth=-1)
|
||||
# return [] if str == ""
|
||||
# list = TkCore::INTERP._split_tklist(str)
|
||||
if depth == 0
|
||||
return "" if str == ""
|
||||
list = [str]
|
||||
else
|
||||
return [] if str == ""
|
||||
list = TkCore::INTERP._split_tklist(str)
|
||||
end
|
||||
if list.size == 1
|
||||
tk_tcl2ruby(list[0])
|
||||
tk_tcl2ruby(list[0], nil, false)
|
||||
else
|
||||
list.collect{|token| tk_split_sublist(token)}
|
||||
list.collect{|token| tk_split_sublist(token, depth - 1)}
|
||||
end
|
||||
end
|
||||
|
||||
def tk_split_list(str)
|
||||
def tk_split_list(str, depth=0)
|
||||
return [] if str == ""
|
||||
TkCore::INTERP._split_tklist(str).collect{|token| tk_split_sublist(token)}
|
||||
TkCore::INTERP._split_tklist(str).collect{|token|
|
||||
tk_split_sublist(token, depth - 1)
|
||||
}
|
||||
end
|
||||
|
||||
def tk_split_simplelist(str)
|
||||
|
@ -239,20 +256,29 @@ else
|
|||
list
|
||||
end
|
||||
|
||||
def tk_split_sublist(str)
|
||||
return [] if str == ""
|
||||
return [tk_split_sublist(str[1..-2])] if str =~ /^\{.*\}$/
|
||||
list = tk_split_escstr(str)
|
||||
if list.size == 1
|
||||
tk_tcl2ruby(list[0])
|
||||
def tk_split_sublist(str, depth=-1)
|
||||
#return [] if str == ""
|
||||
#return [tk_split_sublist(str[1..-2])] if str =~ /^\{.*\}$/
|
||||
#list = tk_split_escstr(str)
|
||||
if depth == 0
|
||||
return "" if str == ""
|
||||
str = str[1..-2] if str =~ /^\{.*\}$/
|
||||
list = [str]
|
||||
else
|
||||
list.collect{|token| tk_split_sublist(token)}
|
||||
return [] if str == []
|
||||
return [tk_split_sublist(str[1..-2], depth - 1)] if str =~ /^\{.*\}$/
|
||||
list = tk_split_escstr(str)
|
||||
end
|
||||
if list.size == 1
|
||||
tk_tcl2ruby(list[0], nil, false)
|
||||
else
|
||||
list.collect{|token| tk_split_sublist(token, depth - 1)}
|
||||
end
|
||||
end
|
||||
|
||||
def tk_split_list(str)
|
||||
def tk_split_list(str, depth=0)
|
||||
return [] if str == ""
|
||||
tk_split_escstr(str).collect{|token| tk_split_sublist(token)}
|
||||
tk_split_escstr(str).collect{|token| tk_split_sublist(token, depth - 1)}
|
||||
end
|
||||
=begin
|
||||
def tk_split_list(str)
|
||||
|
@ -425,8 +451,8 @@ end
|
|||
end
|
||||
=end
|
||||
|
||||
def list(val)
|
||||
tk_split_list(val)
|
||||
def list(val, depth=0)
|
||||
tk_split_list(val, depth)
|
||||
end
|
||||
def simplelist(val)
|
||||
tk_split_simplelist(val)
|
||||
|
@ -457,9 +483,10 @@ end
|
|||
val
|
||||
end
|
||||
end
|
||||
private :bool, :number, :string, :list, :simplelist, :window, :procedure
|
||||
module_function :bool, :number, :num_or_str, :string, :list, :simplelist
|
||||
module_function :window, :image_obj, :procedure
|
||||
private :bool, :number, :string, :num_or_str
|
||||
private :list, :simplelist, :window, :procedure
|
||||
module_function :bool, :number, :num_or_str, :string
|
||||
module_function :list, :simplelist, :window, :image_obj, :procedure
|
||||
|
||||
def _toUTF8(str, encoding = nil)
|
||||
TkCore::INTERP._toUTF8(str, encoding)
|
||||
|
@ -2035,9 +2062,10 @@ class TkObject<TkKernel
|
|||
include TkTreatFont
|
||||
include TkBindCore
|
||||
|
||||
def path
|
||||
@path
|
||||
end
|
||||
### --> definition is moved to TkUtil module
|
||||
# def path
|
||||
# @path
|
||||
# end
|
||||
|
||||
def epath
|
||||
@path
|
||||
|
@ -2433,6 +2461,7 @@ class TkWindow<TkObject
|
|||
TkPack.configure(self, slot=>value)
|
||||
end
|
||||
end
|
||||
alias pack_configure pack_config
|
||||
|
||||
def pack_info()
|
||||
#ilist = list(tk_call('pack', 'info', epath))
|
||||
|
@ -2510,6 +2539,7 @@ class TkWindow<TkObject
|
|||
TkGrid.configure(self, slot=>value)
|
||||
end
|
||||
end
|
||||
alias grid_configure grid_config
|
||||
|
||||
def grid_columnconfig(index, keys)
|
||||
#tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys))
|
||||
|
@ -2625,6 +2655,7 @@ class TkWindow<TkObject
|
|||
#end
|
||||
TkPlace.configure(self, slot, value)
|
||||
end
|
||||
alias place_configure place_config
|
||||
|
||||
def place_configinfo(slot = nil)
|
||||
# for >= Tk8.4a2 ?
|
||||
|
@ -2640,7 +2671,7 @@ class TkWindow<TkObject
|
|||
# conf
|
||||
# }
|
||||
#end
|
||||
TkPlace.configinfo(slot)
|
||||
TkPlace.configinfo(self, slot)
|
||||
end
|
||||
|
||||
def place_info()
|
||||
|
|
|
@ -62,13 +62,26 @@ module TkGrid
|
|||
# master = master.epath if master.kind_of?(TkObject)
|
||||
master = _epath(master)
|
||||
if slot
|
||||
case slot
|
||||
when 'uniform', :uniform
|
||||
tk_call_without_enc('grid', 'columnconfigure',
|
||||
master, index, "-#{slot}")
|
||||
else
|
||||
num_or_str(tk_call_without_enc('grid', 'columnconfigure',
|
||||
master, index, "-#{slot}"))
|
||||
end
|
||||
else
|
||||
ilist = list(tk_call_without_enc('grid','columnconfigure',master,index))
|
||||
#ilist = list(tk_call_without_enc('grid','columnconfigure',master,index))
|
||||
ilist = simplelist(tk_call_without_enc('grid', 'columnconfigure',
|
||||
master, index))
|
||||
info = {}
|
||||
while key = ilist.shift
|
||||
case key
|
||||
when 'uniform'
|
||||
info[key[1..-1]] = ilist.shift
|
||||
else
|
||||
info[key[1..-1]] = tk_tcl2ruby(ilist.shift)
|
||||
end
|
||||
end
|
||||
info
|
||||
end
|
||||
|
@ -78,13 +91,26 @@ module TkGrid
|
|||
# master = master.epath if master.kind_of?(TkObject)
|
||||
master = _epath(master)
|
||||
if slot
|
||||
case slot
|
||||
when 'uniform', :uniform
|
||||
tk_call_without_enc('grid', 'rowconfigure',
|
||||
master, index, "-#{slot}")
|
||||
else
|
||||
num_or_str(tk_call_without_enc('grid', 'rowconfigure',
|
||||
master, index, "-#{slot}"))
|
||||
end
|
||||
else
|
||||
ilist = list(tk_call_without_enc('grid', 'rowconfigure', master, index))
|
||||
#ilist = list(tk_call_without_enc('grid', 'rowconfigure', master, index))
|
||||
ilist = simplelist(tk_call_without_enc('grid', 'rowconfigure',
|
||||
master, index))
|
||||
info = {}
|
||||
while key = ilist.shift
|
||||
case key
|
||||
when 'uniform'
|
||||
info[key[1..-1]] = ilist.shift
|
||||
else
|
||||
info[key[1..-1]] = tk_tcl2ruby(ilist.shift)
|
||||
end
|
||||
end
|
||||
info
|
||||
end
|
||||
|
@ -106,10 +132,12 @@ module TkGrid
|
|||
def info(slave)
|
||||
# slave = slave.epath if slave.kind_of?(TkObject)
|
||||
slave = _epath(slave)
|
||||
ilist = list(tk_call_without_enc('grid', 'info', slave))
|
||||
#ilist = list(tk_call_without_enc('grid', 'info', slave))
|
||||
ilist = simplelist(tk_call_without_enc('grid', 'info', slave))
|
||||
info = {}
|
||||
while key = ilist.shift
|
||||
info[key[1..-1]] = ilist.shift
|
||||
#info[key[1..-1]] = ilist.shift
|
||||
info[key[1..-1]] = tk_tcl2ruby(ilist.shift)
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#
|
||||
# tk/menubar.rb
|
||||
#
|
||||
# Original version:
|
||||
# Copyright (C) 1998 maeda shugo. All rights reserved.
|
||||
# This file can be distributed under the terms of the Ruby.
|
||||
|
||||
|
@ -41,30 +42,56 @@
|
|||
# menubar.configure('activeforeground', 'red')
|
||||
# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1')
|
||||
# menubar.pack('side'=>'top', 'fill'=>'x')
|
||||
|
||||
# The format of the menu_spec is:
|
||||
# [
|
||||
# [
|
||||
# [button text, underline, accelerator],
|
||||
# [menu label, command, underline, accelerator],
|
||||
# '---', # separator
|
||||
# ...
|
||||
# ],
|
||||
# ...
|
||||
#
|
||||
#
|
||||
# OR
|
||||
#
|
||||
# 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],
|
||||
# ['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],
|
||||
# '---',
|
||||
# ['Quit', proc{exit}, 0]],
|
||||
# [['Edit', 0],
|
||||
# ['Cut', proc{puts('Cut clicked')}, 2],
|
||||
# ['Copy', proc{puts('Copy clicked')}, 0],
|
||||
# ['Paste', proc{puts('Paste clicked')}, 0]]
|
||||
# ]
|
||||
# menubar = TkMenubar.new(nil, menu_spec,
|
||||
# 'tearoff'=>false,
|
||||
# 'foreground'=>'grey40',
|
||||
# 'activeforeground'=>'red',
|
||||
# 'font'=>'Helvetia 12 bold')
|
||||
# menubar.pack('side'=>'top', 'fill'=>'x')
|
||||
|
||||
# underline and accelerator are optional parameters.
|
||||
# Hashes are OK instead of Arrays.
|
||||
# See tk/menuspce.rb about the format of the menu_spec
|
||||
|
||||
# To use add_menu, configuration must be done by calling configure after
|
||||
# adding all menus by add_menu, not by the constructor arguments.
|
||||
|
||||
require 'tk'
|
||||
require 'tk/frame'
|
||||
require 'tk/composite'
|
||||
require 'tk/menuspec'
|
||||
|
||||
class TkMenubar<TkFrame
|
||||
|
||||
include TkComposite
|
||||
include TkMenuSpec
|
||||
|
||||
def initialize(parent = nil, spec = nil, options = nil)
|
||||
if parent.kind_of? Hash
|
||||
|
@ -77,65 +104,25 @@ class TkMenubar<TkFrame
|
|||
|
||||
@menus = []
|
||||
|
||||
if spec
|
||||
for menu_info in spec
|
||||
add_menu(menu_info)
|
||||
end
|
||||
end
|
||||
spec.each{|info| add_menu(info)} if spec
|
||||
|
||||
if options
|
||||
for key, value in options
|
||||
configure(key, value)
|
||||
end
|
||||
end
|
||||
options.each{|key, value| configure(key, value)} if options
|
||||
end
|
||||
|
||||
def add_menu(menu_info)
|
||||
btn_info = menu_info.shift
|
||||
mbtn = TkMenubutton.new(@frame)
|
||||
mbtn, menu = _create_menubutton(@frame, menu_info)
|
||||
|
||||
if btn_info.kind_of?(Hash)
|
||||
for key, value in btn_info
|
||||
mbtn.configure(key, value)
|
||||
end
|
||||
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]
|
||||
else
|
||||
mbtn.configure('text', btn_info)
|
||||
end
|
||||
submenus = _get_cascade_menus(menu).flatten
|
||||
|
||||
menu = TkMenu.new(mbtn)
|
||||
|
||||
for item_info in menu_info
|
||||
if item_info.kind_of?(Hash)
|
||||
menu.add('command', item_info)
|
||||
elsif item_info.kind_of?(Array)
|
||||
options = {}
|
||||
options['label'] = item_info[0] if item_info[0]
|
||||
options['command'] = item_info[1] if item_info[1]
|
||||
options['underline'] = item_info[2] if item_info[2]
|
||||
options['accelerator'] = item_info[3] if item_info[3]
|
||||
menu.add('command', options)
|
||||
elsif /^-+$/ =~ item_info
|
||||
menu.add('sep')
|
||||
else
|
||||
menu.add('command', 'label' => item_info)
|
||||
end
|
||||
end
|
||||
|
||||
mbtn.menu(menu)
|
||||
@menus.push([mbtn, menu])
|
||||
delegate('tearoff', menu)
|
||||
delegate('foreground', mbtn, menu)
|
||||
delegate('background', mbtn, menu)
|
||||
delegate('disabledforeground', mbtn, menu)
|
||||
delegate('activeforeground', mbtn, menu)
|
||||
delegate('activebackground', mbtn, menu)
|
||||
delegate('font', mbtn, menu)
|
||||
delegate('kanjifont', mbtn, menu)
|
||||
mbtn.pack('side' => 'left')
|
||||
delegate('tearoff', menu, *submenus)
|
||||
delegate('foreground', mbtn, menu, *submenus)
|
||||
delegate('background', mbtn, menu, *submenus)
|
||||
delegate('disabledforeground', mbtn, menu, *submenus)
|
||||
delegate('activeforeground', mbtn, menu, *submenus)
|
||||
delegate('activebackground', mbtn, menu, *submenus)
|
||||
delegate('font', mbtn, menu, *submenus)
|
||||
delegate('kanjifont', mbtn, menu, *submenus)
|
||||
end
|
||||
|
||||
def [](index)
|
||||
|
|
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
|
|
@ -52,7 +52,8 @@ module TkOptionDB
|
|||
cline = ''
|
||||
open(file, 'r') {|f|
|
||||
while line = f.gets
|
||||
cline += line.chomp!
|
||||
#cline += line.chomp!
|
||||
cline.concat(line.chomp!)
|
||||
case cline
|
||||
when /\\$/ # continue
|
||||
cline.chop!
|
||||
|
|
|
@ -34,14 +34,21 @@ module TkPlace
|
|||
# win = win.epath if win.kind_of?(TkObject)
|
||||
win = _epath(win)
|
||||
if slot
|
||||
conf = tk_split_list(tk_call_without_enc('place', 'configure',
|
||||
#conf = tk_split_list(tk_call_without_enc('place', 'configure',
|
||||
# win, "-#{slot}") )
|
||||
conf = tk_split_simplelist(tk_call_without_enc('place', 'configure',
|
||||
win, "-#{slot}") )
|
||||
conf[0] = conf[0][1..-1]
|
||||
conf[1] = tk_tcl2ruby(conf[1])
|
||||
conf[2] = tk_tcl2ruby(conf[1])
|
||||
conf[3] = tk_tcl2ruby(conf[1])
|
||||
conf[4] = tk_tcl2ruby(conf[1])
|
||||
conf
|
||||
else
|
||||
tk_split_simplelist(tk_call_without_enc('place', 'configure',
|
||||
win)).collect{|conflist|
|
||||
conf = list(conflist)
|
||||
#conf = list(conflist)
|
||||
conf = simplelist(conflist).collect!{|inf| tk_tcl2ruby(inf)}
|
||||
conf[0] = conf[0][1..-1]
|
||||
conf
|
||||
}
|
||||
|
@ -55,13 +62,20 @@ module TkPlace
|
|||
# win = win.epath if win.kind_of?(TkObject)
|
||||
win = _epath(win)
|
||||
if slot
|
||||
conf = tk_split_list(tk_call_without_enc('place', 'configure',
|
||||
#conf = tk_split_list(tk_call_without_enc('place', 'configure',
|
||||
# win, "-#{slot}") )
|
||||
conf = tk_split_simplelist(tk_call_without_enc('place', 'configure',
|
||||
win, "-#{slot}") )
|
||||
{ conf[0][1..-1] => conf[1] }
|
||||
# { conf[0][1..-1] => conf[1] }
|
||||
{ conf[0][1..-1] => tk_tcl2ruby(conf[4]) }
|
||||
else
|
||||
ret = {}
|
||||
tk_split_list(tk_call_without_enc('place','configure',win)).each{|conf|
|
||||
ret[conf[0][1..-1]] = conf[1]
|
||||
#tk_split_list(tk_call_without_enc('place','configure',win)).each{|conf|
|
||||
tk_split_simplelist(tk_call_without_enc('place', 'configure',
|
||||
win)).each{|conf_list|
|
||||
#ret[conf[0][1..-1]] = conf[1]
|
||||
conf = simplelist(conf_list)
|
||||
ret[conf[0][1..-1]] = tk_tcl2ruby(conf[4])
|
||||
}
|
||||
ret
|
||||
end
|
||||
|
@ -76,10 +90,12 @@ module TkPlace
|
|||
def info(win)
|
||||
# win = win.epath if win.kind_of?(TkObject)
|
||||
win = _epath(win)
|
||||
ilist = list(tk_call_without_enc('place', 'info', win))
|
||||
#ilist = list(tk_call_without_enc('place', 'info', win))
|
||||
ilist = simplelist(tk_call_without_enc('place', 'info', win))
|
||||
info = {}
|
||||
while key = ilist.shift
|
||||
info[key[1..-1]] = ilist.shift
|
||||
#info[key[1..-1]] = ilist.shift
|
||||
info[key[1..-1]] = tk_tcl2ruby(ilist.shift)
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
@ -90,7 +106,8 @@ module TkPlace
|
|||
list(tk_call('place', 'slaves', master))
|
||||
end
|
||||
|
||||
module_function :configure, :configinfo, :forget, :info, :slaves
|
||||
module_function :configure, :configinfo, :current_configinfo
|
||||
module_function :forget, :info, :slaves
|
||||
end
|
||||
=begin
|
||||
def TkPlace(win, slot, value=None)
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
#
|
||||
require 'tk'
|
||||
require 'tk/wm'
|
||||
require 'tk/menuspec'
|
||||
|
||||
class TkRoot<TkWindow
|
||||
include Wm
|
||||
include TkMenuSpec
|
||||
|
||||
=begin
|
||||
ROOT = []
|
||||
|
@ -59,6 +61,25 @@ class TkRoot<TkWindow
|
|||
"."
|
||||
end
|
||||
|
||||
def add_menu(menu_info, tearoff=false, opts=nil)
|
||||
# See tk/menuspec.rb for menu_info.
|
||||
# opts is a hash of default configs for all of cascade menus.
|
||||
# Configs of menu_info can override it.
|
||||
if tearoff.kind_of?(Hash)
|
||||
opts = tearoff
|
||||
tearoff = false
|
||||
end
|
||||
_create_menubutton(self, menu_info, tearoff, opts)
|
||||
end
|
||||
|
||||
def add_menubar(menu_spec, tearoff=false, opts=nil)
|
||||
# See tk/menuspec.rb for menu_spec.
|
||||
# opts is a hash of default configs for all of cascade menus.
|
||||
# Configs of menu_spec can override it.
|
||||
menu_spec.each{|info| add_menu(info, tearoff, opts)}
|
||||
self.menu
|
||||
end
|
||||
|
||||
def TkRoot.destroy
|
||||
TkCore::INTERP._invoke('destroy', '.')
|
||||
end
|
||||
|
|
|
@ -67,6 +67,11 @@ class TkText<TkTextWin
|
|||
tk_send_without_enc('index', _get_eval_enc_str(index))
|
||||
end
|
||||
|
||||
def get_displaychars(*index)
|
||||
# Tk8.5 feature
|
||||
get('-displaychars', *index)
|
||||
end
|
||||
|
||||
def value
|
||||
_fromUTF8(tk_send_without_enc('get', "1.0", "end - 1 char"))
|
||||
end
|
||||
|
@ -326,9 +331,35 @@ class TkText<TkTextWin
|
|||
end
|
||||
|
||||
def count(idx1, idx2, *opts)
|
||||
opts = opts.collect{|opt| '-' + opt.to_s}
|
||||
number(tk_send_without_enc('count', _get_eval_enc_str(idx1),
|
||||
_get_eval_enc_str(idx2), *opts))
|
||||
# opts are Tk8.5 feature
|
||||
cnt = 0
|
||||
args = opts.collect{|opt|
|
||||
str = opt.to_s
|
||||
cnt += 1 if str != 'update'
|
||||
'-' + str
|
||||
}
|
||||
args << _get_eval_enc_str(idx1) << _get_eval_enc_str(idx2)
|
||||
if cnt <= 1
|
||||
number(tk_send_without_enc('count', *opts))
|
||||
else
|
||||
list(tk_send_without_enc('count', *opts))
|
||||
end
|
||||
end
|
||||
|
||||
def count_info(idx1, idx2, update=true)
|
||||
# Tk8.5 feature
|
||||
opts = [
|
||||
:chars, :displaychars, :displayindices, :displaylines,
|
||||
:indices, :lines, :xpixels, :ypixels
|
||||
]
|
||||
if update
|
||||
lst = count(idx1, idx2, :update, *opts)
|
||||
else
|
||||
lst = count(idx1, idx2, *opts)
|
||||
end
|
||||
info = {}
|
||||
opts.each_with_index{|key, idx| info[key] = lst[idx]}
|
||||
info
|
||||
end
|
||||
|
||||
def replace(idx1, idx2, *opts)
|
||||
|
@ -879,53 +910,40 @@ class TkText<TkTextWin
|
|||
def tksearch(*args)
|
||||
# call 'search' subcommand of text widget
|
||||
# args ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>]
|
||||
# <pattern> must be a regular expression of Tcl
|
||||
all_mode = false
|
||||
opts = args.shift
|
||||
if opts.kind_of?(Array)
|
||||
opts = opts.collect{|opt|
|
||||
opt = opt.to_s
|
||||
all_mode = true if opt == 'all'
|
||||
opt
|
||||
}
|
||||
# If <pattern> is regexp, then it must be a regular expression of Tcl
|
||||
if args[0].kind_of?(Array)
|
||||
opts = args.shift.collect{|opt| '-' + opt.to_s }
|
||||
else
|
||||
args.unshift(opts)
|
||||
opts = []
|
||||
end
|
||||
|
||||
opts << '--'
|
||||
|
||||
if all_mode
|
||||
tk_split_simplelist(tk_send(*(opts + args)))
|
||||
ret = tk_send('search', *(opts + args))
|
||||
if ret == ""
|
||||
nil
|
||||
else
|
||||
tk_send(*(opts + args))
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
def tksearch_with_count(*args)
|
||||
# call 'search' subcommand of text widget
|
||||
# args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>]
|
||||
# <pattern> must be a regular expression of Tcl
|
||||
all_mode = false
|
||||
opts = args.shift
|
||||
if opts.kind_of?(Array)
|
||||
opts = opts.collect{|opt|
|
||||
opt = opt.to_s
|
||||
all_mode = true if opt == 'all'
|
||||
opt
|
||||
}
|
||||
var = args.shift
|
||||
# If <pattern> is regexp, then it must be a regular expression of Tcl
|
||||
if args[0].kind_of?(Array)
|
||||
opts = args.shift.collect{|opt| '-' + opt.to_s }
|
||||
else
|
||||
var = opts
|
||||
opts = []
|
||||
end
|
||||
|
||||
opts << '-count' << var << '--'
|
||||
opts << '-count' << args.shift << '--'
|
||||
|
||||
if all_mode
|
||||
tk_split_simplelist(tk_send(*(opts + args)))
|
||||
ret = tk_send('search', *(opts + args))
|
||||
if ret == ""
|
||||
nil
|
||||
else
|
||||
tk_send(*(opts + args))
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
#
|
||||
require 'tk'
|
||||
require 'tk/wm'
|
||||
require 'tk/menuspec'
|
||||
|
||||
class TkToplevel<TkWindow
|
||||
include Wm
|
||||
include TkMenuSpec
|
||||
|
||||
TkCommandNames = ['toplevel'.freeze].freeze
|
||||
WidgetClassName = 'Toplevel'.freeze
|
||||
|
@ -169,6 +171,25 @@ class TkToplevel<TkWindow
|
|||
@classname
|
||||
end
|
||||
|
||||
def add_menu(menu_info, tearoff=false, opts=nil)
|
||||
# See tk/menuspec.rb for menu_info.
|
||||
# opts is a hash of default configs for all of cascade menus.
|
||||
# Configs of menu_info can override it.
|
||||
if tearoff.kind_of?(Hash)
|
||||
opts = tearoff
|
||||
tearoff = false
|
||||
end
|
||||
_create_menubutton(self, menu_info, tearoff, opts)
|
||||
end
|
||||
|
||||
def add_menubar(menu_spec, tearoff=false, opts=nil)
|
||||
# See tk/menuspec.rb for menu_spec.
|
||||
# opts is a hash of default configs for all of cascade menus.
|
||||
# Configs of menu_spec can override it.
|
||||
menu_spec.each{|info| add_menu(info, tearoff, opts)}
|
||||
self.menu
|
||||
end
|
||||
|
||||
def self.database_class
|
||||
if self == WidgetClassNames[WidgetClassName] || self.name == ''
|
||||
self
|
||||
|
|
|
@ -588,7 +588,8 @@ end
|
|||
=end
|
||||
else
|
||||
newopts = @trace_opts.dup
|
||||
opts.each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
#opts.each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
|
||||
if newopts != @trace_opts
|
||||
Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, 'rb_var')
|
||||
@trace_opts.replace(newopts)
|
||||
|
@ -637,7 +638,8 @@ end
|
|||
=end
|
||||
else
|
||||
newopts = @trace_opts.dup
|
||||
opts.each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
# opts.each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
|
||||
if newopts != @trace_opts
|
||||
Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, 'rb_var')
|
||||
@trace_opts.replace(newopts)
|
||||
|
@ -684,7 +686,8 @@ end
|
|||
idx = i
|
||||
next
|
||||
end
|
||||
e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
|
||||
}
|
||||
if idx >= 0
|
||||
@trace_var.delete_at(idx)
|
||||
|
@ -694,7 +697,8 @@ end
|
|||
|
||||
@trace_elem.each{|elem|
|
||||
@trace_elem[elem].each{|e|
|
||||
e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -751,11 +755,13 @@ end
|
|||
|
||||
newopts = ''
|
||||
@trace_var.each{|e|
|
||||
e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
|
||||
}
|
||||
@trace_elem.each{|elem|
|
||||
@trace_elem[elem].each{|e|
|
||||
e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)}
|
||||
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
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
|
|
@ -27,6 +27,7 @@ static ID ID_split_tklist;
|
|||
static ID ID_toUTF8;
|
||||
static ID ID_fromUTF8;
|
||||
static ID ID_path;
|
||||
static ID ID_at_path;
|
||||
static ID ID_to_eval;
|
||||
static ID ID_to_s;
|
||||
static ID ID_install_cmd;
|
||||
|
@ -1073,7 +1074,7 @@ static VALUE
|
|||
tkobj_path(self)
|
||||
VALUE self;
|
||||
{
|
||||
return rb_ivar_get(self, ID_path);
|
||||
return rb_ivar_get(self, ID_at_path);
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
|
@ -1091,6 +1092,7 @@ Init_tkutil()
|
|||
cMethod = rb_const_get(rb_cObject, rb_intern("Method"));
|
||||
|
||||
ID_path = rb_intern("path");
|
||||
ID_at_path = rb_intern("@path");
|
||||
ID_to_eval = rb_intern("to_eval");
|
||||
ID_to_s = rb_intern("to_s");
|
||||
ID_install_cmd = rb_intern("install_cmd");
|
||||
|
|
Loading…
Reference in a new issue