* 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
Родитель e13fb8029b
Коммит ed6ce8b43b
228 изменённых файлов: 7275 добавлений и 1058 удалений

Просмотреть файл

@ -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>
* time.c (time_timespec): rounds subsecond toward zero.

Просмотреть файл

@ -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>
* ext/tk/lib/tkextlib/blt/tabset.rb,

Просмотреть файл

@ -140,8 +140,7 @@ module TclTklib
[module methods]
get_version()
: return an array of major, minor, release-type number,
: number, release-type name, and patchlevel of current
: Tcl/Tk library.
: and patchlevel of current Tcl/Tk library.
mainloop(check_root = true)
: 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
: 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)
_fromUTF8(str, encoding=nil)
: Call the function (which is internal function of Tcl/Tk) to

Просмотреть файл

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

Просмотреть файл

@ -3,9 +3,22 @@ ActiveTcl is ActiveState's quality-assured distribution of Tcl.
# see <http://www.activestate.com/Products/ActiveTcl/>
# <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,
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-tk-dir=<ActiveTcl_root>

Просмотреть файл

@ -1,18 +1,53 @@
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
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
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>
force version of Tcl/Tk libaray
(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-tklib=<libname> (e.g. libtk8.4.so ==> --with-tklib=tk8.4)
--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>
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
--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>
Tcl framework headers directory
(e.g. "/Library/Frameworks/Tcl.framework/Headers")

35
ext/tk/config_list.in Normal 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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -30,8 +30,8 @@ class << TclTkIp
end
obj = __new__(*args)
obj.instance_eval{
@force_default_encoding ||= [false].taint
@encoding ||= [nil].taint
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
obj
@ -120,31 +120,31 @@ MultiTkIp_OK.freeze
class MultiTkIp
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 = 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
def mutex; @mutex; end
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
@@ADD_TK_PROCS = [].taint unless defined?(@@ADD_TK_PROCS) # table of [name, args, body]
@@INIT_IP_ENV = TkUtil.untrust([]) unless defined?(@@INIT_IP_ENV) # table of Procs
@@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)
@@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', Hash.new{|hash,key|
fail IndexError,
"unknown command ID '#{key}'"
}.taint)
tbl_obj = TkUtil.untrust(Hash.new{|hash,key|
fail IndexError, "unknown command ID '#{key}'"
})
@@TK_CMD_TBL.instance_variable_set('@tbl', tbl_obj)
class << @@TK_CMD_TBL
allow = [
@ -223,7 +223,10 @@ class MultiTkIp
@@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){
def initialize(ip, cmd)
@ip = ip
@cmd = cmd
@safe = safe = $SAFE
# @cmd = cmd
cmd = MultiTkIp._proc_on_safelevel(&cmd)
@cmd = proc{|*args| cmd.call(safe, *args)}
self.freeze
end
attr_reader :ip, :cmd
@ -736,15 +739,15 @@ class MultiTkIp
@@DEFAULT_MASTER = self.allocate
@@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
fail ArgumentError, "expecting a Hash object for the 2nd argument"
@ -755,7 +758,12 @@ class MultiTkIp
else ### Ruby 1.9 !!!!!!!!!!!
@interp_thread = Thread.new{
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
current[:mutex] = mutex = Mutex.new
current[:root_check] = cond_var = ConditionVariable.new
@ -770,13 +778,29 @@ class MultiTkIp
current[:status] = status
begin
current[:status].value = interp.mainloop(true)
rescue Exception=>e
current[:status].value = e
begin
#TclTkLib.mainloop_abort_on_exception = false
#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
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
current[:status].value = interp.mainloop(false)
}
until @interp_thread[:interp]
Thread.pass
@ -795,18 +819,18 @@ class MultiTkIp
end
@interp.instance_eval{
@force_default_encoding ||= [false].taint
@encoding ||= [nil].taint
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@ip_name = nil
@callback_status = [].taint
@callback_status = TkUtil.untrust([])
@system = Object.new
@wait_on_mainloop = [true, 0].taint
@wait_on_mainloop = TkUtil.untrust([true, 0])
@threadgroup = Thread.current.group
@ -1181,8 +1205,8 @@ class MultiTkIp
ip_name = _create_slave_ip_name
slave_ip = @interp.create_slave(ip_name, true)
slave_ip.instance_eval{
@force_default_encoding ||= [false].taint
@encoding ||= [nil].taint
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@slave_ip_tbl[ip_name] = slave_ip
@ -1228,8 +1252,8 @@ class MultiTkIp
ip_name = _create_slave_ip_name
slave_ip = @interp.create_slave(ip_name, false)
slave_ip.instance_eval{
@force_default_encoding ||= [false].taint
@encoding ||= [nil].taint
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String)
@ -1282,12 +1306,12 @@ class MultiTkIp
@cb_error_proc = []
@evloop_thread = []
@tk_windows.taint unless @tk_windows.tainted?
@tk_table_list.taint unless @tk_table_list.tainted?
@slave_ip_tbl.taint unless @slave_ip_tbl.tainted?
@slave_ip_top.taint unless @slave_ip_top.tainted?
@cb_error_proc.taint unless @cb_error_proc.tainted?
@evloop_thread.taint unless @evloop_thread.tainted?
TkUtil.untrust(@tk_windows) unless @tk_windows.tainted?
TkUtil.untrust(@tk_table_list) unless @tk_table_list.tainted?
TkUtil.untrust(@slave_ip_tbl) unless @slave_ip_tbl.tainted?
TkUtil.untrust(@slave_ip_top) unless @slave_ip_top.tainted?
TkUtil.untrust(@cb_error_proc) unless @cb_error_proc.tainted?
TkUtil.untrust(@evloop_thread) unless @evloop_thread.tainted?
@callback_status = []
@ -1302,17 +1326,18 @@ class MultiTkIp
unless WITH_RUBY_VM
@interp = TclTkIp.new(name, _keys2opts(tk_opts))
@interp.instance_eval{
@force_default_encoding ||= [false].taint
@encoding ||= [nil].taint
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
else ### Ruby 1.9 !!!!!!!!!!!
=begin
@interp_thread = Thread.new{
Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
interp.instance_eval{
@force_default_encoding ||= [false].taint
@encoding ||= [nil].taint
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@ -1324,15 +1349,74 @@ class MultiTkIp
end
# INTERP_THREAD.run
@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
@interp.instance_eval{
@force_default_encoding ||= TkUtil.untrust([false])
@encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@ip_name = nil
if safe
safe = $SAFE if safe < $SAFE
@safe_level = [safe]
else
@safe_level = [$SAFE]
end
else
# create slave-ip
if safeip || master.safe?
@ -1365,8 +1449,8 @@ class MultiTkIp
@system = Object.new
@wait_on_mainloop = [true, 0].taint
# @wait_on_mainloop = [false, 0].taint
@wait_on_mainloop = TkUtil.untrust([true, 0])
# @wait_on_mainloop = TkUtil.untrust([false, 0])
@threadgroup = ThreadGroup.new
@ -1386,8 +1470,7 @@ class MultiTkIp
@@IP_TABLE[@threadgroup] = self
@@TK_TABLE_LIST.size.times{
(tbl = {}).tainted? || tbl.taint
@tk_table_list << tbl
@tk_table_list << TkUtil.untrust({})
}
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
@ -1435,6 +1518,17 @@ end
# get target IP
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_
__getip._ip_id_
end
@ -1445,6 +1539,9 @@ class MultiTkIp
def self.__getip
current = Thread.current
if current.kind_of?(@@CALLBACK_SUBTHREAD)
return current[:callback_ip]
end
if TclTkLib.mainloop_thread? != false && current[:callback_ip]
return current[:callback_ip]
end
@ -1467,11 +1564,11 @@ class << MultiTkIp
alias __new new
private :__new
def new_master(safe=nil, keys={})
def new_master(safe=nil, keys={}, &blk)
if MultiTkIp::WITH_RUBY_VM
#### TODO !!!!!!
fail RuntimeError,
'sorry, still not support multiple master-interpreters on Ruby VM'
'sorry, still not support multiple master-interpreters on RubyVM'
end
if safe.kind_of?(Hash)
@ -1489,15 +1586,17 @@ class << MultiTkIp
ip = __new(__getip, nil, keys)
#ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given?
Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
end
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; yield}.call)}
ip._proc_on_safelevel(&blk).call(ip.safe_level)
end
ip
end
alias new new_master
def new_slave(safe=nil, keys={})
def new_slave(safe=nil, keys={}, &blk)
if safe.kind_of?(Hash)
keys = safe
elsif safe.kind_of?(Integer)
@ -1514,13 +1613,15 @@ class << MultiTkIp
ip = __new(__getip, false, keys)
# ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) 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
ip
end
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)
keys = safe
elsif safe.kind_of?(Integer)
@ -1535,7 +1636,9 @@ class << MultiTkIp
ip = __new(__getip, true, keys)
# ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) 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
ip
end
@ -1669,8 +1772,7 @@ class MultiTkIp
def _add_new_tables
(@@TK_TABLE_LIST.size - @tk_table_list.size).times{
(tbl = {}).tainted? || tbl.taint
@tk_table_list << tbl
@tk_table_list << TkUtil.untrust({})
}
end
@ -1813,7 +1915,6 @@ class MultiTkIp
end
end
# for callback operation
class MultiTkIp
def self.cb_entry_class
@ -1837,6 +1938,13 @@ class MultiTkIp
ret
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)
self.eval_callback(*args){|safe, *params|
$SAFE=safe if $SAFE < safe
@ -1844,6 +1952,7 @@ class MultiTkIp
TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
}
end
=end
=begin
def cb_eval(cmd, *args)
@callback_status[0] ||= TkVariable.new
@ -1938,6 +2047,48 @@ end
# evaluate a procedure on the proper interpreter
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
def eval_proc_core(req_val, cmd, *args)
# check
@ -1953,10 +2104,10 @@ class MultiTkIp
ret = cmd.call(safe_level, *args)
rescue SystemExit => e
# exit IP
warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG
warn("Warning: "+ e.inspect + " on " + self.inspect) if $DEBUG
begin
self._eval_without_enc('exit')
rescue Exception
rescue Exception => e
end
self.delete
ret = nil
@ -2008,7 +2159,7 @@ class MultiTkIp
return ret.value
rescue SystemExit => e
# exit IP
warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
warn("Warning: " + e.inspect + " on " + self.inspect) if $DEBUG
begin
self._eval_without_enc('exit')
rescue Exception
@ -2031,22 +2182,76 @@ class MultiTkIp
end
private :eval_proc_core
if WITH_RUBY_VM ### Ruby 1.9
def eval_callback(*args)
if block_given?
cmd = Proc.new
else
cmd = args.shift
end
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
if @@CALLBACK_SUBTHREAD.table[self].index(Thread.current)
last_th = nil
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
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)
# 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,
@ -2081,6 +2286,7 @@ class MultiTkIp
*args)
end
end
=end
alias call eval_proc
def bg_eval_proc(*args)
@ -2478,7 +2684,8 @@ end
# depend on TclTkIp
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?
if WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
@ -2507,7 +2714,7 @@ class MultiTkIp
end
rescue SystemExit => e
# exit IP
warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
warn("Warning: " + e.inspect + " on " + self.inspect) if $DEBUG
begin
self._eval_without_enc('exit')
rescue Exception

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -27,6 +27,8 @@ def TkPlace(*args); TkPlace.configure(*args); end
############################################
# classes on Tk module
module Tk
autoload :Busy, 'tk/busy'
autoload :Button, 'tk/button'
autoload :Canvas, 'tk/canvas'
@ -319,9 +321,16 @@ module Tk
@TOPLEVEL_ALIAS_SETUP_PROC = {}
@AUTOLOAD_FILE_SYM_TABLE = Hash.new{|h,k| h[k]={}} # TABLE[file][sym] -> obj
@current_default_widget_set = nil
module TOPLEVEL_ALIASES; end
end
class Object
include Tk::TOPLEVEL_ALIASES
end
############################################
# methods to control default widget set
@ -343,50 +352,387 @@ class << Tk
_replace_toplevel_aliases(target)
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] ||= {}
symbols.each{|sym|
@TOPLEVEL_ALIAS_TABLE[target][sym = sym.to_sym] = obj
# if @current_default_widget_set == target
if @TOPLEVEL_ALIAS_OWNER[sym] == target
Object.class_eval{remove_const sym} if Object.const_defined?(sym)
Object.const_set(sym, obj)
if !topalias_defined?(sym) || target == @current_default_widget_set
@TOPLEVEL_ALIAS_OWNER[sym] = target
replace_topalias(sym, obj)
replace_topobj(sym, obj) unless obj.kind_of?(String) # NOT autoload
end
}
end
###################################
private
def _replace_toplevel_aliases(target)
# check already autoloaded
if (table = @TOPLEVEL_ALIAS_TABLE[current = @current_default_widget_set])
table.each{|sym, file|
if !Object.autoload?(sym) && Object.const_defined?(sym) &&
@TOPLEVEL_ALIAS_TABLE[current][sym].kind_of?(String)
# autoload -> class
@TOPLEVEL_ALIAS_TABLE[current][sym] = Object.const_get(sym)
def regist_sym_for_loaded_file(auto, obj, sym)
@AUTOLOAD_FILE_SYM_TABLE[auto][sym] = obj
reg = /^#{Regexp.quote(auto)}(\.rb|\.so|)$/
@TOPLEVEL_ALIAS_TABLE.each_key{|set|
if @TOPLEVEL_ALIAS_TABLE[set][sym] =~ reg
@TOPLEVEL_ALIAS_TABLE[set][sym] = obj
if @TOPLEVEL_ALIAS_OWNER[sym].nil? || @TOPLEVEL_ALIAS_OWNER[sym] == set
replace_topalias(sym, obj)
replace_topobj(sym, obj) if set == @current_default_widget_set
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
# setup autoloads
@TOPLEVEL_ALIAS_TABLE[target].each{|sym, file|
Object.class_eval{remove_const sym} if Object.const_defined?(sym)
if file.kind_of?(String)
# file => autoload target file
Object.autoload(sym, file)
else
# file => loaded class object
Object.const_set(sym, file)
sym
end
private :set_topalias
def __set_toplevel_aliases__(target, obj, *symbols)
# obj is a kind of String : define autoload path
# Class : use the class object
target = target.to_sym
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
@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
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
############################################
# setup default widget set => :Tk
Tk.default_widget_set = :Tk

Просмотреть файл

@ -9,7 +9,7 @@ class TkBindTag
#BTagID_TBL = {}
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
def mutex; @mutex; end
freeze

118
ext/tk/lib/tk/busy.rb Normal 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

Просмотреть файл

@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Button<Tk::Label
TkCommandNames = ['button'.freeze].freeze
WidgetClassName = 'Button'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('button', @path, *hash_kv(keys, true))
@ -27,4 +27,5 @@ class Tk::Button<Tk::Label
end
#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)

Просмотреть файл

@ -45,7 +45,7 @@ class Tk::Canvas<TkWindow
TkCommandNames = ['canvas'.freeze].freeze
WidgetClassName = 'Canvas'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
TkcItem::CItemID_TBL.delete(@path)
@ -265,6 +265,12 @@ class Tk::Canvas<TkWindow
self
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)
number(tk_send_without_enc('index', tagid(tagOrId), idx))
end
@ -523,11 +529,18 @@ class Tk::Canvas<TkWindow
self
end
def move(tag, x, y)
tk_send_without_enc('move', tagid(tag), x, y)
def move(tag, dx, dy)
tk_send_without_enc('move', tagid(tag), dx, dy)
self
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)
tk_send("postscript", *hash_kv(keys))
end
@ -541,6 +554,15 @@ class Tk::Canvas<TkWindow
self
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)
tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)
self
@ -581,7 +603,8 @@ class Tk::Canvas<TkWindow
end
#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

