* ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries.

* ext/tk/*: Support new features of Tcl/Tk8.6b1 and minor bug fixes.
     ( [KNOWN BUG] Ruby/Tk on Ruby 1.9 will not work on Cygwin. )
* ext/tk/*: Unify sources between Ruby 1.8 & 1.9.
            Improve default_widget_set handling.
* ext/tk/*: Multi-TkInterpreter (multi-tk.rb) works on Ruby 1.8 & 1.9.
     ( [KNOWN BUG] On Ruby 1.8, join to a long term Thread on Tk
       callbacks may freeze. On Ruby 1.9, cannot create a second 
       master interpreter (creating slaves are OK); supported master
       interpreter is the default master interpreter only. )
* ext/tk/lib/tkextlib/*: Update supported versions of Tk extensions.
         Tcllib 1.8/Tklib 0.4.1  ==>  Tcllib 1.11.1/Tklib 0.5
         BWidgets 1.7            ==>  BWidgets 1.8
         TkTable 2.9             ==>  TkTable 2.10
         TkTreeCtrl 2005-12-02   ==>  TkTreeCtrl 2.2.9
         Tile 0.8.0/8.5.1        ==>  Tile 0.8.3/8.6b1
         IncrTcl 2005-02-14      ==>  IncrTcl 2008-12-15
         TclX 2005-02-07         ==>  TclX 2008-12-15
         Trofs 0.4.3             ==>  Trofs 0.4.4


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagai 2009-07-12 23:08:32 +00:00
parent e13fb8029b
commit ed6ce8b43b
228 changed files with 7275 additions and 1058 deletions

View File

@ -1,3 +1,29 @@
Mon Jul 13 08:01:00 2009 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries.
* ext/tk/*: Support new features of Tcl/Tk8.6b1 and minor bug fixes.
( [KNOWN BUG] Ruby/Tk on Ruby 1.9 will not work on Cygwin. )
* ext/tk/*: Unify sources between Ruby 1.8 & 1.9.
Improve default_widget_set handling.
* ext/tk/*: Multi-TkInterpreter (multi-tk.rb) works on Ruby 1.8 & 1.9.
( [KNOWN BUG] On Ruby 1.8, join to a long term Thread on Tk
callbacks may freeze. On Ruby 1.9, cannot create a second
master interpreter (creating slaves are OK); supported master
interpreter is the default master interpreter only. )
* ext/tk/lib/tkextlib/*: Update supported versions of Tk extensions.
Tcllib 1.8/Tklib 0.4.1 ==> Tcllib 1.11.1/Tklib 0.5
BWidgets 1.7 ==> BWidgets 1.8
TkTable 2.9 ==> TkTable 2.10
TkTreeCtrl 2005-12-02 ==> TkTreeCtrl 2.2.9
Tile 0.8.0/8.5.1 ==> Tile 0.8.3/8.6b1
IncrTcl 2005-02-14 ==> IncrTcl 2008-12-15
TclX 2005-02-07 ==> TclX 2008-12-15
Trofs 0.4.3 ==> Trofs 0.4.4
Mon Jul 13 01:18:13 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> Mon Jul 13 01:18:13 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* time.c (time_timespec): rounds subsecond toward zero. * time.c (time_timespec): rounds subsecond toward zero.

View File

@ -1,3 +1,17 @@
2009-07-12 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkextlib/*: update release.
Tcllib 1.8/Tklib 0.4.1 ==> Tcllib 1.11.1/Tklib 0.5
BWidgets 1.7 ==> BWidgets 1.8
TkTable 2.9 ==> TkTable 2.10
TkTreeCtrl 2005-12-02 ==> TkTreeCtrl 2.2.9
Tile 0.8.0/8.5.1 ==> Tile 0.8.3/8.6b1
IncrTcl 2005-02-14 ==> IncrTcl 2008-12-15
TclX 2005-02-07 ==> TclX 2008-12-15
Trofs 0.4.3 ==> Trofs 0.4.4
--------------< ... some bug fixes ... >------------------
Tue Nov 25 03:37:42 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> Tue Nov 25 03:37:42 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkextlib/blt/tabset.rb, * ext/tk/lib/tkextlib/blt/tabset.rb,

View File

@ -140,8 +140,7 @@ module TclTklib
[module methods] [module methods]
get_version() get_version()
: return an array of major, minor, release-type number, : return an array of major, minor, release-type number,
: number, release-type name, and patchlevel of current : and patchlevel of current Tcl/Tk library.
: Tcl/Tk library.
mainloop(check_root = true) mainloop(check_root = true)
: Starts the eventloop. If 'check_root' is true, this method : Starts the eventloop. If 'check_root' is true, this method
@ -354,6 +353,11 @@ class TclTkIp
: to _eval and regist the command once, after that, the : to _eval and regist the command once, after that, the
: command can be called by _invoke. : command can be called by _invoke.
_cancel_eval(str)
_cancel_eval_unwind(str)
: (Tcl/Tk8.6 or later)
: Call Tcl_CancelEval() function, and cancel evaluation.
_toUTF8(str, encoding=nil) _toUTF8(str, encoding=nil)
_fromUTF8(str, encoding=nil) _fromUTF8(str, encoding=nil)
: Call the function (which is internal function of Tcl/Tk) to : Call the function (which is internal function of Tcl/Tk) to

View File

@ -235,8 +235,8 @@ require "tcltklib"
モジュールメソッド モジュールメソッド
get_version() get_version()
: Tcl/Tk の major, minor, release-type 番号, release-type 名, : Tcl/Tk の major, minor, release-type 番号, patchlevel を
: patchlevel を配列にして返す. : 配列にして返す.
mainloop(check_root = true) mainloop(check_root = true)
: イベントループを起動するcheck_root が true であれば, : イベントループを起動するcheck_root が true であれば,
@ -464,6 +464,11 @@ require "tcltklib"
: して登録に成功しさえすれば,以降は _invoke でも利用で : して登録に成功しさえすれば,以降は _invoke でも利用で
: きるようになる. : きるようになる.
_cancel_eval(str)
_cancel_eval_unwind(str)
: (Tcl/Tk8.6 or later)
: Tcl_CancelEval() 関数を呼び出しeval の実行を打ち切る.
_toUTF8(str, encoding=nil) _toUTF8(str, encoding=nil)
_fromUTF8(str, encoding=nil) _fromUTF8(str, encoding=nil)
: Tcl/Tk が内蔵している UTF8 変換処理を呼び出す. : Tcl/Tk が内蔵している UTF8 変換処理を呼び出す.

View File

@ -3,9 +3,22 @@ ActiveTcl is ActiveState's quality-assured distribution of Tcl.
# see <http://www.activestate.com/Products/ActiveTcl/> # see <http://www.activestate.com/Products/ActiveTcl/>
# <http://www.tcl.tk/> # <http://www.tcl.tk/>
First of all, please try to configure without any options.
"extconf.rb" searches ActiveTcl as default action.
If you have ActiveTcl and standard (or your own) Tcl/Tk on your
environment and don't want to use ActiveTcl on your Ruby/Tk, please
use --without-ActiveTcl option.
When "extconf.rb" fails to find your ActiveTcl libraries, please try
the followings.
If you want to use ActiveTcl binary package as the Tcl/Tk libraries, If you want to use ActiveTcl binary package as the Tcl/Tk libraries,
please use the following configure options. please use the following configure options.
--with-ActiveTcl=<ActiveTcl_root>
( When without argument; no <ActiveTcl_root>; only '--with-ActiveTcl',
it same to '--with-ActiveTcl=/opt/ActiveTcl*/lib' )
--with-tcl-dir=<ActiveTcl_root> --with-tcl-dir=<ActiveTcl_root>
--with-tk-dir=<ActiveTcl_root> --with-tk-dir=<ActiveTcl_root>

View File

@ -1,18 +1,53 @@
To compile 'tcltklib', you must have Tcl/Tk libraries on your environment. To compile 'tcltklib', you must have Tcl/Tk libraries on your environment.
Although 'extconf.rb' script searches Tcl/Tk libraries and header files, Although 'extconf.rb' script searches Tcl/Tk libraries and header files
(as default, searches tclConfig.sh/tkConfig.sh and use the defintions on
those; ActiveTcl has high priority on searching unless --without-ActiveTcl),
sometimes fails to find them. And then, 'tcltklib' cannot be compiled. If sometimes fails to find them. And then, 'tcltklib' cannot be compiled. If
Tcl/Tk libraries or header files are installed but are not found, you can Tcl/Tk libraries or header files are installed but are not found, you can
give the information by arguments of the 'configure' script. Please give give the information by arguments of the 'configure' script. Please give
some or all of the following options. some or all of the following options.
--with-tk-old-extconf use old "extconf.rb" (default: false).
If current extconf.rb doesn't work properly
(or your install process is based on old
documant about Ruby/Tk install), please try
this option.
--with-ActiveTcl / --without-ActiveTcl
--with-ActiveTcl=<dir> search ActiveTcl libraries (default: true).
When true, try to find installed ActiveTcl.
When <dir> is given, use it as the ActiveTcl's
top directory (use <dir>/lib, and so on).
Old "extconf.rb" doesn't support this option.
--with-tk-shlib-search-path=<paths>
teach the paths for loading shared-libraries
to linker.
<paths> is a path list with the same format
as PATH environment variable.
This option may be experimental.
Old "extconf.rb" doesn't support this option.
--with-tcltkversion=<version> --with-tcltkversion=<version>
force version of Tcl/Tk libaray force version of Tcl/Tk libaray
(e.g. libtcl8.4g.so ==> --with-tcltkversion=8.4g) (e.g. libtcl8.4g.so ==> --with-tcltkversion=8.4g)
--without-tcl-config / --without-tk-config
--with-tclConfig-dir=<dir>
--with-tkConfig-dir=<dir> the directory contains 'tclConfig.sh' and
'tkConfig.sh'.
Current "extconf.rb" uses the information
on tclConfig.sh/tkConfig.rb, if possible.
Old "extconf.rb" doesn't support this option.
--with-tcllib=<libname> (e.g. libtcl8.4.so ==> --with-tcllib=tcl8.4) --with-tcllib=<libname> (e.g. libtcl8.4.so ==> --with-tcllib=tcl8.4)
--with-tklib=<libname> (e.g. libtk8.4.so ==> --with-tklib=tk8.4) --with-tklib=<libname> (e.g. libtk8.4.so ==> --with-tklib=tk8.4)
--enable-tcltk-stubs (if you force to enable stubs) --enable-tcltk-stubs (if you force to enable stubs)
On old "extconf.rb", default is false.
On current "extconf.rb", default is true when
tclConfig.sh/tkConfig.sh have TCL_STUB_LIB_SPEC
/TK_STUB_LIB_SPEC, else default is false.
--with-tcl-dir=<path> --with-tcl-dir=<path>
equal to "--with-tcl-include=<path>/include --with-tcl-lib=<path>/lib" equal to "--with-tcl-include=<path>/include --with-tcl-lib=<path>/lib"
@ -36,6 +71,12 @@ some or all of the following options.
When this option is given, it is assumed that When this option is given, it is assumed that
--enable-tcltk-framework option is given also. --enable-tcltk-framework option is given also.
--with-tcl-framework-dir=<dir>
Tcl framework directory (e.g. "/Library/Frameworks/Tcl.framework")
--with-tk-framework-dir=<dir>
Tk framework directory (e.g. "/Library/Frameworks/Tk.framework")
--with-tcl-framework-header=<dir> --with-tcl-framework-header=<dir>
Tcl framework headers directory Tcl framework headers directory
(e.g. "/Library/Frameworks/Tcl.framework/Headers") (e.g. "/Library/Frameworks/Tcl.framework/Headers")

35
ext/tk/config_list.in Normal file
View File

@ -0,0 +1,35 @@
##############################################
# configure options for Ruby/Tk
# release date: 2009-07-12
##############################################
with tk-old-extconf
with ActiveTcl
with tk-shlib-search-path
with tcltkversion
with tcl-config
with tk-config
with tclConfig-dir
with tkConfig-dir
with tcllib
with tklib
enable tcltk-stubs
with tcl-dir
with tk-dir
with tcl-include
with tcl-lib
with tcl-lib
with tk-lib
enable mac-tcltk-framework
enable tcltk-framework
with tcltk-framework
with tcl-framework-dir
with tk-framework-dir
with tcl-framework-header
with tk-framework-header
with X11
with X11-dir
with X11-include
with X11-lib
enable pthread
enable tcl-thread
with tclConfig-file

File diff suppressed because it is too large Load Diff

View File