Просмотреть файл

@ -60,6 +60,9 @@ module TkcTagAccess
@c.itembindinfo(@id, seq)
end
def cget_tkstring(option)
@c.itemcget_tkstring(@id, option)
end
def cget(option)
@c.itemcget(@id, option)
end
@ -116,6 +119,13 @@ module TkcTagAccess
self
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)
@c.index(@id, idx)
end
@ -135,6 +145,13 @@ module TkcTagAccess
self
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)
@c.raise(@id, abovethis)
self
@ -145,6 +162,14 @@ module TkcTagAccess
self
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)
@c.select('adjust', @id, index)
self
@ -203,7 +228,7 @@ class TkcTag<TkObject
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
def mutex; @mutex; end
freeze
@ -389,7 +414,7 @@ class TkcTagCurrent<TkcTagString
end
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
def mutex; @mutex; end
freeze

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -13,7 +13,7 @@ class Tk::Entry<Tk::Label
TkCommandNames = ['entry'.freeze].freeze
WidgetClassName = 'Entry'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# super(__conv_vcmd_on_hash_kv(keys))
@ -116,4 +116,5 @@ class Tk::Entry<Tk::Label
end
#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)

Просмотреть файл

@ -8,7 +8,7 @@ end
########################
require 'tkutil'
require 'tk'
require 'tk' unless Object.const_defined? :TkComm
########################
@ -482,6 +482,26 @@ module TkEvent
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
keys, args = klass._get_all_subst_keys

Просмотреть файл

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

Просмотреть файл

@ -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

Просмотреть файл

@ -6,7 +6,7 @@ require 'tk'
class Tk::Frame<TkWindow
TkCommandNames = ['frame'.freeze].freeze
WidgetClassName = 'Frame'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
################# old version
# def initialize(parent=nil, keys=nil)
@ -128,4 +128,5 @@ class Tk::Frame<TkWindow
end
#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)

Просмотреть файл

@ -11,7 +11,7 @@ class TkImage<TkObject
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
def mutex; @mutex; end
freeze

Просмотреть файл

@ -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)
orig_opt = option
option = option.to_s

Просмотреть файл

@ -6,7 +6,7 @@ require 'tk'
class Tk::Label<TkWindow
TkCommandNames = ['label'.freeze].freeze
WidgetClassName = 'Label'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('label', @path, *hash_kv(keys, true))
@ -18,4 +18,5 @@ class Tk::Label<TkWindow
end
#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)

Просмотреть файл

@ -7,7 +7,7 @@ require 'tk/frame'
class Tk::LabelFrame<Tk::Frame
TkCommandNames = ['labelframe'.freeze].freeze
WidgetClassName = 'Labelframe'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('labelframe', @path, *hash_kv(keys, true))
@ -26,4 +26,6 @@ end
Tk::Labelframe = Tk::LabelFrame
#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)