@ -30,8 +30,8 @@ class << TclTkIp
end end
obj = __new__(*args) obj = __new__(*args)
obj.instance_eval{ obj.instance_eval{
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
} }
obj obj
@ -120,31 +120,31 @@ MultiTkIp_OK.freeze
class MultiTkIp class MultiTkIp
BASE_DIR = File.dirname(__FILE__) BASE_DIR = File.dirname(__FILE__)
WITH_RUBY_VM = Object.const_defined?(:VM) && ::VM.class == Class WITH_RUBY_VM = Object.const_defined?(:RubyVM) && ::RubyVM.class == Class
WITH_ENCODING = defined?(::Encoding.default_external) WITH_ENCODING = defined?(::Encoding.default_external)
#WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class #WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class
(@@SLAVE_IP_ID = ['slave'.freeze, '0'.taint]).instance_eval{ (@@SLAVE_IP_ID = ['slave'.freeze, TkUtil.untrust('0')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
} }
@@IP_TABLE = {}.taint unless defined?(@@IP_TABLE) @@IP_TABLE = TkUtil.untrust({}) unless defined?(@@IP_TABLE)
@@INIT_IP_ENV = [].taint unless defined?(@@INIT_IP_ENV) # table of Procs @@INIT_IP_ENV = TkUtil.untrust([]) unless defined?(@@INIT_IP_ENV) # table of Procs
@@ADD_TK_PROCS = [].taint unless defined?(@@ADD_TK_PROCS) # table of [name, args, body] @@ADD_TK_PROCS = TkUtil.untrust([]) unless defined?(@@ADD_TK_PROCS) # table of [name, args, body]
@@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST) @@TK_TABLE_LIST = TkUtil.untrust([]) unless defined?(@@TK_TABLE_LIST)
unless defined?(@@TK_CMD_TBL) unless defined?(@@TK_CMD_TBL)
@@TK_CMD_TBL = Object.new.taint @@TK_CMD_TBL = TkUtil.untrust(Object.new)
# @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint) # @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint)
@@TK_CMD_TBL.instance_variable_set('@tbl', Hash.new{|hash,key| tbl_obj = TkUtil.untrust(Hash.new{|hash,key|
fail IndexError, fail IndexError, "unknown command ID '#{key}'"
"unknown command ID '#{key}'" })
}.taint) @@TK_CMD_TBL.instance_variable_set('@tbl', tbl_obj)
class << @@TK_CMD_TBL class << @@TK_CMD_TBL
allow = [ allow = [
@ -223,7 +223,10 @@ class MultiTkIp
@@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){ @@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){
def initialize(ip, cmd) def initialize(ip, cmd)
@ip = ip @ip = ip
@cmd = cmd @safe = safe = $SAFE
# @cmd = cmd
cmd = MultiTkIp._proc_on_safelevel(&cmd)
@cmd = proc{|*args| cmd.call(safe, *args)}
self.freeze self.freeze
end end
attr_reader :ip, :cmd attr_reader :ip, :cmd
@ -736,15 +739,15 @@ class MultiTkIp
@@DEFAULT_MASTER = self.allocate @@DEFAULT_MASTER = self.allocate
@@DEFAULT_MASTER.instance_eval{ @@DEFAULT_MASTER.instance_eval{
@tk_windows = {}.taint @tk_windows = TkUtil.untrust({})
@tk_table_list = [].taint @tk_table_list = TkUtil.untrust([])
@slave_ip_tbl = {}.taint @slave_ip_tbl = TkUtil.untrust({})
@slave_ip_top = {}.taint @slave_ip_top = TkUtil.untrust({})
@evloop_thread = [].taint @evloop_thread = TkUtil.untrust([])
unless keys.kind_of? Hash unless keys.kind_of? Hash
fail ArgumentError, "expecting a Hash object for the 2nd argument" fail ArgumentError, "expecting a Hash object for the 2nd argument"
@ -755,7 +758,12 @@ class MultiTkIp
else ### Ruby 1.9 !!!!!!!!!!! else ### Ruby 1.9 !!!!!!!!!!!
@interp_thread = Thread.new{ @interp_thread = Thread.new{
current = Thread.current current = Thread.current
current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys)) begin
current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys))
rescue e
current[:interp] = e
raise e
end
#sleep #sleep
current[:mutex] = mutex = Mutex.new current[:mutex] = mutex = Mutex.new
current[:root_check] = cond_var = ConditionVariable.new current[:root_check] = cond_var = ConditionVariable.new
@ -770,13 +778,29 @@ class MultiTkIp
current[:status] = status current[:status] = status
begin begin
current[:status].value = interp.mainloop(true) begin
rescue Exception=>e #TclTkLib.mainloop_abort_on_exception = false
current[:status].value = e #Thread.current[:status].value = TclTkLib.mainloop(true)
interp.mainloop_abort_on_exception = true
current[:status].value = interp.mainloop(true)
rescue SystemExit=>e
current[:status].value = e
rescue Exception=>e
current[:status].value = e
retry if interp.has_mainwindow?
ensure
mutex.synchronize{ cond_var.broadcast }
end
#Thread.current[:status].value = TclTkLib.mainloop(false)
current[:status].value = interp.mainloop(false)
ensure ensure
mutex.synchronize{ cond_var.broadcast } # interp must be deleted before the thread for interp is dead.
# If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler
# deleted by the wrong thread.
interp.delete
end end
current[:status].value = interp.mainloop(false)
} }
until @interp_thread[:interp] until @interp_thread[:interp]
Thread.pass Thread.pass
@ -795,18 +819,18 @@ class MultiTkIp
end end
@interp.instance_eval{ @interp.instance_eval{
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
} }
@ip_name = nil @ip_name = nil
@callback_status = [].taint @callback_status = TkUtil.untrust([])
@system = Object.new @system = Object.new
@wait_on_mainloop = [true, 0].taint @wait_on_mainloop = TkUtil.untrust([true, 0])
@threadgroup = Thread.current.group @threadgroup = Thread.current.group
@ -1181,8 +1205,8 @@ class MultiTkIp
ip_name = _create_slave_ip_name ip_name = _create_slave_ip_name
slave_ip = @interp.create_slave(ip_name, true) slave_ip = @interp.create_slave(ip_name, true)
slave_ip.instance_eval{ slave_ip.instance_eval{
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
} }
@slave_ip_tbl[ip_name] = slave_ip @slave_ip_tbl[ip_name] = slave_ip
@ -1228,8 +1252,8 @@ class MultiTkIp
ip_name = _create_slave_ip_name ip_name = _create_slave_ip_name
slave_ip = @interp.create_slave(ip_name, false) slave_ip = @interp.create_slave(ip_name, false)
slave_ip.instance_eval{ slave_ip.instance_eval{
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
} }
slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String) slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String)
@ -1282,12 +1306,12 @@ class MultiTkIp
@cb_error_proc = [] @cb_error_proc = []
@evloop_thread = [] @evloop_thread = []
@tk_windows.taint unless @tk_windows.tainted? TkUtil.untrust(@tk_windows) unless @tk_windows.tainted?
@tk_table_list.taint unless @tk_table_list.tainted? TkUtil.untrust(@tk_table_list) unless @tk_table_list.tainted?
@slave_ip_tbl.taint unless @slave_ip_tbl.tainted? TkUtil.untrust(@slave_ip_tbl) unless @slave_ip_tbl.tainted?
@slave_ip_top.taint unless @slave_ip_top.tainted? TkUtil.untrust(@slave_ip_top) unless @slave_ip_top.tainted?
@cb_error_proc.taint unless @cb_error_proc.tainted? TkUtil.untrust(@cb_error_proc) unless @cb_error_proc.tainted?
@evloop_thread.taint unless @evloop_thread.tainted? TkUtil.untrust(@evloop_thread) unless @evloop_thread.tainted?
@callback_status = [] @callback_status = []
@ -1302,17 +1326,18 @@ class MultiTkIp
unless WITH_RUBY_VM unless WITH_RUBY_VM
@interp = TclTkIp.new(name, _keys2opts(tk_opts)) @interp = TclTkIp.new(name, _keys2opts(tk_opts))
@interp.instance_eval{ @interp.instance_eval{
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
} }
else ### Ruby 1.9 !!!!!!!!!!! else ### Ruby 1.9 !!!!!!!!!!!
=begin
@interp_thread = Thread.new{ @interp_thread = Thread.new{
Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts)) Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
interp.instance_eval{ interp.instance_eval{
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
} }
@ -1324,15 +1349,74 @@ class MultiTkIp
end end
# INTERP_THREAD.run # INTERP_THREAD.run
@interp = @interp_thread[:interp] @interp = @interp_thread[:interp]
=end
@interp_thread = Thread.new{
current = Thread.current
begin
current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
rescue e
current[:interp] = e
raise e
end
#sleep
#TclTkLib.mainloop(true)
current[:mutex] = mutex = Mutex.new
current[:root_check] = cond_ver = ConditionVariable.new
status = [nil]
def status.value
self[0]
end
def status.value=(val)
self[0] = val
end
current[:status] = status
begin
current[:status].value = interp.mainloop(true)
rescue SystemExit=>e
current[:status].value = e
rescue Exception=>e
current[:status].value = e
retry if interp.has_mainwindow?
ensure
mutex.synchronize{ cond_var.broadcast }
end
current[:status].value = interp.mainloop(false)
}
until @interp_thread[:interp]
Thread.pass
end
# INTERP_THREAD.run
@interp = @interp_thread[:interp]
@evloop_thread[0] = @interp_thread
def self.mainloop(check_root = true)
begin
TclTkLib.set_eventloop_window_mode(true)
@interp_thread.value
ensure
TclTkLib.set_eventloop_window_mode(false)
end
end
end end
@interp.instance_eval{
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@ip_name = nil @ip_name = nil
if safe if safe
safe = $SAFE if safe < $SAFE safe = $SAFE if safe < $SAFE
@safe_level = [safe] @safe_level = [safe]
else else
@safe_level = [$SAFE] @safe_level = [$SAFE]
end end
else else
# create slave-ip # create slave-ip
if safeip || master.safe? if safeip || master.safe?
@ -1365,8 +1449,8 @@ class MultiTkIp
@system = Object.new @system = Object.new
@wait_on_mainloop = [true, 0].taint @wait_on_mainloop = TkUtil.untrust([true, 0])
# @wait_on_mainloop = [false, 0].taint # @wait_on_mainloop = TkUtil.untrust([false, 0])
@threadgroup = ThreadGroup.new @threadgroup = ThreadGroup.new
@ -1386,8 +1470,7 @@ class MultiTkIp
@@IP_TABLE[@threadgroup] = self @@IP_TABLE[@threadgroup] = self
@@TK_TABLE_LIST.size.times{ @@TK_TABLE_LIST.size.times{
(tbl = {}).tainted? || tbl.taint @tk_table_list << TkUtil.untrust({})
@tk_table_list << tbl
} }
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS) _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
@ -1435,6 +1518,17 @@ end
# get target IP # get target IP
class MultiTkIp class MultiTkIp
@@CALLBACK_SUBTHREAD = Class.new(Thread){
def self.new(interp, &blk)
super(interp){|ip| Thread.current[:callback_ip] = ip; blk.call}
end
@table = TkUtil.untrust(Hash.new{|h,k| h[k] = TkUtil.untrust([])})
def self.table
@table
end
}
def self._ip_id_ def self._ip_id_
__getip._ip_id_ __getip._ip_id_
end end
@ -1445,6 +1539,9 @@ class MultiTkIp
def self.__getip def self.__getip
current = Thread.current current = Thread.current
if current.kind_of?(@@CALLBACK_SUBTHREAD)
return current[:callback_ip]
end
if TclTkLib.mainloop_thread? != false && current[:callback_ip] if TclTkLib.mainloop_thread? != false && current[:callback_ip]
return current[:callback_ip] return current[:callback_ip]
end end
@ -1467,11 +1564,11 @@ class << MultiTkIp
alias __new new alias __new new
private :__new private :__new
def new_master(safe=nil, keys={}) def new_master(safe=nil, keys={}, &blk)
if MultiTkIp::WITH_RUBY_VM if MultiTkIp::WITH_RUBY_VM
#### TODO !!!!!! #### TODO !!!!!!
fail RuntimeError, fail RuntimeError,
'sorry, still not support multiple master-interpreters on Ruby VM' 'sorry, still not support multiple master-interpreters on RubyVM'
end end
if safe.kind_of?(Hash) if safe.kind_of?(Hash)
@ -1489,15 +1586,17 @@ class << MultiTkIp
ip = __new(__getip, nil, keys) ip = __new(__getip, nil, keys)
#ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? #ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given? if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)} #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
end #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; yield}.call)}
ip._proc_on_safelevel(&blk).call(ip.safe_level)
end
ip ip
end end
alias new new_master alias new new_master
def new_slave(safe=nil, keys={}) def new_slave(safe=nil, keys={}, &blk)
if safe.kind_of?(Hash) if safe.kind_of?(Hash)
keys = safe keys = safe
elsif safe.kind_of?(Integer) elsif safe.kind_of?(Integer)
@ -1514,13 +1613,15 @@ class << MultiTkIp
ip = __new(__getip, false, keys) ip = __new(__getip, false, keys)
# ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given? if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)} #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
#Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; yield}.call)}
ip._proc_on_safelevel(&blk).call(ip.safe_level)
end end
ip ip
end end
alias new_trusted_slave new_slave alias new_trusted_slave new_slave
def new_safe_slave(safe=4, keys={}) def new_safe_slave(safe=4, keys={}, &blk)
if safe.kind_of?(Hash) if safe.kind_of?(Hash)
keys = safe keys = safe
elsif safe.kind_of?(Integer) elsif safe.kind_of?(Integer)
@ -1535,7 +1636,9 @@ class << MultiTkIp
ip = __new(__getip, true, keys) ip = __new(__getip, true, keys)
# ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given? if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)} #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
#Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; yield}.call)}
ip._proc_on_safelevel(&blk).call(ip.safe_level)
end end
ip ip
end end
@ -1669,8 +1772,7 @@ class MultiTkIp
def _add_new_tables def _add_new_tables
(@@TK_TABLE_LIST.size - @tk_table_list.size).times{ (@@TK_TABLE_LIST.size - @tk_table_list.size).times{
(tbl = {}).tainted? || tbl.taint @tk_table_list << TkUtil.untrust({})
@tk_table_list << tbl
} }
end end
@ -1813,7 +1915,6 @@ class MultiTkIp
end end
end end
# for callback operation # for callback operation
class MultiTkIp class MultiTkIp
def self.cb_entry_class def self.cb_entry_class
@ -1837,6 +1938,13 @@ class MultiTkIp
ret ret
end end
=end =end
def cb_eval(cmd, *args)
self.eval_callback(*args,
&_proc_on_safelevel{|*params|
TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
})
end
=begin
def cb_eval(cmd, *args) def cb_eval(cmd, *args)
self.eval_callback(*args){|safe, *params| self.eval_callback(*args){|safe, *params|
$SAFE=safe if $SAFE < safe $SAFE=safe if $SAFE < safe
@ -1844,6 +1952,7 @@ class MultiTkIp
TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params)) TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
} }
end end
=end
=begin =begin
def cb_eval(cmd, *args) def cb_eval(cmd, *args)
@callback_status[0] ||= TkVariable.new @callback_status[0] ||= TkVariable.new
@ -1938,6 +2047,48 @@ end
# evaluate a procedure on the proper interpreter # evaluate a procedure on the proper interpreter
class MultiTkIp class MultiTkIp
# instance & class method
def _proc_on_safelevel(cmd=nil, &blk) # require a block for eval
if cmd
if cmd.kind_of?(Method)
_proc_on_safelevel{|*args| cmd.call(*args)}
else
_proc_on_safelevel(&cmd)
end
else
#Proc.new{|safe, *args| $SAFE=safe if $SAFE < safe; yield(*args)}
Proc.new{|safe, *args|
# avoid security error on Exception objects
untrust_proc = proc{|err|
begin
err.untrust if err.respond_to?(:untrust)
rescue SecurityError
end
err
}
$SAFE=safe if $SAFE < safe;
begin
yield(*args)
rescue Exception => e
fail untrust_proc.call(e)
end
}
end
end
def MultiTkIp._proc_on_safelevel(cmd=nil, &blk)
MultiTkIp.__getip._proc_on_safelevel(cmd, &blk)
end
def _proc_on_current_safelevel(cmd=nil, &blk) # require a block for eval
safe = $SAFE
cmd = _proc_on_safelevel(cmd, &blk)
Proc.new{|*args| cmd.call(safe, *args)}
end
def MultiTkIp._proc_on_current_safelevel(cmd=nil, &blk)
MultiTkIp.__getip._proc_on_current_safelevel(cmd, &blk)
end
######################################
# instance method # instance method
def eval_proc_core(req_val, cmd, *args) def eval_proc_core(req_val, cmd, *args)
# check # check
@ -1953,10 +2104,10 @@ class MultiTkIp
ret = cmd.call(safe_level, *args) ret = cmd.call(safe_level, *args)
rescue SystemExit => e rescue SystemExit => e
# exit IP # exit IP
warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG warn("Warning: "+ e.inspect + " on " + self.inspect) if $DEBUG
begin begin
self._eval_without_enc('exit') self._eval_without_enc('exit')
rescue Exception rescue Exception => e
end end
self.delete self.delete
ret = nil ret = nil
@ -2008,7 +2159,7 @@ class MultiTkIp
return ret.value return ret.value
rescue SystemExit => e rescue SystemExit => e
# exit IP # exit IP
warn("Warning: " + $! + " on " + self.inspect) if $DEBUG warn("Warning: " + e.inspect + " on " + self.inspect) if $DEBUG
begin begin
self._eval_without_enc('exit') self._eval_without_enc('exit')
rescue Exception rescue Exception
@ -2031,22 +2182,76 @@ class MultiTkIp
end end
private :eval_proc_core private :eval_proc_core
if WITH_RUBY_VM ### Ruby 1.9
def eval_callback(*args) def eval_callback(*args)
if block_given? if block_given?
cmd = Proc.new cmd = Proc.new
else else
cmd = args.shift cmd = args.shift
end end
current = Thread.current
backup_ip = current[:callback_ip]
current[:callback_ip] = self
begin begin
eval_proc_core(false, cmd, *args) if @@CALLBACK_SUBTHREAD.table[self].index(Thread.current)
ensure last_th = nil
current[:callback_ip] = backup_ip else
last_th = @@CALLBACK_SUBTHREAD.table[self][-1]
end
@@CALLBACK_SUBTHREAD.new(self){
@@CALLBACK_SUBTHREAD.table[self] << Thread.current
begin
last_th.join if last_th
eval_proc_core(false, cmd, *args)
rescue Exception=>e
e
ensure
@@CALLBACK_SUBTHREAD.table[self].delete(Thread.current)
end
}
end end
end end
else ### Ruby 1.8
def eval_callback(*args)
if block_given?
cmd = Proc.new
else
cmd = args.shift
end
begin
eval_proc_core(false, cmd, *args)
rescue Exception=>e
e
ensure
end
end
end
def eval_proc(*args, &blk)
if block_given?
cmd = _proc_on_safelevel(&blk)
else
unless (cmd = args.shift)
fail ArgumentError, "A Proc or Method object is expected for 1st argument"
end
cmd = _proc_on_safelevel(&cmd)
end
if TclTkLib.mainloop_thread? == true
# call from eventloop
current = Thread.current
backup_ip = current[:callback_ip]
current[:callback_ip] = self
begin
eval_proc_core(false, cmd, *args)
ensure
current[:callback_ip] = backup_ip
end
else
eval_proc_core(true,
proc{|safe, *params|
Thread.new{cmd.call(safe, *params)}.value
},
*args)
end
end
=begin
def eval_proc(*args) def eval_proc(*args)
# The scope of the eval-block of 'eval_proc' method is different from # The scope of the eval-block of 'eval_proc' method is different from
# the external. If you want to pass local values to the eval-block, # the external. If you want to pass local values to the eval-block,
@ -2081,6 +2286,7 @@ class MultiTkIp
*args) *args)
end end
end end
=end
alias call eval_proc alias call eval_proc
def bg_eval_proc(*args) def bg_eval_proc(*args)
@ -2478,7 +2684,8 @@ end
# depend on TclTkIp # depend on TclTkIp
class MultiTkIp class MultiTkIp
def mainloop(check_root = true, restart_on_dead = true) # def mainloop(check_root = true, restart_on_dead = true)
def mainloop(check_root = true, restart_on_dead = false)
raise SecurityError, "no permission to manipulate" unless self.manipulable? raise SecurityError, "no permission to manipulate" unless self.manipulable?
if WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!! if WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
@ -2507,7 +2714,7 @@ class MultiTkIp
end end
rescue SystemExit => e rescue SystemExit => e
# exit IP # exit IP
warn("Warning: " + $! + " on " + self.inspect) if $DEBUG warn("Warning: " + e.inspect + " on " + self.inspect) if $DEBUG
begin begin
self._eval_without_enc('exit') self._eval_without_enc('exit')
rescue Exception rescue Exception

View File

@ -10,8 +10,8 @@ class MultiTkIp; end
class RemoteTkIp < MultiTkIp; end class RemoteTkIp < MultiTkIp; end
class MultiTkIp class MultiTkIp
@@IP_TABLE = {}.taint unless defined?(@@IP_TABLE) @@IP_TABLE = TkUtil.untrust({}) unless defined?(@@IP_TABLE)
@@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST) @@TK_TABLE_LIST = TkUtil.untrust([]) unless defined?(@@TK_TABLE_LIST)
def self._IP_TABLE; @@IP_TABLE; end def self._IP_TABLE; @@IP_TABLE; end
def self._TK_TABLE_LIST; @@TK_TABLE_LIST; end def self._TK_TABLE_LIST; @@TK_TABLE_LIST; end
@ -88,14 +88,14 @@ class RemoteTkIp
@slave_ip_tbl = {} @slave_ip_tbl = {}
@slave_ip_top = {} @slave_ip_top = {}
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
@tk_windows.taint unless @tk_windows.tainted? TkUtil.untrust(@tk_windows) unless @tk_windows.tainted?
@tk_table_list.taint unless @tk_table_list.tainted? TkUtil.untrust(@tk_table_list) unless @tk_table_list.tainted?
@slave_ip_tbl.taint unless @slave_ip_tbl.tainted? TkUtil.untrust(@slave_ip_tbl) unless @slave_ip_tbl.tainted?
@slave_ip_top.taint unless @slave_ip_top.tainted? TkUtil.untrust(@slave_ip_top) unless @slave_ip_top.tainted?
@system = Object.new @system = Object.new
@ -119,7 +119,7 @@ class RemoteTkIp
@@IP_TABLE[@threadgroup] = self @@IP_TABLE[@threadgroup] = self
@@TK_TABLE_LIST.size.times{ @@TK_TABLE_LIST.size.times{
(tbl = {}).tainted? || tbl.taint (tbl = {}).tainted? || TkUtil.untrust(tbl)
@tk_table_list << tbl @tk_table_list << tbl
} }

View File