Просмотреть файл

@ -21,7 +21,7 @@ class Tk::Listbox<TkTextWin
TkCommandNames = ['listbox'.freeze].freeze
WidgetClassName = 'Listbox'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
@ -279,4 +279,6 @@ class Tk::Listbox<TkTextWin
end
#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)

Просмотреть файл

@ -23,7 +23,9 @@ end
module Tk::MacResource
end
#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
extend Tk

Просмотреть файл

@ -33,13 +33,14 @@ module TkMenuEntryConfig
end
private :__item_val2ruby_optkeys
alias entrycget_tkstring itemcget_tkstring
alias entrycget itemcget
alias entrycget_strict itemcget_strict
alias entryconfigure itemconfigure
alias entryconfiginfo itemconfiginfo
alias current_entryconfiginfo current_itemconfiginfo
private :itemcget, :itemcget_strict
private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@ -50,7 +51,7 @@ class Tk::Menu<TkWindow
TkCommandNames = ['menu'.freeze].freeze
WidgetClassName = 'Menu'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
@ -386,9 +387,33 @@ class Tk::Menu<TkWindow
end
#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
=begin
def initialize(parent, type=None)
@ -446,7 +471,9 @@ end
Tk::CloneMenu = Tk::MenuClone
#TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone
#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
def initialize(parent, keys=nil)
@ -480,7 +507,9 @@ class Tk::SysMenu_Help<Tk::Menu
SYSMENU_NAME = 'help'
end
#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
@ -489,7 +518,9 @@ class Tk::SysMenu_System<Tk::Menu
SYSMENU_NAME = 'system'
end
#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
@ -498,13 +529,15 @@ class Tk::SysMenu_Apple<Tk::Menu
SYSMENU_NAME = 'apple'
end
#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
TkCommandNames = ['menubutton'.freeze].freeze
WidgetClassName = 'Menubutton'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
@ -541,7 +574,9 @@ end
Tk::MenuButton = Tk::Menubutton
#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
@ -677,5 +712,7 @@ end
Tk::OptionMenuButton = Tk::OptionMenubutton
#TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton
#TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton
Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
:TkOptionMenubutton, :TkOptionMenuButton)
#Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
# :TkOptionMenubutton, :TkOptionMenuButton)
Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::OptionMenubutton,
:TkOptionMenubutton, :TkOptionMenuButton)