@ -15,7 +15,9 @@ require 'thread'
class TclTkIp class TclTkIp
# backup original (without encoding) _eval and _invoke # backup original (without encoding) _eval and _invoke
alias _eval_without_enc _eval alias _eval_without_enc _eval
alias __eval__ _eval
alias _invoke_without_enc _invoke alias _invoke_without_enc _invoke
alias __invoke__ _invoke
def _ip_id_ def _ip_id_
# for RemoteTkIp # for RemoteTkIp
@ -28,8 +30,8 @@ class TclTkIp
def initialize(*args) def initialize(*args)
__initialize__(*args) __initialize__(*args)
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
end end
end end
@ -39,8 +41,8 @@ module TkComm
include TkUtil include TkUtil
extend TkUtil extend TkUtil
WidgetClassNames = {}.taint WidgetClassNames = TkUtil.untrust({})
TkExtlibAutoloadModule = [].taint TkExtlibAutoloadModule = TkUtil.untrust([])
# None = Object.new ### --> definition is moved to TkUtil module # None = Object.new ### --> definition is moved to TkUtil module
# def None.to_s # def None.to_s
@ -50,7 +52,10 @@ module TkComm
#Tk_CMDTBL = {} #Tk_CMDTBL = {}
#Tk_WINDOWS = {} #Tk_WINDOWS = {}
Tk_IDs = ["00000".taint, "00000".taint] # [0]-cmdid, [1]-winid Tk_IDs = [
TkUtil.untrust("00000"), # [0]-cmdid
TkUtil.untrust("00000") # [1]-winid
]
Tk_IDs.instance_eval{ Tk_IDs.instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
@ -70,7 +75,7 @@ module TkComm
Tk_WINDOWS.freeze Tk_WINDOWS.freeze
self.instance_eval{ self.instance_eval{
@cmdtbl = [].taint @cmdtbl = TkUtil.untrust([])
} }
unless const_defined?(:GET_CONFIGINFO_AS_ARRAY) unless const_defined?(:GET_CONFIGINFO_AS_ARRAY)
@ -113,15 +118,22 @@ module TkComm
gen_class_name = ruby_class_name gen_class_name = ruby_class_name
classname_def = '' classname_def = ''
else # ruby_class == nil else # ruby_class == nil
mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)} if Tk.const_defined?(tk_class)
mods.each{|mod| mod.const_get(tk_class) # auto_load
begin ruby_class = WidgetClassNames[tk_class]
mod.const_get(tk_class) # auto_load end
break if (ruby_class = WidgetClassNames[tk_class])
rescue LoadError unless ruby_class
# ignore load error mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
end mods.each{|mod|
} begin
mod.const_get(tk_class) # auto_load
break if (ruby_class = WidgetClassNames[tk_class])
rescue LoadError
# ignore load error
end
}
end
unless ruby_class unless ruby_class
std_class = 'Tk' << tk_class std_class = 'Tk' << tk_class
@ -131,6 +143,14 @@ module TkComm
end end
end end
unless ruby_class
if Tk.const_defined?('TOPLEVEL_ALIASES') &&
Tk::TOPLEVEL_ALIASES.const_defined?(std_class)
Tk::TOPLEVEL_ALIASES.const_get(std_class) # auto_load
ruby_class = WidgetClassNames[tk_class]
end
end
if ruby_class if ruby_class
# found # found
ruby_class_name = ruby_class.name ruby_class_name = ruby_class.name
@ -613,11 +633,35 @@ end
val val
end end
end end
private :bool, :number, :string, :num_or_str private :bool, :number, :num_or_str, :num_or_nil, :string
private :list, :simplelist, :window, :procedure private :list, :simplelist, :window, :image_obj, :procedure
module_function :bool, :number, :num_or_str, :string module_function :bool, :number, :num_or_str, :num_or_nil, :string
module_function :list, :simplelist, :window, :image_obj, :procedure module_function :list, :simplelist, :window, :image_obj, :procedure
if (RUBY_VERSION.split('.').map{|n| n.to_i} <=> [1,8,7]) < 0
def slice_ary(ary, size)
sliced = []
wk_ary = ary.dup
until wk_ary.size.zero?
sub_ary = []
size.times{ sub_ary << wk_ary.shift }
yield(sub_ary) if block_given?
sliced << sub_ary
end
(block_given?)? ary: sliced
end
else
def slice_ary(ary, size, &b)
if b
ary.each_slice(size, &b)
else
ary.each_slice(size).to_a
end
end
end
private :slice_ary
module_function :slice_ary
def subst(str, *opts) def subst(str, *opts)
# opts := :nobackslashes | :nocommands | novariables # opts := :nobackslashes | :nocommands | novariables
tk_call('subst', tk_call('subst',
@ -803,7 +847,7 @@ end
TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd) TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd)
end end
@cmdtbl = [] unless defined? @cmdtbl @cmdtbl = [] unless defined? @cmdtbl
@cmdtbl.taint unless @cmdtbl.tainted? TkUtil.untrust(@cmdtbl) unless @cmdtbl.tainted?
@cmdtbl.push id @cmdtbl.push id
if local_cmdtbl && local_cmdtbl.kind_of?(Array) if local_cmdtbl && local_cmdtbl.kind_of?(Array)
@ -1130,30 +1174,42 @@ module TkCore
opts = '' opts = ''
end end
if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!! unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
# *** NEED TO FIX *** if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
ip = TclTkIp.new(name, opts) # *** NEED TO FIX ***
if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' && ip = TclTkIp.new(name, opts)
(TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0 if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
# *** KNOWN BUG *** (TclTkLib.get_version<=>[8,4,TclTkLib::RELEASE_TYPE::FINAL,6]) > 0
# Main event loop thread of TkAqua (> Tk8.4.9) must be the main # *** KNOWN BUG ***
# application thread. So, ruby1.9 users must call Tk.mainloop on # Main event loop thread of TkAqua (> Tk8.4.9) must be the main
# the main application thread. # application thread. So, ruby1.9 users must call Tk.mainloop on
RUN_EVENTLOOP_ON_MAIN_THREAD = true # the main application thread.
INTERP = ip #
else # *** ADD (2009/05/10) ***
unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD # In some cases (I don't know the description of conditions),
RUN_EVENTLOOP_ON_MAIN_THREAD = false # TkAqua 8.4.7 has a same kind of hang-up trouble.
end # So, if 8.4.7 or later, set RUN_EVENTLOOP_ON_MAIN_THREAD to true.
if RUN_EVENTLOOP_ON_MAIN_THREAD # When you want to control this mode, please call the following
# (set true/false as you want) before "require 'tk'".
# ----------------------------------------------------------
# module TkCore; RUN_EVENTLOOP_ON_MAIN_THREAD = true; end
# ----------------------------------------------------------
#
RUN_EVENTLOOP_ON_MAIN_THREAD = true
INTERP = ip INTERP = ip
else else
ip.delete unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
RUN_EVENTLOOP_ON_MAIN_THREAD = false
end
if RUN_EVENTLOOP_ON_MAIN_THREAD
INTERP = ip
else
ip.delete
end
end end
end ip = nil
ip = nil
else else # Ruby 1.8.x
unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
RUN_EVENTLOOP_ON_MAIN_THREAD = false RUN_EVENTLOOP_ON_MAIN_THREAD = false
end end
end end
@ -1183,13 +1239,29 @@ module TkCore
#sleep #sleep
begin begin
Thread.current[:status].value = TclTkLib.mainloop(true) begin
rescue Exception=>e #TclTkLib.mainloop_abort_on_exception = false
Thread.current[:status].value = e #Thread.current[:status].value = TclTkLib.mainloop(true)
interp.mainloop_abort_on_exception = true
Thread.current[:status].value = interp.mainloop(true)
rescue SystemExit=>e
Thread.current[:status].value = e
rescue Exception=>e
Thread.current[:status].value = e
retry if interp.has_mainwindow?
ensure
INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
end
#Thread.current[:status].value = TclTkLib.mainloop(false)
Thread.current[:status].value = interp.mainloop(false)
ensure ensure
INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast } # interp must be deleted before the thread for interp is dead.
# If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler
# deleted by the wrong thread.
interp.delete
end end
Thread.current[:status].value = TclTkLib.mainloop(false)
} }
until INTERP_THREAD[:interp] until INTERP_THREAD[:interp]
@ -1210,10 +1282,11 @@ module TkCore
end end
INTERP.instance_eval{ INTERP.instance_eval{
# @tk_cmd_tbl = {}.taint # @tk_cmd_tbl = TkUtil.untrust({})
@tk_cmd_tbl = Hash.new{|hash, key| @tk_cmd_tbl =
fail IndexError, "unknown command ID '#{key}'" TkUtil.untrust(Hash.new{|hash, key|
}.taint fail IndexError, "unknown command ID '#{key}'"
})
def @tk_cmd_tbl.[]=(idx,val) def @tk_cmd_tbl.[]=(idx,val)
if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default
fail SecurityError,"cannot change the entried command" fail SecurityError,"cannot change the entried command"
@ -1221,15 +1294,15 @@ module TkCore
super(idx,val) super(idx,val)
end end
@tk_windows = {}.taint @tk_windows = TkUtil.untrust({})
@tk_table_list = [].taint @tk_table_list = TkUtil.untrust([])
@init_ip_env = [].taint # table of Procs @init_ip_env = TkUtil.untrust([]) # table of Procs
@add_tk_procs = [].taint # table of [name, args, body] @add_tk_procs = TkUtil.untrust([]) # table of [name, args, body]
@force_default_encoding ||= [false].taint @force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= [nil].taint @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end def @encoding.to_s; self.join(nil); end
@cb_entry_class = Class.new(TkCallbackEntry){ @cb_entry_class = Class.new(TkCallbackEntry){
@ -1283,7 +1356,7 @@ module TkCore
end end
def INTERP.create_table def INTERP.create_table
id = @tk_table_list.size id = @tk_table_list.size
(tbl = {}).tainted? || tbl.taint (tbl = {}).tainted? || TkUtil.untrust(tbl)
@tk_table_list << tbl @tk_table_list << tbl
# obj = Object.new # obj = Object.new
# obj.instance_eval <<-EOD # obj.instance_eval <<-EOD
@ -1321,7 +1394,8 @@ module TkCore
@add_tk_procs.delete_if{|elem| @add_tk_procs.delete_if{|elem|
elem.kind_of?(Array) && elem[0].to_s == name elem.kind_of?(Array) && elem[0].to_s == name
} }
self._invoke('rename', name, '') #self._invoke('rename', name, '')
self.__invoke__('rename', name, '')
} }
end end
def INTERP.init_ip_internal def INTERP.init_ip_internal
@ -1704,11 +1778,14 @@ module TkCore
elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
# if TclTkLib::WINDOWING_SYSTEM == 'aqua' && # if TclTkLib::WINDOWING_SYSTEM == 'aqua' &&
if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' && #if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
Thread.current != Thread.main && # Thread.current != Thread.main &&
(TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0 # (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
raise RuntimeError, # raise RuntimeError,
"eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only" # "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
#end
if Thread.current != Thread.main
raise RuntimeError, "Tk.mainloop is allowed on the main thread only"
end end
TclTkLib.mainloop(check_root) TclTkLib.mainloop(check_root)
@ -1911,7 +1988,7 @@ module TkCore
puts 'invoke args => ' + args.inspect if $DEBUG puts 'invoke args => ' + args.inspect if $DEBUG
### print "=> ", args.join(" ").inspect, "\n" if $DEBUG ### print "=> ", args.join(" ").inspect, "\n" if $DEBUG
begin begin
# res = INTERP._invoke(*args).taint # res = TkUtil.untrust(INTERP._invoke(*args))
# res = INTERP._invoke(enc_mode, *args) # res = INTERP._invoke(enc_mode, *args)
res = _ip_invoke_core(enc_mode, *args) res = _ip_invoke_core(enc_mode, *args)
# >>>>> _invoke returns a TAINTED string <<<<< # >>>>> _invoke returns a TAINTED string <<<<<
@ -1919,7 +1996,7 @@ module TkCore
# err = $! # err = $!
begin begin
args.unshift "unknown" args.unshift "unknown"
#res = INTERP._invoke(*args).taint #res = TkUtil.untrust(INTERP._invoke(*args))
#res = INTERP._invoke(enc_mode, *args) #res = INTERP._invoke(enc_mode, *args)
res = _ip_invoke_core(enc_mode, *args) res = _ip_invoke_core(enc_mode, *args)
# >>>>> _invoke returns a TAINTED string <<<<< # >>>>> _invoke returns a TAINTED string <<<<<
@ -3028,7 +3105,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
=begin =begin
if ext_enc_obj == Tk::Encoding::UNKNOWN if ext_enc_obj == Tk::Encoding::UNKNOWN
if defind? DEFAULT_TK_ENCODING if defined? DEFAULT_TK_ENCODING
if DEFAULT_TK_ENCODING.kind_of?(::Encoding) if DEFAULT_TK_ENCODING.kind_of?(::Encoding)
tk_enc_name = DEFAULT_TK_ENCODING.name tk_enc_name = DEFAULT_TK_ENCODING.name
tksys_enc_name = DEFAULT_TK_ENCODING.name tksys_enc_name = DEFAULT_TK_ENCODING.name
@ -3126,7 +3203,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
#if ext_enc_name && ext_enc_name != tksys_enc_name #if ext_enc_name && ext_enc_name != tksys_enc_name
int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj) int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj)
if int_enc_name if int_enc_name
# use default_external # use default_internal
enc_name = int_enc_name enc_name = int_enc_name
else else
# use Tk.encoding_system # use Tk.encoding_system
@ -3279,10 +3356,10 @@ module TkTreatFont
TkFont.init_widget_font(pathname, *__confinfo_cmd) TkFont.init_widget_font(pathname, *__confinfo_cmd)
else else
fonts = {} fonts = {}
optkeys.each{|key| optkeys.each{|k|
key = key.to_s k = k.to_s
pathname = [win, tag, key].join(';') pathname = [win, tag, k].join(';')
fonts[key] = fonts[k] =
TkFont.used_on(pathname) || TkFont.used_on(pathname) ||
TkFont.init_widget_font(pathname, *__confinfo_cmd) TkFont.init_widget_font(pathname, *__confinfo_cmd)
} }
@ -3407,7 +3484,7 @@ module TkTreatFont
if fobj.kind_of?(TkFont) if fobj.kind_of?(TkFont)
if ltn.kind_of?(TkFont) if ltn.kind_of?(TkFont)
conf = {} conf = {}
ltn.latin_configinfo.each{|key,val| conf[key] = val} ltn.latin_configinfo.each{|k,val| conf[k] = val}
if keys if keys
fobj.latin_configure(conf.update(keys)) fobj.latin_configure(conf.update(keys))
else else
@ -3467,7 +3544,7 @@ module TkTreatFont
if fobj.kind_of?(TkFont) if fobj.kind_of?(TkFont)
if knj.kind_of?(TkFont) if knj.kind_of?(TkFont)
conf = {} conf = {}
knj.kanji_configinfo.each{|key,val| conf[key] = val} knj.kanji_configinfo.each{|k,val| conf[k] = val}
if keys if keys
fobj.kanji_configure(conf.update(keys)) fobj.kanji_configure(conf.update(keys))
else else
@ -3701,11 +3778,17 @@ module TkConfigMethod
val val
end end
def cget_tkstring(option)
opt = option.to_s
fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
tk_call_without_enc(*(__cget_cmd << "-#{opt}"))
end
def __cget_core(slot) def __cget_core(slot)
orig_slot = slot orig_slot = slot
slot = slot.to_s slot = slot.to_s
if slot.length == 0 if slot.length == 0
fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" fail ArgumentError, "Invalid option `#{orig_slot.inspect}'"
end end
@ -4106,7 +4189,8 @@ module TkConfigMethod
else else
# conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true) # conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 1, false, true)
end end
conf[__configinfo_struct[:key]] = conf[__configinfo_struct[:key]] =
conf[__configinfo_struct[:key]][1..-1] conf[__configinfo_struct[:key]][1..-1]
@ -4296,8 +4380,8 @@ module TkConfigMethod
end end
} }
__methodcall_optkeys.each{|optkey, method| __methodcall_optkeys.each{|optkey, m|
ret << [optkey.to_s, '', '', '', self.__send__(method)] ret << [optkey.to_s, '', '', '', self.__send__(m)]
} }
ret ret
@ -4335,7 +4419,7 @@ module TkConfigMethod
if slot if slot
slot = slot.to_s slot = slot.to_s
alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} alias_name, real_name = __optkey_aliases.find{|k,var| k.to_s == slot}
if real_name if real_name
slot = real_name.to_s slot = real_name.to_s
end end
@ -4682,8 +4766,8 @@ module TkConfigMethod
end end
} }
__methodcall_optkeys.each{|optkey, method| __methodcall_optkeys.each{|optkey, m|
ret[optkey.to_s] = ['', '', '', self.__send__(method)] ret[optkey.to_s] = ['', '', '', self.__send__(m)]
} }
ret ret
@ -4721,18 +4805,18 @@ module TkConfigMethod
"there is a configure alias loop about '#{org_slot}'" "there is a configure alias loop about '#{org_slot}'"
else else
ret = {} ret = {}
configinfo().each{|conf| configinfo().each{|cnf|
if ( ! __configinfo_struct[:alias] \ if ( ! __configinfo_struct[:alias] \
|| conf.size > __configinfo_struct[:alias] + 1 ) || cnf.size > __configinfo_struct[:alias] + 1 )
ret[conf[0]] = conf[-1] ret[cnf[0]] = cnf[-1]
end end
} }
ret ret
end end
else # ! TkComm::GET_CONFIGINFO_AS_ARRAY else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
ret = {} ret = {}
configinfo(slot).each{|key, conf| configinfo(slot).each{|key, cnf|
ret[key] = conf[-1] if conf.kind_of?(Array) ret[key] = cnf[-1] if cnf.kind_of?(Array)
} }
ret ret
end end
@ -4864,6 +4948,7 @@ class TkWindow<TkObject
include TkWinfo include TkWinfo
extend TkBindCore extend TkBindCore
include Tk::Wm_for_General include Tk::Wm_for_General
include Tk::Busy
@@WIDGET_INSPECT_FULL = false @@WIDGET_INSPECT_FULL = false
def TkWindow._widget_inspect_full_? def TkWindow._widget_inspect_full_?
@ -5551,7 +5636,7 @@ TkWidget = TkWindow
#Tk.freeze #Tk.freeze
module Tk module Tk
RELEASE_DATE = '2009-01-13'.freeze RELEASE_DATE = '2009-07-12'.freeze
autoload :AUTO_PATH, 'tk/variable' autoload :AUTO_PATH, 'tk/variable'
autoload :TCL_PACKAGE_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable'

View File

@ -27,6 +27,8 @@ def TkPlace(*args); TkPlace.configure(*args); end
############################################ ############################################
# classes on Tk module # classes on Tk module
module Tk module Tk
autoload :Busy, 'tk/busy'
autoload :Button, 'tk/button' autoload :Button, 'tk/button'
autoload :Canvas, 'tk/canvas' autoload :Canvas, 'tk/canvas'
@ -319,9 +321,16 @@ module Tk
@TOPLEVEL_ALIAS_SETUP_PROC = {} @TOPLEVEL_ALIAS_SETUP_PROC = {}
@AUTOLOAD_FILE_SYM_TABLE = Hash.new{|h,k| h[k]={}} # TABLE[file][sym] -> obj
@current_default_widget_set = nil @current_default_widget_set = nil
module TOPLEVEL_ALIASES; end
end end
class Object
include Tk::TOPLEVEL_ALIASES
end
############################################ ############################################
# methods to control default widget set # methods to control default widget set
@ -343,50 +352,387 @@ class << Tk
_replace_toplevel_aliases(target) _replace_toplevel_aliases(target)
end end
def __set_toplevel_aliases__(target, obj, *symbols) def widget_set_symbols
@TOPLEVEL_ALIAS_TABLE.keys
end
def toplevel_aliases_on_widget_set(widget_set)
if (tbl = @TOPLEVEL_ALIAS_TABLE[widget_set.to_sym])
tbl.collect{|k, v| (v.nil?)? nil: k}.compact
else
fail ArgumentError, "unknown widget_set #{widget_set.to_sym.inspect}"
end
end
def __toplevel_alias_setup_proc__(*target_list, &cmd)
target_list.each{|target| @TOPLEVEL_ALIAS_SETUP_PROC[target.to_sym] = cmd}
end
def topobj_defined?(sym) #=> alias_filename or object or false
Object.autoload?(sym) ||
(Object.const_defined?(sym) && Object.const_get(sym))
end
def topalias_defined?(sym) #=> alias_filename or object or false
Tk::TOPLEVEL_ALIASES.autoload?(sym) ||
(Tk::TOPLEVEL_ALIASES.const_defined?(sym) &&
Tk::TOPLEVEL_ALIASES.const_get(sym))
end
def define_topobj(sym, obj)
if obj.kind_of? String
# obj is an autoload path
Object.autoload(sym, obj)
unless Object.autoload?(sym)
# file is autoloaded?
if @AUTOLOAD_FILE_SYM_TABLE.has_key?(obj) &&
(loaded_obj = @AUTOLOAD_FILE_SYM_TABLE[obj][sym])
Object.const_set(sym, loaded_obj)
else
fail ArgumentError, "cannot define autoload file (already loaded?)"
end
end
else
# object
Object.const_set(sym, obj)
end
end
def define_topalias(sym, obj)
if obj.kind_of? String
# obj is an autoload path
Tk::TOPLEVEL_ALIASES.autoload(sym, obj)
unless Tk::TOPLEVEL_ALIASES.autoload?(sym)
# file is autoloaded?
if @AUTOLOAD_FILE_SYM_TABLE.has_key?(obj) &&
(loaded_obj = @AUTOLOAD_FILE_SYM_TABLE[obj][sym])
Tk::TOPLEVEL_ALIASES.const_set(sym, loaded_obj)
else
fail ArgumentError, "cannot define autoload file (already loaded?)"
end
end
else
# object
Tk::TOPLEVEL_ALIASES.const_set(sym, obj)
end
end
def replace_topobj(sym, obj) #=> old_obj (alias_filename or object) or nil
if old_obj = topobj_defined?(sym)
Object.class_eval{remove_const sym} rescue nil # ignore err
end
define_topobj(sym, obj)
old_obj
end
def replace_topalias(sym, obj) #=> old_obj (alias_filename or object) or nil
if old_obj = topalias_defined?(sym)
Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} rescue nil #ignore err
end
define_topalias(sym, obj)
old_obj
end
private :topobj_defined?, :topalias_defined?
private :define_topobj, :define_topalias
private :replace_topobj, :replace_topalias
def __regist_toplevel_aliases__(target, obj, *symbols)
# initial regist
@TOPLEVEL_ALIAS_TABLE[target = target.to_sym] ||= {} @TOPLEVEL_ALIAS_TABLE[target = target.to_sym] ||= {}
symbols.each{|sym| symbols.each{|sym|
@TOPLEVEL_ALIAS_TABLE[target][sym = sym.to_sym] = obj @TOPLEVEL_ALIAS_TABLE[target][sym = sym.to_sym] = obj
# if @current_default_widget_set == target if !topalias_defined?(sym) || target == @current_default_widget_set
if @TOPLEVEL_ALIAS_OWNER[sym] == target @TOPLEVEL_ALIAS_OWNER[sym] = target
Object.class_eval{remove_const sym} if Object.const_defined?(sym) replace_topalias(sym, obj)
Object.const_set(sym, obj) replace_topobj(sym, obj) unless obj.kind_of?(String) # NOT autoload
end end
} }
end end
################################### def regist_sym_for_loaded_file(auto, obj, sym)
private @AUTOLOAD_FILE_SYM_TABLE[auto][sym] = obj
def _replace_toplevel_aliases(target)
# check already autoloaded reg = /^#{Regexp.quote(auto)}(\.rb|\.so|)$/
if (table = @TOPLEVEL_ALIAS_TABLE[current = @current_default_widget_set]) @TOPLEVEL_ALIAS_TABLE.each_key{|set|
table.each{|sym, file| if @TOPLEVEL_ALIAS_TABLE[set][sym] =~ reg
if !Object.autoload?(sym) && Object.const_defined?(sym) && @TOPLEVEL_ALIAS_TABLE[set][sym] = obj
@TOPLEVEL_ALIAS_TABLE[current][sym].kind_of?(String) if @TOPLEVEL_ALIAS_OWNER[sym].nil? || @TOPLEVEL_ALIAS_OWNER[sym] == set
# autoload -> class replace_topalias(sym, obj)
@TOPLEVEL_ALIAS_TABLE[current][sym] = Object.const_get(sym) replace_topobj(sym, obj) if set == @current_default_widget_set
end end
} end
}
if (f = Object.autoload?(sym)) && f =~ reg
replace_topobj(sym, obj)
end
if (f = Tk::TOPLEVEL_ALIASES.autoload?(sym)) && f =~ reg
replace_topalias(sym, obj)
end
end
private :regist_sym_for_loaded_file
def set_topalias(target, obj, sym)
# obj is a kind of String : define autoload path
# Class : use the class object
if target == @current_default_widget_set
case @TOPLEVEL_ALIAS_OWNER[sym]
when false
# Object::sym is out of control. --> not change
# Make ALIAS::sym under control, because target widget set is current.
# Keep OWNER[sym]
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
when target
if current_obj = topobj_defined?(sym)
if current_obj == obj
# Make current_obj under control.
# Keep Object::sym.
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
else # current_obj != obj
if current_obj == topalias_defined?(sym)
# Change controlled object
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
replace_topobj(sym, obj)
else # current_obj != topalias_defined?(sym)
# Maybe current_obj is defined by user. --> OWNER[sym] = faise
# Keep Object::sym.
@TOPLEVEL_ALIAS_OWNER[sym] = false
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
end
end
else # NOT topobj_defined?(sym)
# New definition for sym at target.
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
define_topobj(sym, obj)
end
when nil
# New definition for sym at target.
@TOPLEVEL_ALIAS_OWNER[sym] = target
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
else # others
# Maybe planning to make sym under control.
@TOPLEVEL_ALIAS_OWNER[sym] = target
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
replace_topobj(sym, obj)
end
else # target != @current_default_widget_set
case @TOPLEVEL_ALIAS_OWNER[sym]
when false
# Object::sym is out of control. --> not change
if topalias_defined?(sym)
# ALIAS[sym] may be defined by other widget set.
# Keep Object::sym (even if it is not defined)
# Keep ALIAS[sym].
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
else # NOT topalias_defined?(sym)
# Nobody controls ALIAS[sym].
# At leaset, current widget set doesn't control ALIAS[sym].
# Keep Object::sym (even if it is not defined)
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
define_topalias(sym, obj)
end
when target
# Maybe change controlled object, because Object::sym is under control.
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
replace_topobj(sym, obj)
when nil
# New definition for sym
@TOPLEVEL_ALIAS_OWNER[sym] = target
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
replace_topalias(sym, obj)
replace_topobj(sym, obj)
else # others
# An other widget set controls sym.
# Keep Object::sym (even if it is not defined)
# Keep ALIAS[sym].
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[target][sym] = obj
end
end end
# setup autoloads sym
@TOPLEVEL_ALIAS_TABLE[target].each{|sym, file| end
Object.class_eval{remove_const sym} if Object.const_defined?(sym) private :set_topalias
if file.kind_of?(String)
# file => autoload target file def __set_toplevel_aliases__(target, obj, *symbols)
Object.autoload(sym, file) # obj is a kind of String : define autoload path
else # Class : use the class object
# file => loaded class object target = target.to_sym
Object.const_set(sym, file) symbols.each{|sym| set_topalias(target, obj, sym.to_sym)}
end
def __set_loaded_toplevel_aliases__(autopath, target, obj, *symbols)
# autopath is an autoload file
# Currently, this method doesn't support that autoload loads
# different toplevels between <basename>.rb and <basename>.so extension.
shortpath = (autopath =~ /^(.*)(.rb|.so)$/)? $1: autopath
target = target.to_sym
symbols.map!{|sym| sym.to_sym}
symbols.each{|sym| regist_sym_for_loaded_file(shortpath, obj, sym) }
symbols.each{|sym| set_topalias(target, obj, sym)}
end
def backup_current_topdef(sym)
return if (current = @current_default_widget_set).nil?
case @TOPLEVEL_ALIAS_OWNER[sym]
when false
# Object::sym is out of control.
if (cur_alias = topalias_defined?(sym)) && ! cur_alias.kind_of?(String)
@TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
end end
@TOPLEVEL_ALIAS_OWNER[sym] = target
when current
if cur_obj = topobj_defined?(sym)
if ! cur_obj.kind_of?(String) && (cur_alias = topalias_defined?(sym))
if cur_alias.kind_of?(String)
# Mayby, user replaced Object::sym.
# Make Object::sym out of control.
@TOPLEVEL_ALIAS_OWNER[sym] = false
elsif cur_obj == cur_alias
# Possibley, defined normally. Backup it
@TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
else
# Mayby, user replaced Object::sym.
# Make Object::sym out of control.
@TOPLEVEL_ALIAS_OWNER[sym] = false
end
end
else
# Mayby, user replaced Object::sym.
# Make Object::sym out of control.
@TOPLEVEL_ALIAS_OWNER[sym] = false
end
when nil
# Object::sym is out of control.
if (cur_alias = topalias_defined?(sym)) && ! cur_alias.kind_of?(String)
# Possibley, defined normally. Backup it.
@TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
end
else
# No authority to control Object::sym and ALIASES::sym.
# Do nothing.
end
end
private :backup_current_topdef
def _replace_toplevel_aliases(target)
# backup
@TOPLEVEL_ALIAS_TABLE[target].each_key{|sym|
backup_current_topdef(sym)
} }
# update current alias # replace
@TOPLEVEL_ALIAS_TABLE[target].each_key{|sym|
next if (obj = @TOPLEVEL_ALIAS_TABLE[target][sym]).nil?
if @TOPLEVEL_ALIAS_OWNER[sym] == false
# Object::sym is out of control. --> not change
# Keep OWNER[sym].
replace_topalias(sym, obj)
else
# New definition
@TOPLEVEL_ALIAS_OWNER[sym] = target
replace_topalias(sym, obj)
replace_topobj(sym, obj)
end
}
# change default_widget_set
@current_default_widget_set = target @current_default_widget_set = target
end end
private :_replace_toplevel_aliases
def __import_toplevel_aliases__(target, *symbols)
current = @current_default_widget_set
symbols.each{|sym|
sym = sym.to_sym
if (obj = @TOPLEVEL_ALIAS_TABLE[target][sym]).nil?
# remove
@TOPLEVEL_ALIAS_TABLE[current].delete(sym)
@TOPLEVEL_ALIAS_OWNER.delete(sym)
Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
Object.class_eval{remove_const sym} if topobj_defined?(sym)
elsif obj == false
# remove, but OWNER[sym] <- false and not treat Object::sym
@TOPLEVEL_ALIAS_TABLE[current].delete(sym)
@TOPLEVEL_ALIAS_OWNER[sym] = false
Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
elsif @TOPLEVEL_ALIAS_OWNER[sym] == false
# Object::sym is out of control. --> not change
# Keep OWNER[sym].
@TOPLEVEL_ALIAS_TABLE[current][sym] = obj
replace_topalias(sym, obj)
else
# new definition under control
@TOPLEVEL_ALIAS_OWNER[sym] = current
@TOPLEVEL_ALIAS_TABLE[current][sym] = obj
replace_topalias(sym, obj)
replace_topobj(sym, obj)
end
}
end
def __remove_toplevel_aliases__(*symbols)
# remove toplevel aliases of current widget set
current = @current_default_widget_set
symbols.each{|sym|
sym = sym.to_sym
@TOPLEVEL_ALIAS_TABLE[current].delete(sym)
@TOPLEVEL_ALIAS_OWNER.delete(sym)
Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
Object.class_eval{remove_const sym} if topobj_defined?(sym)
}
end
def __reset_toplevel_owner__(*symbols)
symbols.each{|sym| @TOPLEVEL_ALIAS_OWNER.delete(sym.to_sym)}
end
def __disable_toplevel_control__(*symbols)
symbols.each{|sym| @TOPLEVEL_ALIAS_OWNER[sym.to_sym] = false}
end
def __create_widget_set__(new_set, src_set={})
new_set = new_set.to_sym
if @TOPLEVEL_ALIAS_TABLE[new_set]
fail RuntimeError, "A widget-set #{new_set.inspect} is already exist."
end
if src_set.kind_of?(Symbol)
# new_set is an alias name of existed widget set.
@TOPLEVEL_ALIAS_TABLE[new_set] = @TOPLEVEL_ALIAS_TABLE[src_set]
else
@TOPLEVEL_ALIAS_TABLE[new_set] = {}
src_set.each{|sym, obj| set_topalias(new_set, obj, sym.to_sym) }
end
end
end end
############################################ ############################################
# setup default widget set => :Tk # setup default widget set => :Tk
Tk.default_widget_set = :Tk Tk.default_widget_set = :Tk

View File

@ -9,7 +9,7 @@ class TkBindTag
#BTagID_TBL = {} #BTagID_TBL = {}
BTagID_TBL = TkCore::INTERP.create_table BTagID_TBL = TkCore::INTERP.create_table
(Tk_BINDTAG_ID = ["btag".freeze, "00000".taint]).instance_eval{ (Tk_BINDTAG_ID = ["btag".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

118
ext/tk/lib/tk/busy.rb Normal file
View File

@ -0,0 +1,118 @@
#
# tk/busy.rb: support 'tk busy' command (Tcl/Tk8.6 or later)
#
require 'tk'
module Tk::Busy
include TkCore
extend TkCore
extend TkItemConfigMethod
end
class << Tk::Busy
def __item_cget_cmd(win)
# maybe need to override
['tk', 'busy', 'cget', win.path]
end
private :__item_cget_cmd
def __item_config_cmd(win)
# maybe need to override
['tk', 'busy', 'configure', win.path]
end
private :__item_config_cmd
def __item_confinfo_cmd(win)
# maybe need to override
__item_config_cmd(win)
end
private :__item_confinfo_cmd
alias cget_tkstring itemcget_tkstring
alias cget itemcget
alias cget_strict itemcget_strict
alias configure itemconfigure
alias configinfo itemconfiginfo
alias current_configinfo current_itemconfiginfo
private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
def method_missing(id, *args)
name = id.id2name
case args.length
when 1
if name[-1] == ?=
configure name[0..-2], args[0]
args[0]
else
configure name, args[0]
self
end
when 0
begin
cget(name)
rescue
super(id, *args)
end
else
super(id, *args)
end
end
def hold(win, keys={})
tk_call_without_enc('tk', 'busy', 'hold', win, *hash_kv(keys))
win
end
def forget(*wins)
tk_call_without_enc('tk', 'busy', 'forget', *wins)
self
end
def current(pat=None)
list(tk_call('tk', 'busy', 'current', pat))
end
def status(win)
bool(tk_call_without_enc('tk', 'busy', 'status', win))
end
end
module Tk::Busy
def busy_configinfo(option=nil)
Tk::Busy.configinfo(self, option)
end
def busy_current_configinfo(option=nil)
Tk::Busy.current_configinfo(self, option)
end
def busy_configure(option, value=None)
Tk::Busy.configure(self, option, value)
self
end
def busy_cget(option)
Tk::Busy.configure(self, option)
end
def busy(keys={})
Tk::Busy.hold(self, keys)
self
end
alias busy_hold busy
def busy_forget
Tk::Busy.forget(self)
self
end
def busy_current?
! Tk::Busy.current(self.path).empty?
end
def busy_status
Tk::Busy.status(self)
end
end

View File

@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Button<Tk::Label class Tk::Button<Tk::Label
TkCommandNames = ['button'.freeze].freeze TkCommandNames = ['button'.freeze].freeze
WidgetClassName = 'Button'.freeze WidgetClassName = 'Button'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('button', @path, *hash_kv(keys, true)) # tk_call_without_enc('button', @path, *hash_kv(keys, true))
@ -27,4 +27,5 @@ class Tk::Button<Tk::Label
end end
#TkButton = Tk::Button unless Object.const_defined? :TkButton #TkButton = Tk::Button unless Object.const_defined? :TkButton
Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton) #Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)
Tk.__set_loaded_toplevel_aliases__('tk/button.rb', :Tk, Tk::Button, :TkButton)

View File

@ -45,7 +45,7 @@ class Tk::Canvas<TkWindow
TkCommandNames = ['canvas'.freeze].freeze TkCommandNames = ['canvas'.freeze].freeze
WidgetClassName = 'Canvas'.freeze WidgetClassName = 'Canvas'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__ def __destroy_hook__
TkcItem::CItemID_TBL.delete(@path) TkcItem::CItemID_TBL.delete(@path)
@ -265,6 +265,12 @@ class Tk::Canvas<TkWindow
self self
end end
def imove(tagOrId, idx, x, y)
tk_send_without_enc('imove', tagid(tagOrId), idx, x, y)
self
end
alias i_move imove
def index(tagOrId, idx) def index(tagOrId, idx)
number(tk_send_without_enc('index', tagid(tagOrId), idx)) number(tk_send_without_enc('index', tagid(tagOrId), idx))
end end
@ -523,11 +529,18 @@ class Tk::Canvas<TkWindow
self self
end end
def move(tag, x, y) def move(tag, dx, dy)
tk_send_without_enc('move', tagid(tag), x, y) tk_send_without_enc('move', tagid(tag), dx, dy)
self self
end end
def moveto(tag, x, y)
# Tcl/Tk 8.6 or later
tk_send_without_enc('moveto', tagid(tag), x, y)
self
end
alias move_to moveto
def postscript(keys) def postscript(keys)
tk_send("postscript", *hash_kv(keys)) tk_send("postscript", *hash_kv(keys))
end end
@ -541,6 +554,15 @@ class Tk::Canvas<TkWindow
self self
end end
def rchars(tag, first, last, str_or_coords)
# Tcl/Tk 8.6 or later
str_or_coords = str_or_coords.flatten if str_or_coords.kinad_of? Array
tk_send_without_enc('rchars', tagid(tag), first, last, str_or_coords)
self
end
alias replace_chars rchars
alias replace_coords rchars
def scale(tag, x, y, xs, ys) def scale(tag, x, y, xs, ys)
tk_send_without_enc('scale', tagid(tag), x, y, xs, ys) tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)
self self
@ -581,7 +603,8 @@ class Tk::Canvas<TkWindow
end end
#TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas #TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas
Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas) #Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
Tk.__set_loaded_toplevel_aliases__('tk/canvas.rb', :Tk, Tk::Canvas, :TkCanvas)
class TkcItem<TkObject class TkcItem<TkObject

View File

@ -60,6 +60,9 @@ module TkcTagAccess
@c.itembindinfo(@id, seq) @c.itembindinfo(@id, seq)
end end
def cget_tkstring(option)
@c.itemcget_tkstring(@id, option)
end
def cget(option) def cget(option)
@c.itemcget(@id, option) @c.itemcget(@id, option)
end end
@ -116,6 +119,13 @@ module TkcTagAccess
self self
end end
def imove(idx, x, y)
# Tcl/Tk 8.6 or later
@c.imove(@id, idx, x, y)
self
end
alias i_move imove
def index(idx) def index(idx)
@c.index(@id, idx) @c.index(@id, idx)
end end
@ -135,6 +145,13 @@ module TkcTagAccess
self self
end end
def moveto(x, y)
# Tcl/Tk 8.6 or later
@c.moveto(@id, x, y)
self
end
alias move_to moveto
def raise(abovethis=None) def raise(abovethis=None)
@c.raise(@id, abovethis) @c.raise(@id, abovethis)
self self
@ -145,6 +162,14 @@ module TkcTagAccess
self self
end end
def rchars(first, last, str_or_coords)
# Tcl/Tk 8.6 or later
@c.rchars(@id, first, last, str_or_coords)
self
end
alias replace_chars rchars
alias replace_coords rchars
def select_adjust(index) def select_adjust(index)
@c.select('adjust', @id, index) @c.select('adjust', @id, index)
self self
@ -203,7 +228,7 @@ class TkcTag<TkObject
CTagID_TBL = TkCore::INTERP.create_table CTagID_TBL = TkCore::INTERP.create_table
(Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint]).instance_eval{ (Tk_CanvasTag_ID = ['ctag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -389,7 +414,7 @@ class TkcTagCurrent<TkcTagString
end end
class TkcGroup<TkcTag class TkcGroup<TkcTag
(Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint]).instance_eval{ (Tk_cGroup_ID = ['tkcg'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -7,7 +7,7 @@ require 'tk/radiobutton'
class Tk::CheckButton<Tk::RadioButton class Tk::CheckButton<Tk::RadioButton
TkCommandNames = ['checkbutton'.freeze].freeze TkCommandNames = ['checkbutton'.freeze].freeze
WidgetClassName = 'Checkbutton'.freeze WidgetClassName = 'Checkbutton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true)) # tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true))
@ -26,5 +26,7 @@ end
Tk::Checkbutton = Tk::CheckButton Tk::Checkbutton = Tk::CheckButton
#TkCheckButton = Tk::CheckButton unless Object.const_defined? :TkCheckButton #TkCheckButton = Tk::CheckButton unless Object.const_defined? :TkCheckButton
#TkCheckbutton = Tk::Checkbutton unless Object.const_defined? :TkCheckbutton #TkCheckbutton = Tk::Checkbutton unless Object.const_defined? :TkCheckbutton
Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton, #Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton,
:TkCheckButton, :TkCheckbutton) # :TkCheckButton, :TkCheckbutton)
Tk.__set_loaded_toplevel_aliases__('tk/checkbutton.rb', :Tk, Tk::CheckButton,
:TkCheckButton, :TkCheckbutton)

View File

@ -145,16 +145,34 @@ module TkComposite
str.chop << ' @epath=' << @epath.inspect << '>' str.chop << ' @epath=' << @epath.inspect << '>'
end end
def _get_opt_method_list(arg)
m_set, m_cget, m_info = arg
m_set = m_set.to_s
m_cget = m_set if !m_cget && self.method(m_set).arity == -1
m_cget = m_cget.to_s if m_cget
m_info = m_info.to_s if m_info
[m_set, m_cget, m_info]
end
private :_get_opt_method_list
def option_methods(*opts) def option_methods(*opts)
opts.each{|m_set, m_cget, m_info| if opts.size == 1 && opts[0].kind_of?(Hash)
m_set = m_set.to_s # {name => [m_set, m_cget, m_info], name => method} style
m_cget = m_set if !m_cget && self.method(m_set).arity == -1 opts[0].each{|name, arg|
m_cget = m_cget.to_s if m_cget m_set, m_cget, m_info = _get_opt_method_list(arg)
m_info = m_info.to_s if m_info @option_methods[name.to_s] = {
@option_methods[m_set] = { :set => m_set, :cget => m_cget, :info => m_info
:set => m_set, :cget => m_cget, :info => m_info }
} }
} else
# [m_set, m_cget, m_info] or method style
opts.each{|arg|
m_set, m_cget, m_info = _get_opt_method_list(arg)
@option_methods[m_set] = {
:set => m_set, :cget => m_cget, :info => m_info
}
}
end
end end
def delegate_alias(alias_opt, option, *wins) def delegate_alias(alias_opt, option, *wins)
@ -215,6 +233,14 @@ module TkComposite
end end
private :__cget_delegates private :__cget_delegates
def cget_tkstring(slot)
if (ret = __cget_delegates(slot)) == None
super(slot)
else
_get_eval_string(ret)
end
end
def cget(slot) def cget(slot)
if (ret = __cget_delegates(slot)) == None if (ret = __cget_delegates(slot)) == None
super(slot) super(slot)

View File

@ -13,7 +13,7 @@ class Tk::Entry<Tk::Label
TkCommandNames = ['entry'.freeze].freeze TkCommandNames = ['entry'.freeze].freeze
WidgetClassName = 'Entry'.freeze WidgetClassName = 'Entry'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# super(__conv_vcmd_on_hash_kv(keys)) # super(__conv_vcmd_on_hash_kv(keys))
@ -116,4 +116,5 @@ class Tk::Entry<Tk::Label
end end
#TkEntry = Tk::Entry unless Object.const_defined? :TkEntry #TkEntry = Tk::Entry unless Object.const_defined? :TkEntry
Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry) #Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)
Tk.__set_loaded_toplevel_aliases__('tk/entry.rb', :Tk, Tk::Entry, :TkEntry)

View File

@ -8,7 +8,7 @@ end
######################## ########################
require 'tkutil' require 'tkutil'
require 'tk' require 'tk' unless Object.const_defined? :TkComm
######################## ########################
@ -482,6 +482,26 @@ module TkEvent
end end
}) })
end end
elsif cmd.respond_to?(:arity) && cmd.arity == 0 # args.size == 0
args = ''
if cmd.kind_of?(String)
id = cmd
elsif cmd.kind_of?(TkCallbackEntry)
id = install_cmd(cmd)
else
id = install_cmd(proc{
begin
TkUtil.eval_cmd(cmd)
rescue Exception=>e
if TkCore::INTERP.kind_of?(TclTkIp)
fail e
else
# MultiTkIp
fail Exception, "#{e.class}: #{e.message.dup}"
end
end
})
end
else else
keys, args = klass._get_all_subst_keys keys, args = klass._get_all_subst_keys

View File

@ -11,7 +11,7 @@ class TkFont
TkCommandNames = ['font'.freeze].freeze TkCommandNames = ['font'.freeze].freeze
(Tk_FontID = ["@font".freeze, "00000".taint]).instance_eval{ (Tk_FontID = ["@font".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -211,7 +211,7 @@ class TkFont
end end
end end
def TkFont.actual_hash(fnt, option=nil) def TkFont.actual_hash(fnt, option=nil)
Hash[TkFont.actual_hash(fnt, option)] Hash[TkFont.actual(fnt, option)]
end end
def TkFont.actual_displayof(fnt, win, option=nil) def TkFont.actual_displayof(fnt, win, option=nil)
@ -224,7 +224,7 @@ class TkFont
end end
end end
def TkFont.actual_hash_displayof(fnt, option=nil) def TkFont.actual_hash_displayof(fnt, option=nil)
Hash[TkFont.actual_hash_displayof(fnt, option)] Hash[TkFont.actual_displayof(fnt, option)]
end end
def TkFont.configure(fnt, slot, value=None) def TkFont.configure(fnt, slot, value=None)
@ -2199,7 +2199,7 @@ module TkFont::CoreMethods
alias measure_core measure_core_tk4x alias measure_core measure_core_tk4x
alias metrics_core metrics_core_tk4x alias metrics_core metrics_core_tk4x
when /^8\.[0-5]/ when /^8\.[0-9]/
alias actual_core actual_core_tk8x alias actual_core actual_core_tk8x
alias configure_core configure_core_tk8x alias configure_core configure_core_tk8x
alias configinfo_core configinfo_core_tk8x alias configinfo_core configinfo_core_tk8x
@ -2342,3 +2342,10 @@ if Tk::TCL_MAJOR_VERSION > 8 ||
'systemDetailSystemFont', 'systemDetailEmphasizedSystemFont' 'systemDetailSystemFont', 'systemDetailEmphasizedSystemFont'
] ]
end end
#######################################
# autoload
#######################################
class TkFont
autoload :Chooser, 'tk/fontchooser'
end

View File

@ -0,0 +1,166 @@
#
# tk/fontchooser.rb -- "tk fontchooser" support (Tcl/Tk8.6 or later)
#
require 'tk'
require 'tk/font'
module TkFont::Chooser
extend TkCore
end
class << TkFont::Chooser
def method_missing(id, *args)
name = id.id2name
case args.length
when 1
if name[-1] == ?=
configure name[0..-2], args[0]
args[0]
else
configure name, args[0]
self
end
when 0
begin
cget(name)
rescue
super(id, *args)
end
else
super(id, *args)
end
end
def __conviginfo_value(key, val)
case key
when 'parent'
window(val)
when 'title'
val
when 'font'
if (lst = tk_split_simplelist(val)).size == 1
lst[0]
else
lst.map{|elem| num_or_str(elem)}
end
when 'command'
tk_tcl2ruby(val)
when 'visible'
bool(val)
else # unkown
val
end
end
private :__conviginfo_value
def configinfo(option=nil)
if !option && TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
lst = tk_split_simplelist(tk_call('tk', 'fontchooser', 'configure'))
ret = []
TkComm.slice_ary(lst, 2){|k, v|
k = k[1..-1]
ret << [k, __conviginfo_value(k, v)]
}
ret
else
current_configinfo(option)
end
end
def current_configinfo(option=nil)
if option
opt = option.to_s
fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.empty?
__conviginfo_value(option.to_s, tk_call('tk','fontchooser',
'configure',"-#{opt}"))
else
lst = tk_split_simplelist(tk_call('tk', 'fontchooser', 'configure'))
ret = {}
TkComm.slice_ary(lst, 2){|k, v|
k = k[1..-1]
ret[k] = __conviginfo_value(k, v)
}
ret
end
end
def configure(option, value=None)
if option.kind_of? Hash
tk_call('tk', 'fontchooser', 'configure',
*hash_kv(_symbolkey2str(option)))
else
opt = option.to_s
fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.empty?
tk_call('tk', 'fontchooser', 'configure', "-#{opt}", value)
end
self
end
def configure_cmd(slot, value)
configure(slot, install_cmd(value))
end
def command(cmd=nil, &b)
if cmd
configure_cmd('command', cmd)
elsif b
configure_cmd('command', Proc.new(&b))
else
cget('command')
end
end
def cget(slot)
configinfo slot
end
def [](slot)
cget slot
end
def []=(slot, val)
configure slot, val
val
end
def show
tk_call('tk', 'fontchooser', 'show')
self
end
def hide
tk_call('tk', 'fontchooser', 'hide')
self
end
def toggle
cget(:visible) ? hide: show
self
end
def set_for(target, title="Font")
if target.kind_of? TkFont
configs = {
:font=>target.actual_hash,
:command=>proc{|fnt, *args|
target.configure(TkFont.actual_hash(fnt))
}
}
else
configs = {
:font=>target.cget_tkstring(:font),
:command=>proc{|fnt, *args|
target.font = TkFont.actual_hash_displayof(fnt, target)
}
}
end
configs[:title] = title if title
configure(configs)
target
end
def unset
configure(:command, nil)
end
end

View File

@ -6,7 +6,7 @@ require 'tk'
class Tk::Frame<TkWindow class Tk::Frame<TkWindow
TkCommandNames = ['frame'.freeze].freeze TkCommandNames = ['frame'.freeze].freeze
WidgetClassName = 'Frame'.freeze WidgetClassName = 'Frame'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
################# old version ################# old version
# def initialize(parent=nil, keys=nil) # def initialize(parent=nil, keys=nil)
@ -128,4 +128,5 @@ class Tk::Frame<TkWindow
end end
#TkFrame = Tk::Frame unless Object.const_defined? :TkFrame #TkFrame = Tk::Frame unless Object.const_defined? :TkFrame
Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame) #Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)
Tk.__set_loaded_toplevel_aliases__('tk/frame.rb', :Tk, Tk::Frame, :TkFrame)

View File

@ -11,7 +11,7 @@ class TkImage<TkObject
Tk_IMGTBL = TkCore::INTERP.create_table Tk_IMGTBL = TkCore::INTERP.create_table
(Tk_Image_ID = ['i'.freeze, '00000'.taint]).instance_eval{ (Tk_Image_ID = ['i'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -162,6 +162,13 @@ module TkItemConfigMethod
################################################ ################################################
def itemcget_tkstring(tagOrId, option)
opt = option.to_s
fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{opt}"))
end
def __itemcget_core(tagOrId, option) def __itemcget_core(tagOrId, option)
orig_opt = option orig_opt = option
option = option.to_s option = option.to_s

View File

@ -6,7 +6,7 @@ require 'tk'
class Tk::Label<TkWindow class Tk::Label<TkWindow
TkCommandNames = ['label'.freeze].freeze TkCommandNames = ['label'.freeze].freeze
WidgetClassName = 'Label'.freeze WidgetClassName = 'Label'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('label', @path, *hash_kv(keys, true)) # tk_call_without_enc('label', @path, *hash_kv(keys, true))
@ -18,4 +18,5 @@ class Tk::Label<TkWindow
end end
#TkLabel = Tk::Label unless Object.const_defined? :TkLabel #TkLabel = Tk::Label unless Object.const_defined? :TkLabel
Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel) #Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)
Tk.__set_loaded_toplevel_aliases__('tk/label.rb', :Tk, Tk::Label, :TkLabel)

View File

@ -7,7 +7,7 @@ require 'tk/frame'
class Tk::LabelFrame<Tk::Frame class Tk::LabelFrame<Tk::Frame
TkCommandNames = ['labelframe'.freeze].freeze TkCommandNames = ['labelframe'.freeze].freeze
WidgetClassName = 'Labelframe'.freeze WidgetClassName = 'Labelframe'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('labelframe', @path, *hash_kv(keys, true)) # tk_call_without_enc('labelframe', @path, *hash_kv(keys, true))
@ -26,4 +26,6 @@ end
Tk::Labelframe = Tk::LabelFrame Tk::Labelframe = Tk::LabelFrame
#TkLabelFrame = Tk::LabelFrame unless Object.const_defined? :TkLabelFrame #TkLabelFrame = Tk::LabelFrame unless Object.const_defined? :TkLabelFrame
#TkLabelframe = Tk::Labelframe unless Object.const_defined? :TkLabelframe #TkLabelframe = Tk::Labelframe unless Object.const_defined? :TkLabelframe
Tk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe) #Tk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe)
Tk.__set_loaded_toplevel_aliases__('tk/labelframe.rb', :Tk, Tk::LabelFrame,
:TkLabelFrame, :TkLabelframe)

View File

@ -21,7 +21,7 @@ class Tk::Listbox<TkTextWin
TkCommandNames = ['listbox'.freeze].freeze TkCommandNames = ['listbox'.freeze].freeze
WidgetClassName = 'Listbox'.freeze WidgetClassName = 'Listbox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
@ -279,4 +279,6 @@ class Tk::Listbox<TkTextWin
end end
#TkListbox = Tk::Listbox unless Object.const_defined? :TkListbox #TkListbox = Tk::Listbox unless Object.const_defined? :TkListbox
Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox) #Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)
Tk.__set_loaded_toplevel_aliases__('tk/listbox.rb', :Tk, Tk::Listbox,
:TkListbox)

View File

@ -23,7 +23,9 @@ end
module Tk::MacResource module Tk::MacResource
end end
#TkMacResource = Tk::MacResource #TkMacResource = Tk::MacResource
Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource) #Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)
Tk.__set_loaded_toplevel_aliases__('tk/macpkg.rb', :Tk, Tk::MacResource,
:TkMacResource)
module Tk::MacResource module Tk::MacResource
extend Tk extend Tk

View File

@ -33,13 +33,14 @@ module TkMenuEntryConfig
end end
private :__item_val2ruby_optkeys private :__item_val2ruby_optkeys
alias entrycget_tkstring itemcget_tkstring
alias entrycget itemcget alias entrycget itemcget
alias entrycget_strict itemcget_strict alias entrycget_strict itemcget_strict
alias entryconfigure itemconfigure alias entryconfigure itemconfigure
alias entryconfiginfo itemconfiginfo alias entryconfiginfo itemconfiginfo
alias current_entryconfiginfo current_itemconfiginfo alias current_entryconfiginfo current_itemconfiginfo
private :itemcget, :itemcget_strict private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end end
@ -50,7 +51,7 @@ class Tk::Menu<TkWindow
TkCommandNames = ['menu'.freeze].freeze TkCommandNames = ['menu'.freeze].freeze
WidgetClassName = 'Menu'.freeze WidgetClassName = 'Menu'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
@ -386,9 +387,33 @@ class Tk::Menu<TkWindow
end end
#TkMenu = Tk::Menu unless Object.const_defined? :TkMenu #TkMenu = Tk::Menu unless Object.const_defined? :TkMenu
Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu) #Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::Menu, :TkMenu)
module Tk::Menu::TkInternalFunction; end
class << Tk::Menu::TkInternalFunction
# These methods calls internal functions of Tcl/Tk.
# So, They may not work on your Tcl/Tk.
def next_menu(menu, dir='next')
dir = dir.to_s
case dir
when 'next', 'forward', 'down'
dir = 'right'
when 'previous', 'backward', 'up'
dir = 'left'
end
Tk.tk_call('::tk::MenuNextMenu', menu, dir)
end
def next_entry(menu, delta)
# delta is increment value of entry index.
# For example, +1 denotes 'next entry' and -1 denotes 'previous entry'.
Tk.tk_call('::tk::MenuNextEntry', menu, delta)
end
end
class Tk::MenuClone<Tk::Menu class Tk::MenuClone<Tk::Menu
=begin =begin
def initialize(parent, type=None) def initialize(parent, type=None)
@ -446,7 +471,9 @@ end
Tk::CloneMenu = Tk::MenuClone Tk::CloneMenu = Tk::MenuClone
#TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone #TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone
#TkCloneMenu = Tk::CloneMenu unless Object.const_defined? :TkCloneMenu #TkCloneMenu = Tk::CloneMenu unless Object.const_defined? :TkCloneMenu
Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu) #Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::MenuClone,
:TkMenuClone, :TkCloneMenu)
module Tk::SystemMenu module Tk::SystemMenu
def initialize(parent, keys=nil) def initialize(parent, keys=nil)
@ -480,7 +507,9 @@ class Tk::SysMenu_Help<Tk::Menu
SYSMENU_NAME = 'help' SYSMENU_NAME = 'help'
end end
#TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help #TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help
Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help) #Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_Help,
:TkSysMenu_Help)
class Tk::SysMenu_System<Tk::Menu class Tk::SysMenu_System<Tk::Menu
@ -489,7 +518,9 @@ class Tk::SysMenu_System<Tk::Menu
SYSMENU_NAME = 'system' SYSMENU_NAME = 'system'
end end
#TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System #TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System
Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System) #Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_System,
:TkSysMenu_System)
class Tk::SysMenu_Apple<Tk::Menu class Tk::SysMenu_Apple<Tk::Menu
@ -498,13 +529,15 @@ class Tk::SysMenu_Apple<Tk::Menu
SYSMENU_NAME = 'apple' SYSMENU_NAME = 'apple'
end end
#TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple #TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple
Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple) #Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_Apple,
:TkSysMenu_Apple)
class Tk::Menubutton<Tk::Label class Tk::Menubutton<Tk::Label
TkCommandNames = ['menubutton'.freeze].freeze TkCommandNames = ['menubutton'.freeze].freeze
WidgetClassName = 'Menubutton'.freeze WidgetClassName = 'Menubutton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def create_self(keys) def create_self(keys)
if keys and keys != None if keys and keys != None
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
@ -541,7 +574,9 @@ end
Tk::MenuButton = Tk::Menubutton Tk::MenuButton = Tk::Menubutton
#TkMenubutton = Tk::Menubutton unless Object.const_defined? :TkMenubutton #TkMenubutton = Tk::Menubutton unless Object.const_defined? :TkMenubutton
#TkMenuButton = Tk::MenuButton unless Object.const_defined? :TkMenuButton #TkMenuButton = Tk::MenuButton unless Object.const_defined? :TkMenuButton
Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton) #Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::Menubutton,
:TkMenubutton, :TkMenuButton)
class Tk::OptionMenubutton<Tk::Menubutton class Tk::OptionMenubutton<Tk::Menubutton
@ -677,5 +712,7 @@ end
Tk::OptionMenuButton = Tk::OptionMenubutton Tk::OptionMenuButton = Tk::OptionMenubutton
#TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton #TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton
#TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton #TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton
Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton, #Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
:TkOptionMenubutton, :TkOptionMenuButton) # :TkOptionMenubutton, :TkOptionMenuButton)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::OptionMenubutton,
:TkOptionMenubutton, :TkOptionMenuButton)

View File

@ -93,24 +93,30 @@ class TkMenubar<Tk::Frame
include TkComposite include TkComposite
include TkMenuSpec include TkMenuSpec
def initialize(parent = nil, spec = nil, options = nil) def initialize(parent = nil, spec = nil, options = {})
if parent.kind_of? Hash if parent.kind_of? Hash
options = _symbolkey2str(parent) options = parent
spec = options.delete('spec') parent = nil
super(options) spec = (options.has_key?('spec'))? options.delete('spec'): nil
else
super(parent, options)
end end
_symbolkey2str(options)
menuspec_opt = {}
TkMenuSpec::MENUSPEC_OPTKEYS.each{|key|
menuspec_opt[key] = options.delete(key) if options.has_key?(key)
}
super(parent, options)
@menus = [] @menus = []
spec.each{|info| add_menu(info)} if spec spec.each{|info| add_menu(info, menuspec_opt)} if spec
options.each{|key, value| configure(key, value)} if options options.each{|key, value| configure(key, value)} if options
end end
def add_menu(menu_info) def add_menu(menu_info, menuspec_opt={})
mbtn, menu = _create_menubutton(@frame, menu_info) mbtn, menu = _create_menubutton(@frame, menu_info, menuspec_opt)
submenus = _get_cascade_menus(menu).flatten submenus = _get_cascade_menus(menu).flatten

View File

@ -7,9 +7,12 @@
# This file can be distributed under the terms of the Ruby. # This file can be distributed under the terms of the Ruby.
# #
# The format of the menu_spec is: # The format of the menu_spec is:
# [ menu_info, menu_info, ... ] # [ menubutton_info, menubutton_info, ... ]
# #
# And the format of the menu_info is: # The format of the menubutton_info is:
# [ menubutton_info, entry_info, entry_info, ... ]
#
# And each format of *_info is:
# [ # [
# [text, underline, configs], # menu button/entry (*1) # [text, underline, configs], # menu button/entry (*1)
# [label, command, underline, accelerator, configs], # command entry # [label, command, underline, accelerator, configs], # command entry
@ -22,12 +25,24 @@
# ... # ...
# ] # ]
# #
# A menu_info is an array of menu entries:
# [ entry_info, entry_info, ... ]
#
#
# underline, accelerator, and configs are optional pearameters. # underline, accelerator, and configs are optional pearameters.
# Hashes are OK instead of Arrays. Then the entry type ('command', # Hashes are OK instead of Arrays. Then the entry type ('command',
# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key # 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key
# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info # (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info
# is acceptable for 'menu' key (then, create sub-menu). # is acceptable for 'menu' key (then, create sub-menu).
# #
# If the value of underline is true instead of an integer,
# check whether the text/label string contains a '&' character.
# When includes, the first '&' is removed and its following character is
# converted the corresponding 'underline' option (first '&' is removed).
# Else if the value of underline is a String or a Regexp,
# use the result of label.index(underline) as the index of underline
# (don't remove matched substring).
#
# NOTE: (*1) # NOTE: (*1)
# If you want to make special menus (*.help for UNIX, *.system for Win, # 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, # and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX,
@ -39,6 +54,10 @@
# to the configs of the cascade entry. # to the configs of the cascade entry.
module TkMenuSpec module TkMenuSpec
extend TkMenuSpec
MENUSPEC_OPTKEYS = [ 'layout_proc' ]
def _create_menu(parent, menu_info, menu_name = nil, def _create_menu(parent, menu_info, menu_name = nil,
tearoff = false, default_opts = nil) tearoff = false, default_opts = nil)
if tearoff.kind_of?(Hash) if tearoff.kind_of?(Hash)
@ -59,6 +78,7 @@ module TkMenuSpec
end end
tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff') tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')
tearoff = false unless tearoff # nil --> false
if menu_name if menu_name
#menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff) #menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
@ -84,6 +104,23 @@ module TkMenuSpec
tearoff, menu_opts) tearoff, menu_opts)
options['menu'] = submenu options['menu'] = submenu
end end
case options['underline']
when String, Regexp
if options['label'] &&
(idx = options['label'].index(options['underline']))
options['underline'] = idx
else
options['underline'] = -1
end
when true
if options['label'] && (idx = options['label'].index('&'))
options['label'] = options['label'].dup
options['label'][idx] = ''
options['underline'] = idx
else
options['underline'] = -1
end
end
menu.add(item_type, options) menu.add(item_type, options)
elsif item_info.kind_of?(Array) elsif item_info.kind_of?(Array)
@ -138,6 +175,25 @@ module TkMenuSpec
end end
options.update(opts) options.update(opts)
end end
case options['underline']
when String, Regexp
if options['label'] &&
(idx = options['label'].index(options['underline']))
options['underline'] = idx
else
options['underline'] = -1
end
when true
if options['label'] && (idx = options['label'].index('&'))
options['label'] = options['label'].dup
options['label'][idx] = ''
options['underline'] = idx
else
options['underline'] = -1
end
end
menu.add(item_type, options) menu.add(item_type, options)
elsif /^-+$/ =~ item_info elsif /^-+$/ =~ item_info
@ -177,7 +233,7 @@ module TkMenuSpec
end end
private :_create_menu_for_menubar private :_create_menu_for_menubar
def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil) def _create_menubutton(parent, menu_info, tearoff=false, default_opts = {})
btn_info = menu_info[0] btn_info = menu_info[0]
if tearoff.kind_of?(Hash) if tearoff.kind_of?(Hash)
@ -186,14 +242,49 @@ module TkMenuSpec
end end
if default_opts.kind_of?(Hash) if default_opts.kind_of?(Hash)
keys = _symbolkey2str(default_opts) default_opts = _symbolkey2str(default_opts)
else
keys = {} if default_opts.has_key?('layout_proc')
layout_proc = default_opts.delete('layout_proc')
end
_vertical_mbar_bind_proc = proc{|m, dir|
Tk::Menu::TkInternalFunction.next_menu(m, dir) rescue nil
# ignore error when the internal function doesn't exist
}
case layout_proc
when :vertical, 'vertical', :vertical_left, 'vertical_left'
layout_proc = proc{|_parent, _mbtn|
_mbtn.direction :right
_mbtn.pack(:side=>:top, :fill=>:x)
menu = _mbtn.menu
menu.bind('Tab', _vertical_mbar_bind_proc, :widget, 'forward')
menu.bind('Alt-Tab', _vertical_mbar_bind_proc, :widget, 'backward')
}
when :vertical_right, 'vertical_right'
layout_proc = proc{|_parent, _mbtn|
_mbtn.direction :left
_mbtn.pack(:side=>:top, :fill=>:x)
menu = _mbtn.menu
menu.bind('Tab', _vertical_mbar_bind_proc, :widget, 'forward')
menu.bind('Alt-Tab', _vertical_mbar_bind_proc, :widget, 'backward')
}
when :horizontal, 'horizontal'
layout_proc = proc{|_parent, _mbtn| _mbtn.pack(:side=>:left)}
else
# do nothing
end
end end
tearoff = keys.delete('tearoff') if keys.key?('tearoff') keys = default_opts.dup
if _use_menubar?(parent) tearoff = keys.delete('tearoff') if keys.key?('tearoff')
tearoff = false unless tearoff # nil --> false
if _use_menubar?(parent) && ! layout_proc
# menubar by menu entries # menubar by menu entries
mbar = _create_menu_for_menubar(parent) mbar = _create_menu_for_menubar(parent)
@ -202,14 +293,52 @@ module TkMenuSpec
if btn_info.kind_of?(Hash) if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info)) keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name') menu_name = keys.delete('menu_name')
keys['label'] = keys.delete('text') if keys.key?('text') keys['label'] = keys.delete('text') || ''
case keys['underline']
when String, Regexp
if idx = keys['label'].index(keys['underline'])
keys['underline'] = idx
else
keys['underline'] = -1
end
when true
if idx = keys['label'].index('&')
keys['label'] = keys['label'].dup
keys['label'][idx] = ''
keys['underline'] = idx
else
keys['underline'] = -1
end
end
elsif btn_info.kind_of?(Array) elsif btn_info.kind_of?(Array)
keys['label'] = btn_info[0] if btn_info[0] keys['label'] = btn_info[0] if btn_info[0]
keys['underline'] = btn_info[1] if btn_info[1]
case btn_info[1]
when Integer
keys['underline'] = btn_info[1]
when String, Regexp
if idx = keys['label'].index(btn_info[1])
keys['underline'] = idx
else
keys['underline'] = -1
end
when true
if idx = keys['label'].index('&')
keys['label'] = keys['label'].dup
keys['label'][idx] = ''
keys['underline'] = idx
else
keys['underline'] = -1
end
end
if btn_info[2]&&btn_info[2].kind_of?(Hash) if btn_info[2]&&btn_info[2].kind_of?(Hash)
keys.update(_symbolkey2str(btn_info[2])) keys.update(_symbolkey2str(btn_info[2]))
menu_name = keys.delete('menu_name') menu_name = keys.delete('menu_name')
end end
else else
keys = {:label=>btn_info} keys = {:label=>btn_info}
end end
@ -234,9 +363,42 @@ module TkMenuSpec
if btn_info.kind_of?(Hash) if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info)) keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name') menu_name = keys.delete('menu_name')
keys['text'] = keys.delete('label') if keys.key?('label') keys['text'] = keys.delete('label') || ''
case keys['underline']
when String, Regexp
if idx = keys['text'].index(keys['underline'])
keys['underline'] = idx
else
keys['underline'] = -1
end
when true
if idx = keys['text'].index('&')
keys['text'] = keys['text'].dup
keys['text'][idx] = ''
keys['underline'] = idx
else
keys['underline'] = -1
end
end
mbtn.configure(keys) mbtn.configure(keys)
elsif btn_info.kind_of?(Array) elsif btn_info.kind_of?(Array)
case btn_info[1]
when String, Regexp
if btn_info[0] && (idx = btn_info[0].index(btn_info[1]))
btn_info[1] = idx
else
btn_info[1] = -1
end
when true
if btn_info[0] && (idx = btn_info[0].index('&'))
btn_info[0] = btn_info[0].dup
btn_info[0][idx] = ''
btn_info[1] = idx
else
btn_info[1] = -1
end
end
mbtn.configure('text', btn_info[0]) if btn_info[0] mbtn.configure('text', btn_info[0]) if btn_info[0]
mbtn.configure('underline', btn_info[1]) if btn_info[1] mbtn.configure('underline', btn_info[1]) if btn_info[1]
# mbtn.configure('accelerator', btn_info[2]) if btn_info[2] # mbtn.configure('accelerator', btn_info[2]) if btn_info[2]
@ -245,22 +407,41 @@ module TkMenuSpec
menu_name = keys.delete('menu_name') menu_name = keys.delete('menu_name')
mbtn.configure(keys) mbtn.configure(keys)
end end
else else
mbtn.configure('text', btn_info) mbtn.configure('text', btn_info)
end end
mbtn.pack('side' => 'left')
menu = _create_menu(mbtn, menu_info[1..-1], menu_name, menu = _create_menu(mbtn, menu_info[1..-1], menu_name,
tearoff, default_opts) tearoff, default_opts)
mbtn.menu(menu) mbtn.menu(menu)
if layout_proc.kind_of?(Proc) || layout_proc.kind_of?(Method)
# e.g. make a vertical menubar
# :layout_proc => proc{|parent, btn| btn.pack(:side=>:top, :fill=>:x)}
layout_proc.call(parent, mbtn)
else
mbtn.pack('side' => 'left')
end
[mbtn, menu] [mbtn, menu]
end end
end end
private :_create_menubutton private :_create_menubutton
def _create_menubar(parent, menu_spec, tearoff = false, opts = nil)
if tearoff.kind_of?(Hash)
opts = tearoff
tearoff = false
end
tearoff = false unless tearoff # nil --> false
menu_spec.each{|menu_info|
_create_menubutton(parent, menu_info, tearoff, opts)
}
parent
end
private :_create_menubar
def _get_cascade_menus(menu) def _get_cascade_menus(menu)
menus = [] menus = []
(0..(menu.index('last'))).each{|idx| (0..(menu.index('last'))).each{|idx|

View File

@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Message<Tk::Label class Tk::Message<Tk::Label
TkCommandNames = ['message'.freeze].freeze TkCommandNames = ['message'.freeze].freeze
WidgetClassName = 'Message'.freeze WidgetClassName = 'Message'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('message', @path, *hash_kv(keys, true)) # tk_call_without_enc('message', @path, *hash_kv(keys, true))
@ -19,4 +19,6 @@ class Tk::Message<Tk::Label
end end
#TkMessage = Tk::Message unless Object.const_defined? :TkMessage #TkMessage = Tk::Message unless Object.const_defined? :TkMessage
Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage) #Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)
Tk.__set_loaded_toplevel_aliases__('tk/message.rb', :Tk, Tk::Message,
:TkMessage)

View File

@ -36,7 +36,7 @@ class TkMsgCatalog < TkObject
MSGCAT_EXT = '.msg' MSGCAT_EXT = '.msg'
UNKNOWN_CBTBL = Hash.new{|hash,key| hash[key] = {}}.taint UNKNOWN_CBTBL = TkUtil.untrust(Hash.new{|hash,key| hash[key] = {}})
TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL') TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL')
if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} { if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} {

View File

@ -13,7 +13,7 @@ class TkNamespace < TkObject
Tk_Namespace_ID_TBL = TkCore::INTERP.create_table Tk_Namespace_ID_TBL = TkCore::INTERP.create_table
(Tk_Namespace_ID = ["ns".freeze, "00000".taint]).instance_eval{ (Tk_Namespace_ID = ["ns".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -8,7 +8,7 @@ module TkOptionDB
extend Tk extend Tk
TkCommandNames = ['option'.freeze].freeze TkCommandNames = ['option'.freeze].freeze
(CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint]).instance_eval{ (CmdClassID = ['CMD_CLASS'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -6,7 +6,7 @@ require 'tk'
class Tk::PanedWindow<TkWindow class Tk::PanedWindow<TkWindow
TkCommandNames = ['panedwindow'.freeze].freeze TkCommandNames = ['panedwindow'.freeze].freeze
WidgetClassName = 'Panedwindow'.freeze WidgetClassName = 'Panedwindow'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true)) # tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true))
@ -254,5 +254,7 @@ end
Tk::Panedwindow = Tk::PanedWindow Tk::Panedwindow = Tk::PanedWindow
#TkPanedWindow = Tk::PanedWindow unless Object.const_defined? :TkPanedWindow #TkPanedWindow = Tk::PanedWindow unless Object.const_defined? :TkPanedWindow
#TkPanedwindow = Tk::Panedwindow unless Object.const_defined? :TkPanedwindow #TkPanedwindow = Tk::Panedwindow unless Object.const_defined? :TkPanedwindow
Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow, #Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow,
:TkPanedWindow, :TkPanedwindow) # :TkPanedWindow, :TkPanedwindow)
Tk.__set_loaded_toplevel_aliases__('tk/panedwindow.rb', :Tk, Tk::PanedWindow,
:TkPanedWindow, :TkPanedwindow)

View File

@ -7,7 +7,7 @@ require 'tk/button'
class Tk::RadioButton<Tk::Button class Tk::RadioButton<Tk::Button
TkCommandNames = ['radiobutton'.freeze].freeze TkCommandNames = ['radiobutton'.freeze].freeze
WidgetClassName = 'Radiobutton'.freeze WidgetClassName = 'Radiobutton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys) #def create_self(keys)
# if keys and keys != None # if keys and keys != None
# tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true)) # tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true))
@ -67,5 +67,7 @@ end
Tk::Radiobutton = Tk::RadioButton Tk::Radiobutton = Tk::RadioButton
#TkRadioButton = Tk::RadioButton unless Object.const_defined? :TkRadioButton #TkRadioButton = Tk::RadioButton unless Object.const_defined? :TkRadioButton
#TkRadiobutton = Tk::Radiobutton unless Object.const_defined? :TkRadiobutton #TkRadiobutton = Tk::Radiobutton unless Object.const_defined? :TkRadiobutton
Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton, #Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton,
:TkRadioButton, :TkRadiobutton) # :TkRadioButton, :TkRadiobutton)
Tk.__set_loaded_toplevel_aliases__('tk/radiobutton.rb', :Tk, Tk::RadioButton,
:TkRadioButton, :TkRadiobutton)

View File

@ -52,7 +52,7 @@ class Tk::Root<TkWindow
end end
WidgetClassName = 'Tk'.freeze WidgetClassName = 'Tk'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def self.to_eval def self.to_eval
# self::WidgetClassName # self::WidgetClassName

View File

@ -6,7 +6,7 @@ require 'tk'
class Tk::Scale<TkWindow class Tk::Scale<TkWindow
TkCommandNames = ['scale'.freeze].freeze TkCommandNames = ['scale'.freeze].freeze
WidgetClassName = 'Scale'.freeze WidgetClassName = 'Scale'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def create_self(keys) def create_self(keys)
if keys and keys != None if keys and keys != None
@ -108,4 +108,5 @@ class Tk::Scale<TkWindow
end end
#TkScale = Tk::Scale unless Object.const_defined? :TkScale #TkScale = Tk::Scale unless Object.const_defined? :TkScale
Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale) #Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)
Tk.__set_loaded_toplevel_aliases__('tk/scale.rb', :Tk, Tk::Scale, :TkScale)

View File

@ -6,7 +6,7 @@ require 'tk'
class Tk::Scrollbar<TkWindow class Tk::Scrollbar<TkWindow
TkCommandNames = ['scrollbar'.freeze].freeze TkCommandNames = ['scrollbar'.freeze].freeze
WidgetClassName = 'Scrollbar'.freeze WidgetClassName = 'Scrollbar'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def create_self(keys) def create_self(keys)
@assigned = [] @assigned = []
@ -148,7 +148,9 @@ class Tk::Scrollbar<TkWindow
end end
#TkScrollbar = Tk::Scrollbar unless Object.const_defined? :TkScrollbar #TkScrollbar = Tk::Scrollbar unless Object.const_defined? :TkScrollbar
Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar) #Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)
Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::Scrollbar,
:TkScrollbar)
class Tk::XScrollbar<Tk::Scrollbar class Tk::XScrollbar<Tk::Scrollbar
@ -161,7 +163,9 @@ class Tk::XScrollbar<Tk::Scrollbar
end end
#TkXScrollbar = Tk::XScrollbar unless Object.const_defined? :TkXScrollbar #TkXScrollbar = Tk::XScrollbar unless Object.const_defined? :TkXScrollbar
Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar) #Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)
Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::XScrollbar,
:TkXScrollbar)
class Tk::YScrollbar<Tk::Scrollbar class Tk::YScrollbar<Tk::Scrollbar
@ -174,4 +178,6 @@ class Tk::YScrollbar<Tk::Scrollbar
end end
#TkYScrollbar = Tk::YScrollbar unless Object.const_defined? :TkYScrollbar #TkYScrollbar = Tk::YScrollbar unless Object.const_defined? :TkYScrollbar
Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar) #Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)
Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::YScrollbar,
:TkYScrollbar)

View File

@ -8,7 +8,7 @@ require 'tk/entry'
class Tk::Spinbox<Tk::Entry class Tk::Spinbox<Tk::Entry
TkCommandNames = ['spinbox'.freeze].freeze TkCommandNames = ['spinbox'.freeze].freeze
WidgetClassName = 'Spinbox'.freeze WidgetClassName = 'Spinbox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
class SpinCommand < TkValidateCommand class SpinCommand < TkValidateCommand
class ValidateArgs < TkUtil::CallbackSubst class ValidateArgs < TkUtil::CallbackSubst
@ -100,13 +100,36 @@ class Tk::Spinbox<Tk::Entry
tk_send_without_enc('identify', x, y) tk_send_without_enc('identify', x, y)
end end
def invoke(elem)
tk_send_without_enc('invoke', elem)
self
end
def spinup def spinup
tk_send_without_enc('invoke', 'spinup') begin
tk_send_without_enc('invoke', 'buttonup')
rescue RuntimeError => e
# old version of element?
begin
tk_send_without_enc('invoke', 'spinup')
rescue
fail e
end
end
self self
end end
def spindown def spindown
tk_send_without_enc('invoke', 'spindown') begin
tk_send_without_enc('invoke', 'buttondown')
rescue RuntimeError => e
# old version of element?
begin
tk_send_without_enc('invoke', 'spinup')
rescue
fail e
end
end
self self
end end
@ -116,4 +139,6 @@ class Tk::Spinbox<Tk::Entry
end end
#TkSpinbox = Tk::Spinbox unless Object.const_defined? :TkSpinbox #TkSpinbox = Tk::Spinbox unless Object.const_defined? :TkSpinbox
Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox) #Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)
Tk.__set_loaded_toplevel_aliases__('tk/spinbox.rb', :Tk, Tk::Spinbox,
:TkSpinbox)

View File

@ -29,6 +29,9 @@ module TkTextTagConfig
end end
private :__item_pathname private :__item_pathname
def tag_cget_tkstring(tagOrId, option)
itemcget_tkstring(['tag', tagOrId], option)
end
def tag_cget(tagOrId, option) def tag_cget(tagOrId, option)
itemcget(['tag', tagOrId], option) itemcget(['tag', tagOrId], option)
end end
@ -45,6 +48,9 @@ module TkTextTagConfig
current_itemconfiginfo(['tag', tagOrId], slot) current_itemconfiginfo(['tag', tagOrId], slot)
end end
def window_cget_tkstring(tagOrId, option)
itemcget_tkstring(['window', tagOrId], option)
end
def window_cget(tagOrId, option) def window_cget(tagOrId, option)
itemcget(['window', tagOrId], option) itemcget(['window', tagOrId], option)
end end
@ -61,7 +67,7 @@ module TkTextTagConfig
current_itemconfiginfo(['window', tagOrId], slot) current_itemconfiginfo(['window', tagOrId], slot)
end end
private :itemcget, :itemcget_strict private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end end
@ -251,7 +257,7 @@ class Tk::Text<TkTextWin
TkCommandNames = ['text'.freeze].freeze TkCommandNames = ['text'.freeze].freeze
WidgetClassName = 'Text'.freeze WidgetClassName = 'Text'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def self.new(*args, &block) def self.new(*args, &block)
obj = super(*args){} obj = super(*args){}
@ -1570,7 +1576,8 @@ class Tk::Text<TkTextWin
end end
#TkText = Tk::Text unless Object.const_defined? :TkText #TkText = Tk::Text unless Object.const_defined? :TkText
Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText) #Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)
Tk.__set_loaded_toplevel_aliases__('tk/text.rb', :Tk, Tk::Text, :TkText)
####################################### #######################################
@ -1587,7 +1594,8 @@ class Tk::Text::Peer < Tk::Text
def create_self(keys) def create_self(keys)
if keys and keys != None if keys and keys != None
tk_call_without_enc(@src_text.path, 'peer', 'create', @path) tk_call_without_enc(@src_text.path, 'peer', 'create',
@path, *hash_kv(keys, true))
else else
tk_call_without_enc(@src_text.path, 'peer', 'create', @path) tk_call_without_enc(@src_text.path, 'peer', 'create', @path)
end end

View File

@ -9,7 +9,7 @@ class TkTextMark<TkObject
TMarkID_TBL = TkCore::INTERP.create_table TMarkID_TBL = TkCore::INTERP.create_table
(Tk_TextMark_ID = ['mark'.freeze, '00000'.taint]).instance_eval{ (Tk_TextMark_ID = ['mark'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -11,7 +11,7 @@ class TkTextTag<TkObject
TTagID_TBL = TkCore::INTERP.create_table TTagID_TBL = TkCore::INTERP.create_table
(Tk_TextTag_ID = ['tag'.freeze, '00000'.taint]).instance_eval{ (Tk_TextTag_ID = ['tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -129,6 +129,9 @@ class TkTextTag<TkObject
val val
end end
def cget_tkstring(key)
@t.tag_cget_tkstring @id, key
end
def cget(key) def cget(key)
@t.tag_cget @id, key @t.tag_cget @id, key
end end

View File

@ -11,13 +11,13 @@ class TkTimer
TkCommandNames = ['after'.freeze].freeze TkCommandNames = ['after'.freeze].freeze
(Tk_CBID = ['a'.freeze, '00000'.taint]).instance_eval{ (Tk_CBID = ['a'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
} }
Tk_CBTBL = {}.taint Tk_CBTBL = TkUtil.untrust({})
TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL') TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')
if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} { if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} {

View File

@ -11,7 +11,7 @@ class Tk::Toplevel<TkWindow
TkCommandNames = ['toplevel'.freeze].freeze TkCommandNames = ['toplevel'.freeze].freeze
WidgetClassName = 'Toplevel'.freeze WidgetClassName = 'Toplevel'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
################# old version ################# old version
# def initialize(parent=nil, screen=nil, classname=nil, keys=nil) # def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
@ -259,4 +259,6 @@ class Tk::Toplevel<TkWindow
end end
#TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel #TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel
Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel) #Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)
Tk.__set_loaded_toplevel_aliases__('tk/toplevel.rb', :Tk, Tk::Toplevel,
:TkToplevel)

View File

@ -53,21 +53,43 @@ module Tk
:TkTreeview => 'tkextlib/tile/treeview', :TkTreeview => 'tkextlib/tile/treeview',
} }
@TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]
# @TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]
Tk.__create_widget_set__(:Tile, :Ttk)
############################################
# depend on the version of Tcl/Tk
major, minor, type, patchlevel = TclTkLib.get_version
# ttk::spinbox is supported on Tcl/Tk8.6b1 or later
if ([major,minor,type,patchlevel] <=>
[8,6,TclTkLib::RELEASE_TYPE::BETA,1]) >= 0
@TOPLEVEL_ALIAS_TABLE[:Ttk].update(
:TkSpinbox => 'tkextlib/tile/tspinbox'
)
end
################################################ ################################################
# register some Ttk widgets as default # register some Ttk widgets as default
# (Ttk is a standard library on Tcl/Tk8.5+) # (Ttk is a standard library on Tcl/Tk8.5+)
@TOPLEVEL_ALIAS_TABLE[:Ttk].each{|sym, file| @TOPLEVEL_ALIAS_TABLE[:Ttk].each{|sym, file|
unless Object.autoload?(sym) || Object.const_defined?(sym) #unless Tk::TOPLEVEL_ALIASES.autoload?(sym) || Tk::TOPLEVEL_ALIASES.const_defined?(sym)
Object.autoload(sym, file) # @TOPLEVEL_ALIAS_OWNER[sym] = :Ttk
end # Tk::TOPLEVEL_ALIASES.autoload(sym, file)
#end
Tk.__regist_toplevel_aliases__(:Ttk, file, sym)
} }
################################################ ################################################
@TOPLEVEL_ALIAS_SETUP_PROC[:Tile] = # @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
@TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod| # @TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|
# unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile)
# Object.autoload :Ttk, 'tkextlib/tile'
# Tk.autoload :Tile, 'tkextlib/tile'
# end
# }
Tk.__toplevel_alias_setup_proc__(:Ttk, :Tile){|mod|
unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile) unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile)
Object.autoload :Ttk, 'tkextlib/tile' Object.autoload :Ttk, 'tkextlib/tile'
Tk.autoload :Tile, 'tkextlib/tile' Tk.autoload :Tile, 'tkextlib/tile'

View File

@ -16,7 +16,7 @@ class TkVariable
#TkVar_ID_TBL = {} #TkVar_ID_TBL = {}
TkVar_CB_TBL = TkCore::INTERP.create_table TkVar_CB_TBL = TkCore::INTERP.create_table
TkVar_ID_TBL = TkCore::INTERP.create_table TkVar_ID_TBL = TkCore::INTERP.create_table
(Tk_VARIABLE_ID = ["v".freeze, "00000".taint]).instance_eval{ (Tk_VARIABLE_ID = ["v".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -1239,6 +1239,14 @@ end
end end
end end
def ===(other)
if other.kind_of?(TkVariable)
self.id == other.id
else
super
end
end
def zero? def zero?
numeric.zero? numeric.zero?
end end

View File

@ -9,7 +9,7 @@ class TkVirtualEvent<TkObject
TkCommandNames = ['event'.freeze].freeze TkCommandNames = ['event'.freeze].freeze
(TkVirtualEventID = ["VirtEvent".freeze, "00000".taint]).instance_eval{ (TkVirtualEventID = ["VirtEvent".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -10,7 +10,8 @@ require 'tk'
module Tk::WinDDE module Tk::WinDDE
end end
#TkWinDDE = Tk::WinDDE #TkWinDDE = Tk::WinDDE
Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE) #Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)
Tk.__set_loaded_toplevel_aliases__('tk/winpkg.rb', :Tk, Tk::WinDDE, :TkWinDDE)
module Tk::WinDDE module Tk::WinDDE
extend Tk extend Tk
@ -93,7 +94,9 @@ end
module Tk::WinRegistry module Tk::WinRegistry
end end
#TkWinRegistry = Tk::WinRegistry #TkWinRegistry = Tk::WinRegistry
Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry) #Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)
Tk.__set_loaded_toplevel_aliases__('tk/winpkg.rb', :Tk, Tk::WinRegistry,
:TkWinRegistry)
module Tk::WinRegistry module Tk::WinRegistry
extend Tk extend Tk

View File

@ -55,18 +55,20 @@ script may give you some hints about that.
===< support with some examples (may be beta quality) >======================= ===< support with some examples (may be beta quality) >=======================
Tcllib 1.8 Tcllib 1.11.1
Tklib 0.4.1 http://sourceforge.net/projects/tcllib ==> tcllib Tklib 0.5 http://sourceforge.net/projects/tcllib ==> tcllib
( partial support; primary support target is Tklib)
IWidgets 4.0.2 http://sourceforge.net/projects/incrtcl ==> iwidgets IWidgets 4.0.2 http://sourceforge.net/projects/incrtcl ==> iwidgets
BWidgets 1.7 http://sourceforge.net/projects/tcllib ==> bwidget BWidget 1.8 [ CVS/Hd(2009-07-02) ]
http://sourceforge.net/projects/tcllib ==> bwidget
TkTable 2.9 http://sourceforge.net/projects/tktable ==> tktable TkTable 2.10 http://sourceforge.net/projects/tktable ==> tktable
* see also <http://www.korus.hu/~fery/ruby/tktable.rb> * see also <http://www.korus.hu/~fery/ruby/tktable.rb>
written by Ferenc Engard (ferenc@engard.hu) written by Ferenc Engard (ferenc@engard.hu)
vu 2.3.0 http://sourceforge.net/projects/tktable ==> vu Vu widgets 2.3.0 http://sourceforge.net/projects/tktable ==> vu
TkHTML 2.0 http://www.hwaci.com/sw/tkhtml/ ==> tkHTML TkHTML 2.0 http://www.hwaci.com/sw/tkhtml/ ==> tkHTML
@ -80,25 +82,25 @@ BLT 2.4z http://sourceforge.net/projects/blt
(http://raa.ruby-lang.org/) (http://raa.ruby-lang.org/)
==> blt ==> blt
TkTreeCtrl CVS/Hd(2005-12-02) TkTreeCtrl 2.2.9
http://sourceforge.net/projects/tktreectrl ==> treectrl http://tktreectrl.sourceforge.net/ ==> treectrl
Tile 0.8.0/8.5.1 Tile 0.8.3/8.6b1
http://sourceforge.net/projects/tktable ==> tile http://sourceforge.net/projects/tktable ==> tile
===< support (may be alpha or beta quality) >================================= ===< support (may be alpha or beta quality) >=================================
IncrTcl CVS/Hd(2005-02-14) IncrTcl CVS/Hd(2008-12-15)
http://sourceforge.net/projects/incrtcl ==> itcl, itk http://sourceforge.net/projects/incrtcl ==> itcl, itk
TclX CVS/Hd(2005-02-07) TclX CVS/Hd(2008-12-15)
http://sourceforge.net/projects/tclx http://sourceforge.net/projects/tclx
==> tclx (partial support; infox command and ==> tclx (partial support; infox command and
XPG/3 message catalogs only) XPG/3 message catalogs only)
Trofs 0.4.3 http://math.nist.gov/~DPorter/tcltk/trofs/ Trofs 0.4.4 http://math.nist.gov/~DPorter/tcltk/trofs/

View File

@ -19,6 +19,8 @@ TkPackage.require('BLT')
module Tk module Tk
module BLT module BLT
TkComm::TkExtlibAutoloadModule.unshift(self) TkComm::TkExtlibAutoloadModule.unshift(self)
# Require autoload-symbols which is a same name as widget classname.
# Those are used at TkComm._genobj_for_tkwidget method.
extend TkCore extend TkCore

View File

@ -11,7 +11,7 @@ module Tk::BLT
class Barchart < TkWindow class Barchart < TkWindow
TkCommandNames = ['::blt::barchart'.freeze].freeze TkCommandNames = ['::blt::barchart'.freeze].freeze
WidgetClassName = 'Barchart'.freeze WidgetClassName = 'Barchart'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
include PlotComponent include PlotComponent
include GraphCommand include GraphCommand
@ -33,7 +33,7 @@ module Tk::BLT
private :__tkvariable_optkeys private :__tkvariable_optkeys
=begin =begin
BarElement_ID = ['blt_barchart_bar'.freeze, '00000'.taint].freeze BarElement_ID = ['blt_barchart_bar'.freeze, TkUtil.untrust('00000')].freeze
def bar(elem=nil, keys={}) def bar(elem=nil, keys={})
if elem.kind_of?(Hash) if elem.kind_of?(Hash)

View File

@ -14,7 +14,7 @@ module Tk::BLT
BITMAP_ID_TBL = TkCore::INTERP.create_table BITMAP_ID_TBL = TkCore::INTERP.create_table
(BITMAP_ID = ['blt_bitmap_id'.freeze, '00000'.taint]).instance_eval{ (BITMAP_ID = ['blt_bitmap_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -44,6 +44,7 @@ class << Tk::BLT::Busy
private :__item_config_cmd private :__item_config_cmd
undef itemcget undef itemcget
undef itemcget_tkstring
alias configure itemconfigure alias configure itemconfigure
alias configinfo itemconfiginfo alias configinfo itemconfiginfo
alias current_configinfo current_itemconfiginfo alias current_configinfo current_itemconfiginfo

View File

@ -82,6 +82,9 @@ module Tk::BLT
end end
private :__item_pathname private :__item_pathname
def axis_cget_tkstring(id, option)
ret = itemcget_tkstring(['axis', tagid(id)], option)
end
def axis_cget(id, option) def axis_cget(id, option)
ret = itemcget(['axis', tagid(id)], option) ret = itemcget(['axis', tagid(id)], option)
end end
@ -118,6 +121,9 @@ module Tk::BLT
current_itemconfiginfo(['axis', tagid(id)], slot) current_itemconfiginfo(['axis', tagid(id)], slot)
end end
def crosshairs_cget_tkstring(option)
itemcget_tkstring('crosshairs', option)
end
def crosshairs_cget(option) def crosshairs_cget(option)
itemcget('crosshairs', option) itemcget('crosshairs', option)
end end
@ -134,6 +140,9 @@ module Tk::BLT
current_itemconfiginfo('crosshairs', slot) current_itemconfiginfo('crosshairs', slot)
end end
def element_cget_tkstring(id, option)
itemcget_tkstring(['element', tagid(id)], option)
end
def element_cget(id, option) def element_cget(id, option)
itemcget(['element', tagid(id)], option) itemcget(['element', tagid(id)], option)
end end
@ -158,6 +167,9 @@ module Tk::BLT
current_itemconfiginfo(['element', tagid(id)], slot) current_itemconfiginfo(['element', tagid(id)], slot)
end end
def bar_cget_tkstring(id, option)
itemcget_tkstring(['bar', tagid(id)], option)
end
def bar_cget(id, option) def bar_cget(id, option)
itemcget(['bar', tagid(id)], option) itemcget(['bar', tagid(id)], option)
end end
@ -182,6 +194,9 @@ module Tk::BLT
current_itemconfiginfo(['bar', tagid(id)], slot) current_itemconfiginfo(['bar', tagid(id)], slot)
end end
def line_cget_tkstring(id, option)
itemcget_tkstring(['line', tagid(id)], option)
end
def line_cget(id, option) def line_cget(id, option)
itemcget(['line', tagid(id)], option) itemcget(['line', tagid(id)], option)
end end
@ -206,6 +221,9 @@ module Tk::BLT
current_itemconfiginfo(['line', tagid(id)], slot) current_itemconfiginfo(['line', tagid(id)], slot)
end end
def gridline_cget_tkstring(option)
itemcget_tkstring('grid', option)
end
def gridline_cget(option) def gridline_cget(option)
itemcget('grid', option) itemcget('grid', option)
end end
@ -222,6 +240,9 @@ module Tk::BLT
current_itemconfiginfo('grid', slot) current_itemconfiginfo('grid', slot)
end end
def legend_cget_tkstring(option)
itemcget_tkstring('legend', option)
end
def legend_cget(option) def legend_cget(option)
itemcget('legend', option) itemcget('legend', option)
end end
@ -238,6 +259,9 @@ module Tk::BLT
current_itemconfiginfo('legend', slot) current_itemconfiginfo('legend', slot)
end end
def pen_cget_tkstring(id, option)
itemcget_tkstring(['pen', tagid(id)], option)
end
def pen_cget(id, option) def pen_cget(id, option)
itemcget(['pen', tagid(id)], option) itemcget(['pen', tagid(id)], option)
end end
@ -262,6 +286,9 @@ module Tk::BLT
current_itemconfiginfo(['pen', tagid(id)], slot) current_itemconfiginfo(['pen', tagid(id)], slot)
end end
def postscript_cget_tkstring(option)
itemcget_tkstring('postscript', option)
end
def postscript_cget(option) def postscript_cget(option)
itemcget('postscript', option) itemcget('postscript', option)
end end
@ -278,6 +305,9 @@ module Tk::BLT
current_itemconfiginfo('postscript', slot) current_itemconfiginfo('postscript', slot)
end end
def marker_cget_tkstring(id, option)
itemcget_tkstring(['marker', tagid(id)], option)
end
def marker_cget(id, option) def marker_cget(id, option)
itemcget(['marker', tagid(id)], option) itemcget(['marker', tagid(id)], option)
end end
@ -302,12 +332,16 @@ module Tk::BLT
current_itemconfiginfo(['marker', tagid(id)], slot) current_itemconfiginfo(['marker', tagid(id)], slot)
end end
alias __itemcget_tkstring itemcget_tkstring
alias __itemcget itemcget alias __itemcget itemcget
alias __itemcget_strict itemcget_strict alias __itemcget_strict itemcget_strict
alias __itemconfiginfo itemconfiginfo alias __itemconfiginfo itemconfiginfo
alias __current_itemconfiginfo current_itemconfiginfo alias __current_itemconfiginfo current_itemconfiginfo
private :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo private :__itemcget_tkstring, :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo
def itemcget_tkstring(tagOrId, option)
__itemcget_tkstring(tagid(tagOrId), option)
end
def itemcget_strict(tagOrId, option) def itemcget_strict(tagOrId, option)
ret = __itemcget(tagid(tagOrId), option) ret = __itemcget(tagid(tagOrId), option)
if option == 'bindtags' || option == :bindtags if option == 'bindtags' || option == :bindtags
@ -373,13 +407,13 @@ module Tk::BLT
ret ret
end end
private :itemcget, :itemcget_strict private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
################# #################
class Axis < TkObject class Axis < TkObject
(OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint]).instance_eval{ (OBJ_ID = ['blt_chart_axis'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -477,6 +511,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.axis_cget_tkstring(@id, option)
end
def cget(option) def cget(option)
@chart.axis_cget(@id, option) @chart.axis_cget(@id, option)
end end
@ -582,6 +619,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.crosshair_cget_tkstring(option)
end
def cget(option) def cget(option)
@chart.crosshair_cget(option) @chart.crosshair_cget(option)
end end
@ -631,7 +671,7 @@ module Tk::BLT
ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear } ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear }
} }
(OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint]).instance_eval{ (OBJ_ID = ['blt_chart_element'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -729,6 +769,10 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
# @chart.element_cget(@id, option)
@chart.__send__(@typename + '_cget_tkstring', @id, option)
end
def cget(option) def cget(option)
# @chart.element_cget(@id, option) # @chart.element_cget(@id, option)
@chart.__send__(@typename + '_cget', @id, option) @chart.__send__(@typename + '_cget', @id, option)
@ -833,6 +877,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.gridline_cget_tkstring(option)
end
def cget(option) def cget(option)
@chart.gridline_cget(option) @chart.gridline_cget(option)
end end
@ -907,6 +954,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.legend_cget_tkstring(option)
end
def cget(option) def cget(option)
@chart.legend_cget(option) @chart.legend_cget(option)
end end
@ -940,7 +990,7 @@ module Tk::BLT
################# #################
class Pen < TkObject class Pen < TkObject
(OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint]).instance_eval{ (OBJ_ID = ['blt_chart_pen'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -1036,6 +1086,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.pen_cget_tkstring(@id, option)
end
def cget(option) def cget(option)
@chart.pen_cget(@id, option) @chart.pen_cget(@id, option)
end end
@ -1106,6 +1159,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.postscript_cget_tkstring(option)
end
def cget(option) def cget(option)
@chart.postscript_cget(option) @chart.postscript_cget(option)
end end
@ -1269,6 +1325,9 @@ module Tk::BLT
@id @id
end end
def cget_tkstring(option)
@chart.marker_cget_tkstring(@id, option)
end
def cget(option) def cget(option)
@chart.marker_cget(@id, option) @chart.marker_cget(@id, option)
end end
@ -1854,6 +1913,9 @@ module Tk::BLT
################### ###################
def xaxis_cget_tkstring(option)
itemcget_tkstring('xaxis', option)
end
def xaxis_cget(option) def xaxis_cget(option)
itemcget('xaxis', option) itemcget('xaxis', option)
end end
@ -1926,6 +1988,9 @@ module Tk::BLT
end end
end end
def x2axis_cget_tkstring(option)
itemcget_tkstring('x2axis', option)
end
def x2axis_cget(option) def x2axis_cget(option)
itemcget('x2axis', option) itemcget('x2axis', option)
end end
@ -1998,6 +2063,9 @@ module Tk::BLT
end end
end end
def yaxis_cget_tkstring(option)
itemcget_tkstring('yaxis', option)
end
def yaxis_cget(option) def yaxis_cget(option)
itemcget('yaxis', option) itemcget('yaxis', option)
end end
@ -2070,6 +2138,9 @@ module Tk::BLT
end end
end end
def y2axis_cget_tkstring(option)
itemcget_tkstring('y2axis', option)
end
def y2axis_cget(option) def y2axis_cget(option)
itemcget('y2axis', option) itemcget('y2axis', option)
end end

View File

@ -10,7 +10,7 @@ module Tk::BLT
class Container < TkWindow class Container < TkWindow
TkCommandNames = ['::blt::container'.freeze].freeze TkCommandNames = ['::blt::container'.freeze].freeze
WidgetClassName = 'Container'.freeze WidgetClassName = 'Container'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'name' super() << 'name'

View File

@ -15,7 +15,7 @@ module Tk::BLT
class Token < TkWindow class Token < TkWindow
WidgetClassName = 'DragDropToken'.freeze WidgetClassName = 'DragDropToken'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def initialize(arg) def initialize(arg)
if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token
@ -55,6 +55,7 @@ module Tk::BLT
private :__item_strval_optkeys private :__item_strval_optkeys
undef itemcget undef itemcget
undef itemcget_tkstring
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
def source_configure(win, slot, value=None) def source_configure(win, slot, value=None)

View File

@ -11,7 +11,7 @@ module Tk::BLT
class Graph < TkWindow class Graph < TkWindow
TkCommandNames = ['::blt::graph'.freeze].freeze TkCommandNames = ['::blt::graph'.freeze].freeze
WidgetClassName = 'Graph'.freeze WidgetClassName = 'Graph'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
include PlotComponent include PlotComponent
include GraphCommand include GraphCommand
@ -27,7 +27,7 @@ module Tk::BLT
private :__strval_optkeys private :__strval_optkeys
=begin =begin
BarElement_ID = ['blt_graph_bar'.freeze, '00000'.taint].freeze BarElement_ID = ['blt_graph_bar'.freeze, TkUtil.untrust('00000')].freeze
def bar(elem=nil, keys={}) def bar(elem=nil, keys={})
if elem.kind_of?(Hash) if elem.kind_of?(Hash)

View File

@ -19,8 +19,9 @@ module Tk::BLT
TkCommandNames = ['::blt::htext'.freeze].freeze TkCommandNames = ['::blt::htext'.freeze].freeze
WidgetClassName = 'Htext'.freeze WidgetClassName = 'Htext'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
alias window_cget_tkstring itemcget_tkstring
alias window_cget itemcget alias window_cget itemcget
alias window_cget_strict itemcget_strict alias window_cget_strict itemcget_strict
alias window_configure itemconfigure alias window_configure itemconfigure

View File

@ -11,7 +11,7 @@ module Tk::BLT
class Stripchart < TkWindow class Stripchart < TkWindow
TkCommandNames = ['::blt::stripchart'.freeze].freeze TkCommandNames = ['::blt::stripchart'.freeze].freeze
WidgetClassName = 'Stripchart'.freeze WidgetClassName = 'Stripchart'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
include PlotComponent include PlotComponent
include GraphCommand include GraphCommand
@ -28,7 +28,7 @@ module Tk::BLT
private :__strval_optkeys private :__strval_optkeys
=begin =begin
BarElement_ID = ['blt_stripchart_bar'.freeze, '00000'.taint].freeze BarElement_ID = ['blt_stripchart_bar'.freeze, TkUtil.untrust('00000')].freeze
def bar(elem=nil, keys={}) def bar(elem=nil, keys={})
if elem.kind_of?(Hash) if elem.kind_of?(Hash)

View File

@ -26,6 +26,9 @@ module Tk::BLT
self self
end end
def blt_table_cget_tkstring(*args)
Tk::BLT::Table.cget_tkstring(self, *args)
end
def blt_table_cget(*args) def blt_table_cget(*args)
Tk::BLT::Table.cget(self, *args) Tk::BLT::Table.cget(self, *args)
end end
@ -92,6 +95,9 @@ module Tk::BLT
self self
end end
def blt_table_itemcget_tkstring(*args)
Tk::BLT::Table.itemcget_tkstring(self, *args)
end
def blt_table_itemcget(*args) def blt_table_itemcget(*args)
Tk::BLT::Table.itemcget(self, *args) Tk::BLT::Table.itemcget(self, *args)
end end
@ -141,13 +147,14 @@ class << Tk::BLT::Table
end end
private :__item_pathname private :__item_pathname
alias __itemcget_tkstring itemcget_tkstring
alias __itemcget itemcget alias __itemcget itemcget
alias __itemcget_strict itemcget_strict alias __itemcget_strict itemcget_strict
alias __itemconfigure itemconfigure alias __itemconfigure itemconfigure
alias __itemconfiginfo itemconfiginfo alias __itemconfiginfo itemconfiginfo
alias __current_itemconfiginfo current_itemconfiginfo alias __current_itemconfiginfo current_itemconfiginfo
private :__itemcget, :__itemcget_strict private :__itemcget_tkstring, :__itemcget, :__itemcget_strict
private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo
def __boolval_optkeys def __boolval_optkeys
@ -180,6 +187,9 @@ class << Tk::BLT::Table
############################################ ############################################
def cget_tkstring(container, option)
__itemcget_tkstring([container], option)
end
def cget(container, option) def cget(container, option)
__itemcget([container], option) __itemcget([container], option)
end end
@ -199,6 +209,9 @@ class << Tk::BLT::Table
__current_itemconfiginfo([container], *args) __current_itemconfiginfo([container], *args)
end end
def itemcget_tkstring(container, item, option)
__itemcget_tkstring([container, tagid(item)], option)
end
def itemcget(container, item, option) def itemcget(container, item, option)
__itemcget([container, tagid(item)], option) __itemcget([container, tagid(item)], option)
end end

View File

@ -11,7 +11,7 @@ module Tk::BLT
class Tabnotebook < Tabset class Tabnotebook < Tabset
TkCommandNames = ['::blt::tabnotebook'.freeze].freeze TkCommandNames = ['::blt::tabnotebook'.freeze].freeze
WidgetClassName = 'Tabnotebook'.freeze WidgetClassName = 'Tabnotebook'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
class Tab < Tk::BLT::Tabset::Tab class Tab < Tk::BLT::Tabset::Tab
def self.new(parent, pos=nil, name=nil, keys={}) def self.new(parent, pos=nil, name=nil, keys={})

View File

@ -13,7 +13,7 @@ module Tk::BLT
TabID_TBL = TkCore::INTERP.create_table TabID_TBL = TkCore::INTERP.create_table
(TabsetTab_ID = ['blt_tabset_tab'.freeze, '00000'.taint]).instance_eval{ (TabsetTab_ID = ['blt_tabset_tab'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -132,6 +132,9 @@ module Tk::BLT
@t.tab_bindinfo(@id, context) @t.tab_bindinfo(@id, context)
end end
def cget_tkstring(*args)
@t.tab_cget_tkstring(@id, *args)
end
def cget(*args) def cget(*args)
@t.tab_cget(@id, *args) @t.tab_cget(@id, *args)
end end
@ -210,7 +213,7 @@ module Tk::BLT
TkCommandNames = ['::blt::tabset'.freeze].freeze TkCommandNames = ['::blt::tabset'.freeze].freeze
WidgetClassName = 'Tabset'.freeze WidgetClassName = 'Tabset'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__ def __destroy_hook__
Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{ Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{
@ -249,6 +252,7 @@ module Tk::BLT
end end
private :__item_pathname private :__item_pathname
alias tab_cget_tkstring itemcget_tkstring
alias tab_cget itemcget alias tab_cget itemcget
alias tab_cget_strict itemcget_strict alias tab_cget_strict itemcget_strict
alias tab_configure itemconfigure alias tab_configure itemconfigure

View File

@ -30,9 +30,12 @@ module Tk::BLT
end end
private :__item_config_cmd private :__item_config_cmd
private :itemcget, :itemcget_strict private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
def cget_tkstring(master, option)
itemcget_tkstring(master, option)
end
def cget(master, option) def cget(master, option)
itemcget(master, option) itemcget(master, option)
end end

View File

@ -8,6 +8,10 @@ require 'tkextlib/blt.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
TkComm::TkExtlibAutoloadModule.unshift(self)
# Require autoload-symbols which is a same name as widget classname.
# Those are used at TkComm._genobj_for_tkwidget method.
autoload :Button, 'tkextlib/blt/tile/button.rb' autoload :Button, 'tkextlib/blt/tile/button.rb'
autoload :CheckButton, 'tkextlib/blt/tile/checkbutton.rb' autoload :CheckButton, 'tkextlib/blt/tile/checkbutton.rb'
autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb' autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb'

View File

@ -272,7 +272,7 @@ module Tk::BLT
TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear } TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }
} }
(TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint]).instance_eval{ (TreeTag_ID = ['blt_tree_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -578,7 +578,7 @@ module Tk::BLT
TreeID_TBL = TkCore::INTERP.create_table TreeID_TBL = TkCore::INTERP.create_table
(Tree_ID = ['blt_tree'.freeze, '00000'.taint]).instance_eval{ (Tree_ID = ['blt_tree'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -95,6 +95,9 @@ module Tk::BLT::Treeview::ConfigMethod
end end
private :__item_pathname private :__item_pathname
def column_cget_tkstring(name, option)
itemcget_tkstring(['column', name], option)
end
def column_cget(name, option) def column_cget(name, option)
itemcget(['column', name], option) itemcget(['column', name], option)
end end
@ -111,6 +114,9 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo(['column', name], slot) current_itemconfiginfo(['column', name], slot)
end end
def button_cget_tkstring(option)
itemcget_tkstring('button', option)
end
def button_cget(option) def button_cget(option)
itemcget('button', option) itemcget('button', option)
end end
@ -127,6 +133,9 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo('button', slot) current_itemconfiginfo('button', slot)
end end
def entry_cget_tkstring(option)
itemcget_tkstring('entry', option)
end
def entry_cget(option) def entry_cget(option)
ret = itemcget('entry', option) ret = itemcget('entry', option)
if option == 'bindtags' || option == :bindtags if option == 'bindtags' || option == :bindtags
@ -181,6 +190,9 @@ module Tk::BLT::Treeview::ConfigMethod
ret ret
end end
def sort_cget_tkstring(option)
itemcget_tkstring('sort', option)
end
def sort_cget(option) def sort_cget(option)
itemcget('sort', option) itemcget('sort', option)
end end
@ -197,6 +209,9 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo('sort', slot) current_itemconfiginfo('sort', slot)
end end
def text_cget_tkstring(option)
itemcget_tkstring('text', option)
end
def text_cget(option) def text_cget(option)
itemcget('text', option) itemcget('text', option)
end end
@ -213,14 +228,14 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo('text', slot) current_itemconfiginfo('text', slot)
end end
private :itemcget, :itemcget_strict private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end end
class Tk::BLT::Treeview class Tk::BLT::Treeview
TkCommandNames = ['::blt::treeview'.freeze].freeze TkCommandNames = ['::blt::treeview'.freeze].freeze
WidgetClassName = 'TreeView'.freeze WidgetClassName = 'TreeView'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
include Scrollable include Scrollable
include ValidateConfigure include ValidateConfigure
@ -1029,7 +1044,7 @@ class Tk::BLT::Treeview::Node < TkObject
TreeNodeID_TBL = TkCore::INTERP.create_table TreeNodeID_TBL = TkCore::INTERP.create_table
(TreeNode_ID = ['blt_treeview_node'.freeze, '00000'.taint]).instance_eval{ (TreeNode_ID = ['blt_treeview_node'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -1150,7 +1165,7 @@ class Tk::BLT::Treeview::Tag < TkObject
TreeTagID_TBL = TkCore::INTERP.create_table TreeTagID_TBL = TkCore::INTERP.create_table
(TreeTag_ID = ['blt_treeview_tag'.freeze, '00000'.taint]).instance_eval{ (TreeTag_ID = ['blt_treeview_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -1268,5 +1283,5 @@ end
class Tk::BLT::Hiertable class Tk::BLT::Hiertable
TkCommandNames = ['::blt::hiertable'.freeze].freeze TkCommandNames = ['::blt::hiertable'.freeze].freeze
WidgetClassName = 'Hiertable'.freeze WidgetClassName = 'Hiertable'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
end end

View File

@ -30,9 +30,12 @@ module Tk::BLT
end end
private :__item_config_cmd private :__item_config_cmd
private :itemcget, :itemcget_strict private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
def cget_tkstring(win, option)
itemcget_tkstring(['cget', win], option)
end
def cget(win, option) def cget(win, option)
itemcget(['cget', win], option) itemcget(['cget', win], option)
end end
@ -49,6 +52,9 @@ module Tk::BLT
current_itemconfiginfo(['configure', win], slot) current_itemconfiginfo(['configure', win], slot)
end end
def token_cget_tkstring(win, option)
itemcget_tkstring(['token', 'cget', win], option)
end
def token_cget(win, option) def token_cget(win, option)
itemcget(['token', 'cget', win], option) itemcget(['token', 'cget', win], option)
end end

View File

@ -14,7 +14,7 @@ module Tk::BLT
WATCH_ID_TBL = TkCore::INTERP.create_table WATCH_ID_TBL = TkCore::INTERP.create_table
(BLT_WATCH_ID = ['blt_watch_id'.freeze, '00000'.taint]).instance_eval{ (BLT_WATCH_ID = ['blt_watch_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze

View File

@ -18,6 +18,8 @@ TkPackage.require('BWidget')
module Tk module Tk
module BWidget module BWidget
TkComm::TkExtlibAutoloadModule.unshift(self) TkComm::TkExtlibAutoloadModule.unshift(self)
# Require autoload-symbols which is a same name as widget classname.
# Those are used at TkComm._genobj_for_tkwidget method.
extend TkCore extend TkCore

View File

@ -17,5 +17,5 @@ end
class Tk::BWidget::ArrowButton class Tk::BWidget::ArrowButton
TkCommandNames = ['ArrowButton'.freeze].freeze TkCommandNames = ['ArrowButton'.freeze].freeze
WidgetClassName = 'ArrowButton'.freeze WidgetClassName = 'ArrowButton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
end end

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::Button class Tk::BWidget::Button
TkCommandNames = ['Button'.freeze].freeze TkCommandNames = ['Button'.freeze].freeze
WidgetClassName = 'Button'.freeze WidgetClassName = 'Button'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'helptext' super() << 'helptext'

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::ButtonBox class Tk::BWidget::ButtonBox
TkCommandNames = ['ButtonBox'.freeze].freeze TkCommandNames = ['ButtonBox'.freeze].freeze
WidgetClassName = 'ButtonBox'.freeze WidgetClassName = 'ButtonBox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
include TkItemConfigMethod include TkItemConfigMethod

View File

@ -21,7 +21,12 @@ class Tk::BWidget::ComboBox
TkCommandNames = ['ComboBox'.freeze].freeze TkCommandNames = ['ComboBox'.freeze].freeze
WidgetClassName = 'ComboBox'.freeze WidgetClassName = 'ComboBox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'autocomplete' << 'autopost'
end
private :__boolval_optkeys
def get_listbox(&b) def get_listbox(&b)
win = window(tk_send_without_enc('getlistbox')) win = window(tk_send_without_enc('getlistbox'))
@ -35,6 +40,12 @@ class Tk::BWidget::ComboBox
win win
end end
def clear_value
tk_send_without_enc('clearvalue')
self
end
alias clearvalue clear_value
def icursor(idx) def icursor(idx)
tk_send_without_enc('icursor', idx) tk_send_without_enc('icursor', idx)
end end

View File

@ -18,12 +18,17 @@ end
class Tk::BWidget::Dialog class Tk::BWidget::Dialog
TkCommandNames = ['Dialog'.freeze].freeze TkCommandNames = ['Dialog'.freeze].freeze
WidgetClassName = 'Dialog'.freeze WidgetClassName = 'Dialog'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
include TkItemConfigMethod include TkItemConfigMethod
def __numstrval_optkeys
super() << 'buttonwidth'
end
private :__numstrval_optkeys
def __strval_optkeys def __strval_optkeys
super() << 'title' super() << 'title' << 'geometry'
end end
private :__strval_optkeys private :__strval_optkeys
@ -59,6 +64,13 @@ class Tk::BWidget::Dialog
end end
end end
def cget_tkstring(slot)
if slot.to_s == 'relative'
super('parent')
else
super(slot)
end
end
def cget_strict(slot) def cget_strict(slot)
if slot.to_s == 'relative' if slot.to_s == 'relative'
super('parent') super('parent')

View File

@ -19,7 +19,7 @@ class Tk::BWidget::Entry
TkCommandNames = ['Entry'.freeze].freeze TkCommandNames = ['Entry'.freeze].freeze
WidgetClassName = 'Entry'.freeze WidgetClassName = 'Entry'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'helptext' << 'insertbackground' super() << 'helptext' << 'insertbackground'

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::Label class Tk::BWidget::Label
TkCommandNames = ['Label'.freeze].freeze TkCommandNames = ['Label'.freeze].freeze
WidgetClassName = 'Label'.freeze WidgetClassName = 'Label'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'helptext' super() << 'helptext'

View File

@ -21,7 +21,7 @@ class Tk::BWidget::LabelEntry
TkCommandNames = ['LabelEntry'.freeze].freeze TkCommandNames = ['LabelEntry'.freeze].freeze
WidgetClassName = 'LabelEntry'.freeze WidgetClassName = 'LabelEntry'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg' super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg'

View File

@ -18,7 +18,7 @@ end
class Tk::BWidget::LabelFrame class Tk::BWidget::LabelFrame
TkCommandNames = ['LabelFrame'.freeze].freeze TkCommandNames = ['LabelFrame'.freeze].freeze
WidgetClassName = 'LabelFrame'.freeze WidgetClassName = 'LabelFrame'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'helptext' super() << 'helptext'

View File

@ -25,7 +25,7 @@ class Tk::BWidget::ListBox
TkCommandNames = ['ListBox'.freeze].freeze TkCommandNames = ['ListBox'.freeze].freeze
WidgetClassName = 'ListBox'.freeze WidgetClassName = 'ListBox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
class Event_for_Items < TkEvent::Event class Event_for_Items < TkEvent::Event
def self._get_extra_args_tbl def self._get_extra_args_tbl
@ -212,7 +212,7 @@ class Tk::BWidget::ListBox::Item
ListItem_TBL = TkCore::INTERP.create_table ListItem_TBL = TkCore::INTERP.create_table
(ListItem_ID = ['bw:item'.freeze, '00000'.taint]).instance_eval{ (ListItem_ID = ['bw:item'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new @mutex = Mutex.new
def mutex; @mutex; end def mutex; @mutex; end
freeze freeze
@ -294,6 +294,9 @@ class Tk::BWidget::ListBox::Item
val val
end end
def cget_tkstring(key)
@listbox.itemcget_tkstring(@id, key)
end
def cget(key) def cget(key)
@listbox.itemcget(@id, key) @listbox.itemcget(@id, key)
end end

View File

@ -18,7 +18,7 @@ end
class Tk::BWidget::MainFrame class Tk::BWidget::MainFrame
TkCommandNames = ['MainFrame'.freeze].freeze TkCommandNames = ['MainFrame'.freeze].freeze
WidgetClassName = 'MainFrame'.freeze WidgetClassName = 'MainFrame'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'progressfg' super() << 'progressfg'
@ -111,6 +111,10 @@ class Tk::BWidget::MainFrame
win win
end end
def get_menustate(tag)
tk_send('getmenustate', tag) # return state name string
end
def set_menustate(tag, state) def set_menustate(tag, state)
tk_send('setmenustate', tag, state) tk_send('setmenustate', tag, state)
self self

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::MessageDlg class Tk::BWidget::MessageDlg
TkCommandNames = ['MessageDlg'.freeze].freeze TkCommandNames = ['MessageDlg'.freeze].freeze
WidgetClassName = 'MessageDlg'.freeze WidgetClassName = 'MessageDlg'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def initialize(parent=nil, keys=nil) def initialize(parent=nil, keys=nil)
@relative = '' @relative = ''

View File

@ -19,7 +19,7 @@ class Tk::BWidget::NoteBook
TkCommandNames = ['NoteBook'.freeze].freeze TkCommandNames = ['NoteBook'.freeze].freeze
WidgetClassName = 'NoteBook'.freeze WidgetClassName = 'NoteBook'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
class Event_for_Tabs < TkEvent::Event class Event_for_Tabs < TkEvent::Event
def self._get_extra_args_tbl def self._get_extra_args_tbl

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::PagesManager class Tk::BWidget::PagesManager
TkCommandNames = ['PagesManager'.freeze].freeze TkCommandNames = ['PagesManager'.freeze].freeze
WidgetClassName = 'PagesManager'.freeze WidgetClassName = 'PagesManager'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def tagid(id) def tagid(id)
# id.to_s # id.to_s

View File

@ -17,7 +17,12 @@ end
class Tk::BWidget::PanedWindow class Tk::BWidget::PanedWindow
TkCommandNames = ['PanedWindow'.freeze].freeze TkCommandNames = ['PanedWindow'.freeze].freeze
WidgetClassName = 'PanedWindow'.freeze WidgetClassName = 'PanedWindow'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'activator'
end
private :__strval_optkeys
def add(keys={}) def add(keys={})
window(tk_send('add', *hash_kv(keys))) window(tk_send('add', *hash_kv(keys)))

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::PanelFrame class Tk::BWidget::PanelFrame
TkCommandNames = ['PanelFrame'.freeze].freeze TkCommandNames = ['PanelFrame'.freeze].freeze
WidgetClassName = 'PanelFrame'.freeze WidgetClassName = 'PanelFrame'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() + ['panelforeground', 'panelbackground'] super() + ['panelforeground', 'panelbackground']
@ -47,11 +47,21 @@ class Tk::BWidget::PanelFrame
end end
def items def items
list(tk_send('items')) simplelist(tk_send('items')).map{|w| window(w)}
end end
def remove(*wins) def remove(*wins)
tk_send('remove', *wins) tk_send('remove', *wins)
self self
end end
def remove_with_destroy(*wins)
tk_send('remove', '-destroy', *wins)
self
end
def delete(*wins) # same to 'remove_with_destroy'
tk_send('delete', *wins)
self
end
end end

View File

@ -17,7 +17,7 @@ end
class Tk::BWidget::PasswdDlg class Tk::BWidget::PasswdDlg
TkCommandNames = ['PasswdDlg'.freeze].freeze TkCommandNames = ['PasswdDlg'.freeze].freeze
WidgetClassName = 'PasswdDlg'.freeze WidgetClassName = 'PasswdDlg'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'loginhelptext' << 'loginlabel' << 'logintext' << super() << 'loginhelptext' << 'loginlabel' << 'logintext' <<

View File

@ -16,5 +16,5 @@ end
class Tk::BWidget::ProgressBar class Tk::BWidget::ProgressBar
TkCommandNames = ['ProgressBar'.freeze].freeze TkCommandNames = ['ProgressBar'.freeze].freeze
WidgetClassName = 'ProgressBar'.freeze WidgetClassName = 'ProgressBar'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
end end

View File

@ -19,7 +19,7 @@ end
class Tk::BWidget::ProgressDlg class Tk::BWidget::ProgressDlg
TkCommandNames = ['ProgressDlg'.freeze].freeze TkCommandNames = ['ProgressDlg'.freeze].freeze
WidgetClassName = 'ProgressDlg'.freeze WidgetClassName = 'ProgressDlg'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def create_self(keys) def create_self(keys)
# NOT create widget for reusing the object # NOT create widget for reusing the object

View File

@ -19,7 +19,7 @@ class Tk::BWidget::ScrollableFrame
TkCommandNames = ['ScrollableFrame'.freeze].freeze TkCommandNames = ['ScrollableFrame'.freeze].freeze
WidgetClassName = 'ScrollableFrame'.freeze WidgetClassName = 'ScrollableFrame'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))

View File

@ -17,7 +17,17 @@ end
class Tk::BWidget::ScrolledWindow class Tk::BWidget::ScrolledWindow
TkCommandNames = ['ScrolledWindow'.freeze].freeze TkCommandNames = ['ScrolledWindow'.freeze].freeze
WidgetClassName = 'ScrolledWindow'.freeze WidgetClassName = 'ScrolledWindow'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'sides'
end
private :__strval_optkeys
def __boolval_optkeys
super() << 'managed'
end
private :__boolval_optkeys
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))

View File

@ -16,7 +16,7 @@ end
class Tk::BWidget::ScrollView class Tk::BWidget::ScrollView
TkCommandNames = ['ScrollView'.freeze].freeze TkCommandNames = ['ScrollView'.freeze].freeze
WidgetClassName = 'ScrollView'.freeze WidgetClassName = 'ScrollView'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'fill' super() << 'fill'

View File

@ -24,7 +24,7 @@ class Tk::BWidget::SelectColor
TkCommandNames = ['SelectColor'.freeze].freeze TkCommandNames = ['SelectColor'.freeze].freeze
WidgetClassName = 'SelectColor'.freeze WidgetClassName = 'SelectColor'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def dialog(keys={}) def dialog(keys={})
newkeys = @keys.dup newkeys = @keys.dup

View File

@ -23,13 +23,18 @@ class Tk::BWidget::SelectFont
TkCommandNames = ['SelectFont'.freeze].freeze TkCommandNames = ['SelectFont'.freeze].freeze
WidgetClassName = 'SelectFont'.freeze WidgetClassName = 'SelectFont'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'sampletext' << 'title' super() << 'sampletext' << 'title'
end end
private :__strval_optkeys private :__strval_optkeys
def __boolval_optkeys
super() << 'nosizes'
end
private :__boolval_optkeys
def __font_optkeys def __font_optkeys
[] # without fontobj operation [] # without fontobj operation
end end

View File

@ -16,5 +16,5 @@ end
class Tk::BWidget::Separator class Tk::BWidget::Separator
TkCommandNames = ['Separator'.freeze].freeze TkCommandNames = ['Separator'.freeze].freeze
WidgetClassName = 'Separator'.freeze WidgetClassName = 'Separator'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
end end

View File

@ -20,7 +20,7 @@ class Tk::BWidget::SpinBox
TkCommandNames = ['SpinBox'.freeze].freeze TkCommandNames = ['SpinBox'.freeze].freeze
WidgetClassName = 'SpinBox'.freeze WidgetClassName = 'SpinBox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys def __strval_optkeys
super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg' super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg'

View File

@ -17,10 +17,10 @@ end
class Tk::BWidget::StatusBar class Tk::BWidget::StatusBar
TkCommandNames = ['StatusBar'.freeze].freeze TkCommandNames = ['StatusBar'.freeze].freeze
WidgetClassName = 'StatusBar'.freeze WidgetClassName = 'StatusBar'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys def __boolval_optkeys
super() << 'showresize' super() << 'showresize' << 'showseparator' << 'showresizesep'
end end
private :__boolval_optkeys private :__boolval_optkeys
@ -29,7 +29,17 @@ class Tk::BWidget::StatusBar
self self
end end
def delete(*wins) def remove(*wins)
tk_send('remove', *wins)
self
end
def remove_with_destroy(*wins)
tk_send('remove', '-destroy', *wins)
self
end
def delete(*wins) # same to 'remove_with_destroy'
tk_send('delete', *wins) tk_send('delete', *wins)
self self
end end
@ -47,6 +57,6 @@ class Tk::BWidget::StatusBar
end end
def items def items
list(tk_send('items')) simplelist(tk_send('items')).map{|w| window(w)}
end end
end end

Some files were not shown because too many files have changed in this diff Show More