Просмотреть файл

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

Просмотреть файл

@ -7,9 +7,12 @@
# This file can be distributed under the terms of the Ruby.
#
# 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)
# [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.
# Hashes are OK instead of Arrays. Then the entry type ('command',
# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key
# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info
# is acceptable for 'menu' key (then, create sub-menu).
#
# 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)
# 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,
@ -39,6 +54,10 @@
# to the configs of the cascade entry.
module TkMenuSpec
extend TkMenuSpec
MENUSPEC_OPTKEYS = [ 'layout_proc' ]
def _create_menu(parent, menu_info, menu_name = nil,
tearoff = false, default_opts = nil)
if tearoff.kind_of?(Hash)
@ -59,6 +78,7 @@ module TkMenuSpec
end
tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')
tearoff = false unless tearoff # nil --> false
if menu_name
#menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
@ -84,6 +104,23 @@ module TkMenuSpec
tearoff, menu_opts)
options['menu'] = submenu
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)
elsif item_info.kind_of?(Array)
@ -138,6 +175,25 @@ module TkMenuSpec
end
options.update(opts)
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)
elsif /^-+$/ =~ item_info
@ -177,7 +233,7 @@ module TkMenuSpec
end
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]
if tearoff.kind_of?(Hash)
@ -186,14 +242,49 @@ module TkMenuSpec
end
if default_opts.kind_of?(Hash)
keys = _symbolkey2str(default_opts)
else
keys = {}
default_opts = _symbolkey2str(default_opts)
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
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
mbar = _create_menu_for_menubar(parent)
@ -202,14 +293,52 @@ module TkMenuSpec
if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name')
keys['label'] = keys.delete('text') if keys.key?('text')
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)
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)
keys.update(_symbolkey2str(btn_info[2]))
menu_name = keys.delete('menu_name')
end
else
keys = {:label=>btn_info}
end
@ -234,9 +363,42 @@ module TkMenuSpec
if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name')
keys['text'] = keys.delete('label') if keys.key?('label')
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)
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('underline', btn_info[1]) if btn_info[1]
# mbtn.configure('accelerator', btn_info[2]) if btn_info[2]
@ -245,22 +407,41 @@ module TkMenuSpec
menu_name = keys.delete('menu_name')
mbtn.configure(keys)
end
else
mbtn.configure('text', btn_info)
end
mbtn.pack('side' => 'left')
menu = _create_menu(mbtn, menu_info[1..-1], menu_name,
tearoff, default_opts)
mbtn.menu(menu)
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]
end
end
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)
menus = []
(0..(menu.index('last'))).each{|idx|

Просмотреть файл

@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Message<Tk::Label
TkCommandNames = ['message'.freeze].freeze
WidgetClassName = 'Message'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('message', @path, *hash_kv(keys, true))
@ -19,4 +19,6 @@ class Tk::Message<Tk::Label
end
#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)

Просмотреть файл

@ -36,7 +36,7 @@ class TkMsgCatalog < TkObject
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')
if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} {

Просмотреть файл

@ -13,7 +13,7 @@ class TkNamespace < TkObject
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
def mutex; @mutex; end
freeze

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -6,7 +6,7 @@ require 'tk'
class Tk::Scale<TkWindow
TkCommandNames = ['scale'.freeze].freeze
WidgetClassName = 'Scale'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
@ -108,4 +108,5 @@ class Tk::Scale<TkWindow
end
#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)

Просмотреть файл

@ -6,7 +6,7 @@ require 'tk'
class Tk::Scrollbar<TkWindow
TkCommandNames = ['scrollbar'.freeze].freeze
WidgetClassName = 'Scrollbar'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
@assigned = []
@ -148,7 +148,9 @@ class Tk::Scrollbar<TkWindow
end
#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
@ -161,7 +163,9 @@ class Tk::XScrollbar<Tk::Scrollbar
end
#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
@ -174,4 +178,6 @@ class Tk::YScrollbar<Tk::Scrollbar
end
#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)

Просмотреть файл

@ -8,7 +8,7 @@ require 'tk/entry'
class Tk::Spinbox<Tk::Entry
TkCommandNames = ['spinbox'.freeze].freeze
WidgetClassName = 'Spinbox'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
class SpinCommand < TkValidateCommand
class ValidateArgs < TkUtil::CallbackSubst
@ -100,13 +100,36 @@ class Tk::Spinbox<Tk::Entry
tk_send_without_enc('identify', x, y)
end
def invoke(elem)
tk_send_without_enc('invoke', elem)
self
end
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
end
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
end
@ -116,4 +139,6 @@ class Tk::Spinbox<Tk::Entry
end
#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)

Просмотреть файл

@ -29,6 +29,9 @@ module TkTextTagConfig
end
private :__item_pathname
def tag_cget_tkstring(tagOrId, option)
itemcget_tkstring(['tag', tagOrId], option)
end
def tag_cget(tagOrId, option)
itemcget(['tag', tagOrId], option)
end
@ -45,6 +48,9 @@ module TkTextTagConfig
current_itemconfiginfo(['tag', tagOrId], slot)
end
def window_cget_tkstring(tagOrId, option)
itemcget_tkstring(['window', tagOrId], option)
end
def window_cget(tagOrId, option)
itemcget(['window', tagOrId], option)
end
@ -61,7 +67,7 @@ module TkTextTagConfig
current_itemconfiginfo(['window', tagOrId], slot)
end
private :itemcget, :itemcget_strict
private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@ -251,7 +257,7 @@ class Tk::Text<TkTextWin
TkCommandNames = ['text'.freeze].freeze
WidgetClassName = 'Text'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def self.new(*args, &block)
obj = super(*args){}
@ -1570,7 +1576,8 @@ class Tk::Text<TkTextWin
end
#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)
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
tk_call_without_enc(@src_text.path, 'peer', 'create', @path)
end

Просмотреть файл

@ -9,7 +9,7 @@ class TkTextMark<TkObject
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
def mutex; @mutex; end
freeze

Просмотреть файл

@ -11,7 +11,7 @@ class TkTextTag<TkObject
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
def mutex; @mutex; end
freeze
@ -129,6 +129,9 @@ class TkTextTag<TkObject
val
end
def cget_tkstring(key)
@t.tag_cget_tkstring @id, key
end
def cget(key)
@t.tag_cget @id, key
end

Просмотреть файл

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

Просмотреть файл

@ -11,7 +11,7 @@ class Tk::Toplevel<TkWindow
TkCommandNames = ['toplevel'.freeze].freeze
WidgetClassName = 'Toplevel'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
################# old version
# def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
@ -259,4 +259,6 @@ class Tk::Toplevel<TkWindow
end
#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)

Просмотреть файл

@ -53,21 +53,43 @@ module Tk
: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
# (Ttk is a standard library on Tcl/Tk8.5+)
@TOPLEVEL_ALIAS_TABLE[:Ttk].each{|sym, file|
unless Object.autoload?(sym) || Object.const_defined?(sym)
Object.autoload(sym, file)
end
#unless Tk::TOPLEVEL_ALIASES.autoload?(sym) || Tk::TOPLEVEL_ALIASES.const_defined?(sym)
# @TOPLEVEL_ALIAS_OWNER[sym] = :Ttk
# Tk::TOPLEVEL_ALIASES.autoload(sym, file)
#end
Tk.__regist_toplevel_aliases__(:Ttk, file, sym)
}
################################################
@TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
@TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|
# @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
# @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)
Object.autoload :Ttk, 'tkextlib/tile'
Tk.autoload :Tile, 'tkextlib/tile'

Просмотреть файл

@ -16,7 +16,7 @@ class TkVariable
#TkVar_ID_TBL = {}
TkVar_CB_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
def mutex; @mutex; end
freeze
@ -1239,6 +1239,14 @@ end
end
end
def ===(other)
if other.kind_of?(TkVariable)
self.id == other.id
else
super
end
end
def zero?
numeric.zero?
end

Просмотреть файл

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

Просмотреть файл

@ -10,7 +10,8 @@ require 'tk'
module Tk::WinDDE
end
#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
extend Tk
@ -93,7 +94,9 @@ end
module Tk::WinRegistry
end
#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
extend Tk

Просмотреть файл

@ -55,18 +55,20 @@ script may give you some hints about that.
===< support with some examples (may be beta quality) >=======================
Tcllib 1.8
Tklib 0.4.1 http://sourceforge.net/projects/tcllib ==> tcllib
Tcllib 1.11.1
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
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>
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
@ -80,25 +82,25 @@ BLT 2.4z http://sourceforge.net/projects/blt
(http://raa.ruby-lang.org/)
==> blt
TkTreeCtrl CVS/Hd(2005-12-02)
http://sourceforge.net/projects/tktreectrl ==> treectrl
TkTreeCtrl 2.2.9
http://tktreectrl.sourceforge.net/ ==> treectrl
Tile 0.8.0/8.5.1
Tile 0.8.3/8.6b1
http://sourceforge.net/projects/tktable ==> tile
===< 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
TclX CVS/Hd(2005-02-07)
TclX CVS/Hd(2008-12-15)
http://sourceforge.net/projects/tclx
==> tclx (partial support; infox command and
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/

Просмотреть файл

@ -19,6 +19,8 @@ TkPackage.require('BLT')
module Tk
module BLT
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

Просмотреть файл

@ -11,7 +11,7 @@ module Tk::BLT
class Barchart < TkWindow
TkCommandNames = ['::blt::barchart'.freeze].freeze
WidgetClassName = 'Barchart'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
include PlotComponent
include GraphCommand
@ -33,7 +33,7 @@ module Tk::BLT
private :__tkvariable_optkeys
=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={})
if elem.kind_of?(Hash)

Просмотреть файл

@ -14,7 +14,7 @@ module Tk::BLT
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
def mutex; @mutex; end
freeze

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -15,7 +15,7 @@ module Tk::BLT
class Token < TkWindow
WidgetClassName = 'DragDropToken'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def initialize(arg)
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
undef itemcget
undef itemcget_tkstring
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
def source_configure(win, slot, value=None)

Просмотреть файл

@ -11,7 +11,7 @@ module Tk::BLT
class Graph < TkWindow
TkCommandNames = ['::blt::graph'.freeze].freeze
WidgetClassName = 'Graph'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
include PlotComponent
include GraphCommand
@ -27,7 +27,7 @@ module Tk::BLT
private :__strval_optkeys
=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={})
if elem.kind_of?(Hash)

Просмотреть файл

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

Просмотреть файл

@ -11,7 +11,7 @@ module Tk::BLT
class Stripchart < TkWindow
TkCommandNames = ['::blt::stripchart'.freeze].freeze
WidgetClassName = 'Stripchart'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
include PlotComponent
include GraphCommand
@ -28,7 +28,7 @@ module Tk::BLT
private :__strval_optkeys
=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={})
if elem.kind_of?(Hash)

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -13,7 +13,7 @@ module Tk::BLT
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
def mutex; @mutex; end
freeze
@ -132,6 +132,9 @@ module Tk::BLT
@t.tab_bindinfo(@id, context)
end
def cget_tkstring(*args)
@t.tab_cget_tkstring(@id, *args)
end
def cget(*args)
@t.tab_cget(@id, *args)
end
@ -210,7 +213,7 @@ module Tk::BLT
TkCommandNames = ['::blt::tabset'.freeze].freeze
WidgetClassName = 'Tabset'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{
@ -249,6 +252,7 @@ module Tk::BLT
end
private :__item_pathname
alias tab_cget_tkstring itemcget_tkstring
alias tab_cget itemcget
alias tab_cget_strict itemcget_strict
alias tab_configure itemconfigure

Просмотреть файл

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

Просмотреть файл

@ -8,6 +8,10 @@ require 'tkextlib/blt.rb'
module Tk::BLT
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 :CheckButton, 'tkextlib/blt/tile/checkbutton.rb'
autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb'

Просмотреть файл

@ -272,7 +272,7 @@ module Tk::BLT
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
def mutex; @mutex; end
freeze
@ -578,7 +578,7 @@ module Tk::BLT
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
def mutex; @mutex; end
freeze

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -14,7 +14,7 @@ module Tk::BLT
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
def mutex; @mutex; end
freeze

Просмотреть файл

@ -18,6 +18,8 @@ TkPackage.require('BWidget')
module Tk
module BWidget
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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -25,7 +25,7 @@ class Tk::BWidget::ListBox
TkCommandNames = ['ListBox'.freeze].freeze
WidgetClassName = 'ListBox'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
class Event_for_Items < TkEvent::Event
def self._get_extra_args_tbl
@ -212,7 +212,7 @@ class Tk::BWidget::ListBox::Item
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
def mutex; @mutex; end
freeze
@ -294,6 +294,9 @@ class Tk::BWidget::ListBox::Item
val
end
def cget_tkstring(key)
@listbox.itemcget_tkstring(@id, key)
end
def cget(key)
@listbox.itemcget(@id, key)
end

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -17,7 +17,7 @@ end
class Tk::BWidget::PanelFrame
TkCommandNames = ['PanelFrame'.freeze].freeze
WidgetClassName = 'PanelFrame'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() + ['panelforeground', 'panelbackground']
@ -47,11 +47,21 @@ class Tk::BWidget::PanelFrame
end
def items
list(tk_send('items'))
simplelist(tk_send('items')).map{|w| window(w)}
end
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)
self
end
end

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -17,7 +17,17 @@ end
class Tk::BWidget::ScrolledWindow
TkCommandNames = ['ScrolledWindow'.freeze].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)
win = window(tk_send_without_enc('getframe'))

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -17,10 +17,10 @@ end
class Tk::BWidget::StatusBar
TkCommandNames = ['StatusBar'.freeze].freeze
WidgetClassName = 'StatusBar'.freeze
WidgetClassNames[WidgetClassName] = self
WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'showresize'
super() << 'showresize' << 'showseparator' << 'showresizesep'
end
private :__boolval_optkeys
@ -29,7 +29,17 @@ class Tk::BWidget::StatusBar
self
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)
self
end
@ -47,6 +57,6 @@ class Tk::BWidget::StatusBar
end
def items
list(tk_send('items'))
simplelist(tk_send('items')).map{|w| window(w)}
end
end

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше