* ext/tk/*: full update Ruby/Tk to support Ruby(1.9|1.8) and Tc/Tk8.5.

* ext/tk/lib/tkextlib/tile.rb: [incompatible] remove TileWidgets' 
  instate/state/identify method to avoid the conflict with standard
  widget options. Those methods are renamed to ttk_instate/ttk_state/
  ttk_identify (tile_instate/tile_state/tile_identify are available 
  too). Although I don't recommend, if you realy need old methods, 
  please define "Tk::USE_OBSOLETE_TILE_STATE_METHOD = true" before 
  "require 'tkextlib/tile'".

* ext/tk/lib/tkextlib/tile.rb: "Tk::Tile::__Import_Tile_Widgets__!"
  is obsolete. It outputs warning. To control default widget set, 
  use "Tk.default_widget_set = :Ttk".

* ext/tk/lib/tk.rb: __IGNORE_UNKNOWN_CONFIGURE_OPTION__ method and 
  __set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) method are defind 
  as module methods of TkConfigMethod. It may help users to wrap old 
  Ruby/Tk scripts (use standard widgets) to force to use Ttk widgets.
  Ttk widgets don't have some options of standard widgets which are 
  control the view of widgets. When set ignore-mode true, configure 
  method tries to ignoure such unknown options with no exception. 
  Of course, it may raise other troubles on the GUI design. 
  So, those are a little danger methods. 

* ext/tk/lib/tk/itemconfig.rb: __IGNORE_UNKNOWN_CONFIGURE_OPTION__ 
  method and __set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) method 
  are defind as module methods of TkItemConfigMethod as the same 
  purpose as TkConfigMethod's ones.

* ext/tk/sample/ttk_wrapper.rb: A new example. This is a tool for 
  wrapping old Ruby/Tk scripts (which use standard widgets) to use 
  Ttk (Tile) widgets as default.

* ext/tk/sample/tkextlib/tile/demo.rb: use ttk_instate/ttk_state 
  method instead of instate/state method.

* ext/tk/lib/tk/root, ext/tk/lib/tk/namespace.rb,
  ext/tk/lib/tk/text.rb, ext/tk/lib/tkextlib/*: some 'instance_eval's  
  are replaced to "instance_exec(self)".

* ext/tk/lib/tk/event.rb: bug fix on KEY_TBL and PROC_TBL (?x is not 
  a character code on Ruby1.9).

* ext/tk/lib/tk/variable.rb: support new style of operation argument 
  on Tcl/Tk's 'trace' command for variables. 

* ext/tk/sample/demos-jp/widget, ext/tk/sample/demos-en/widget: bug fix

* ext/tk/sammple/demos-jp/textpeer.rb, 
  ext/tk/sammple/demos-en/textpeer.rb: new widget demo.

* ext/tk/tcltklib.c: decrase SEGV troubles (probably)

* ext/tk/lib/tk.rb: remove Thread.critical access if Ruby1.9

* ext/tk/lib/tk/multi-tk.rb: support Ruby1.9 (probably)

* ext/tk/lib/tkextlib/tile.rb: add method to define Tcl/Tk command 
  to make Tcl/Tk theme sources (based on different version of Tile 
  extension) available. 
  (Tk::Tile::__define_LoadImages_proc_for_comaptibility__)

* ext/tk/lib/tk.rb, ext/tk/lib/tk/wm.rb: support dockable frames
  (Tcl/Tk8.5 feature). 'wm' command can treat many kinds of widgets 
  as toplevel widgets.

* ext/tk/lib/tkextlib/tile/style.rb: ditto.
  (Tk::Tile::Style.__define_wrapper_proc_for_compatibility__)

* ext/tk/lib/tk/font.rb: add actual_hash and metrics_hash to get 
  properties as a hash. metrics_hash method returns a boolean value 
  for 'fixed' option. But metrics method returns numeric value 
  (0 or 1) for 'fixed' option, because of backward compatibility. 

* ext/tk/lib/tk/timer.rb: somtimes fail to set callback procedure.

* ext/tk/lib/tk.rb: add Tk.sleep and Tk.wakeup method. Tk.sleep 
  doesn't block the eventloop. It will be better to use the method 
  in event callbacks.

* ext/tk/sample/tksleep_sample.rb: sample script about Tk.sleep.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@15849 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagai 2008-03-29 05:25:45 +00:00
parent 058c981311
commit aff4ce9c77
238 changed files with 9566 additions and 2732 deletions

View file

@ -1,3 +1,87 @@
Sat Mar 29 14:18:41 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/*: full update Ruby/Tk to support Ruby(1.9|1.8) and Tc/Tk8.5.
* ext/tk/lib/tkextlib/tile.rb: [incompatible] remove TileWidgets'
instate/state/identify method to avoid the conflict with standard
widget options. Those methods are renamed to ttk_instate/ttk_state/
ttk_identify (tile_instate/tile_state/tile_identify are available
too). Although I don't recommend, if you realy need old methods,
please define "Tk::USE_OBSOLETE_TILE_STATE_METHOD = true" before
"require 'tkextlib/tile'".
* ext/tk/lib/tkextlib/tile.rb: "Tk::Tile::__Import_Tile_Widgets__!"
is obsolete. It outputs warning. To control default widget set,
use "Tk.default_widget_set = :Ttk".
* ext/tk/lib/tk.rb: __IGNORE_UNKNOWN_CONFIGURE_OPTION__ method and
__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) method are defind
as module methods of TkConfigMethod. It may help users to wrap old
Ruby/Tk scripts (use standard widgets) to force to use Ttk widgets.
Ttk widgets don't have some options of standard widgets which are
control the view of widgets. When set ignore-mode true, configure
method tries to ignoure such unknown options with no exception.
Of course, it may raise other troubles on the GUI design.
So, those are a little danger methods.
* ext/tk/lib/tk/itemconfig.rb: __IGNORE_UNKNOWN_CONFIGURE_OPTION__
method and __set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) method
are defind as module methods of TkItemConfigMethod as the same
purpose as TkConfigMethod's ones.
* ext/tk/sample/ttk_wrapper.rb: A new example. This is a tool for
wrapping old Ruby/Tk scripts (which use standard widgets) to use
Ttk (Tile) widgets as default.
* ext/tk/sample/tkextlib/tile/demo.rb: use ttk_instate/ttk_state
method instead of instate/state method.
* ext/tk/lib/tk/root, ext/tk/lib/tk/namespace.rb,
ext/tk/lib/tk/text.rb, ext/tk/lib/tkextlib/*: some 'instance_eval's
are replaced to "instance_exec(self)".
* ext/tk/lib/tk/event.rb: bug fix on KEY_TBL and PROC_TBL (?x is not
a character code on Ruby1.9).
* ext/tk/lib/tk/variable.rb: support new style of operation argument
on Tcl/Tk's 'trace' command for variables.
* ext/tk/sample/demos-jp/widget, ext/tk/sample/demos-en/widget: bug fix
* ext/tk/sammple/demos-jp/textpeer.rb,
ext/tk/sammple/demos-en/textpeer.rb: new widget demo.
* ext/tk/tcltklib.c: decrase SEGV troubles (probably)
* ext/tk/lib/tk.rb: remove Thread.critical access if Ruby1.9
* ext/tk/lib/tk/multi-tk.rb: support Ruby1.9 (probably)
* ext/tk/lib/tkextlib/tile.rb: add method to define Tcl/Tk command
to make Tcl/Tk theme sources (based on different version of Tile
extension) available.
(Tk::Tile::__define_LoadImages_proc_for_comaptibility__)
* ext/tk/lib/tk.rb, ext/tk/lib/tk/wm.rb: support dockable frames
(Tcl/Tk8.5 feature). 'wm' command can treat many kinds of widgets
as toplevel widgets.
* ext/tk/lib/tkextlib/tile/style.rb: ditto.
(Tk::Tile::Style.__define_wrapper_proc_for_compatibility__)
* ext/tk/lib/tk/font.rb: add actual_hash and metrics_hash to get
properties as a hash. metrics_hash method returns a boolean value
for 'fixed' option. But metrics method returns numeric value
(0 or 1) for 'fixed' option, because of backward compatibility.
* ext/tk/lib/tk/timer.rb: somtimes fail to set callback procedure.
* ext/tk/lib/tk.rb: add Tk.sleep and Tk.wakeup method. Tk.sleep
doesn't block the eventloop. It will be better to use the method
in event callbacks.
* ext/tk/sample/tksleep_sample.rb: sample script about Tk.sleep.
Mon Mar 24 20:07:42 2008 Akinori MUSHA <knu@iDaemons.org> Mon Mar 24 20:07:42 2008 Akinori MUSHA <knu@iDaemons.org>
* eval.c (rb_eval): Call trace hook for if expression after the * eval.c (rb_eval): Call trace hook for if expression after the

View file

@ -125,7 +125,24 @@ module TclTklib
: Tcl7.6 doesn't have this flag. So PARSE_VARNAME is : Tcl7.6 doesn't have this flag. So PARSE_VARNAME is
: defined as 0. : defined as 0.
module TclTkLib::RELEASE_TYPE
: Defines release type number of Tcl/Tk
ALPHA
: ALPHA release
BETA
: BETA release
FINAL
: FINAL release
[module methods] [module methods]
get_version()
: return an array of major, minor, release-type number,
: number, release-type name, and patchlevel of current
: Tcl/Tk library.
mainloop(check_root = true) mainloop(check_root = true)
: Starts the eventloop. If 'check_root' is true, this method : Starts the eventloop. If 'check_root' is true, this method
: doesn't return when a root widget exists. : doesn't return when a root widget exists.
@ -431,6 +448,10 @@ class TclTkIp
: slave interpreter, same to the TclTkLib module method with : slave interpreter, same to the TclTkLib module method with
: the same name. : the same name.
encoding_table
: For Ruby m17n. Return encoding relation table between Ruby's
: Encoding object and Tcl's encoding name.
class TkCallbackBreak < StandardError class TkCallbackBreak < StandardError
class TkCallbackContinue < StandardError class TkCallbackContinue < StandardError
: They are exception classes to break or continue the Tk callback : They are exception classes to break or continue the Tk callback
@ -441,5 +462,8 @@ class TkCallbackContinue < StandardError
: If raise TkCallbackContinue, returns 'continue' code (Then the Tk : If raise TkCallbackContinue, returns 'continue' code (Then the Tk
: interpreter will break the operateion for the current bindtag and : interpreter will break the operateion for the current bindtag and
: starts the operation for the next buindtag for the current event). : starts the operation for the next buindtag for the current event).
: However, current tcltklib supports Ruby's 'break' and 'next' to
: get the same effect. That is, those classes are obsolete. Those
: exist for backward compatibility.
(eof) (eof)

View file

@ -221,7 +221,23 @@ require "tcltklib"
: から抽出されるはずであるからindex_name 引数は nil と : から抽出されるはずであるからindex_name 引数は nil と
: せねばならない. : せねばならない.
モジュール TclTkLib::RELEASE_TYPE
: Tcl/Tk のリリースタイプ番号の定義
定数 ALPHA
: ALPHA リリース
定数 BETA
: BETA リリース
定数 FINAL
: FINAL リリース
モジュールメソッド モジュールメソッド
get_version()
: Tcl/Tk の major, minor, release-type 番号, release-type 名,
: patchlevel を配列にして返す.
mainloop(check_root = true) mainloop(check_root = true)
: イベントループを起動するcheck_root が true であれば, : イベントループを起動するcheck_root が true であれば,
: root widget が存在する限り,このメソッドは終了しない. : root widget が存在する限り,このメソッドは終了しない.
@ -543,6 +559,9 @@ require "tcltklib"
: スレーブ IP の場合には値の設定が許されない (無視される) : スレーブ IP の場合には値の設定が許されない (無視される)
: それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ. : それ以外の点では引数を含めて TclTkLib の同名メソッドに同じ.
encoding_table
: Ruby m17n 用に Ruby と Tk との間の encoding 対応表を返す.
クラス TkCallbackBreak < StandardError クラス TkCallbackBreak < StandardError
クラス TkCallbackContinue < StandardError クラス TkCallbackContinue < StandardError
: これらはイベントコールバックにおいて,コールバック処理を適切に中 : これらはイベントコールバックにおいて,コールバック処理を適切に中
@ -553,5 +572,8 @@ require "tcltklib"
: ドを返す必要があるRuby の手続きが普通に値を返すのでは,それが普 : ドを返す必要があるRuby の手続きが普通に値を返すのでは,それが普
: 通の戻り値であるのか否かを区別ができないため,例外発生を利用した : 通の戻り値であるのか否かを区別ができないため,例外発生を利用した
: 実装を行っている. : 実装を行っている.
: ただし現在では,コールバック手続きを Ruby の break, next で終了す
: ることで同等の結果を得ることができるようになっている.それゆえ,
: これらは必要ないものではあるが,互換性のために残してある.
(eof) (eof)

View file

@ -1,7 +1,6 @@
If you want to use Ruby/Tk (tk.rb and so on), you must have tcltklib.so If you want to use Ruby/Tk (tk.rb and so on), you must have tcltklib.so
which is working correctly. If you fail to call 'require "tcltklib"', which is working correctly. When you have some troubles on compiling,
you may not have tcltklib.so. When you have some troubles on compiling please read README.tcltklib and README.ActiveTcl.
tcltklib, please read README files on tcltklib.
Even if there is a tcltklib.so on your Ruby library directry, it will not Even if there is a tcltklib.so on your Ruby library directry, it will not
work without Tcl/Tk libraries (e.g. libtcl8.4.so) on your environment. work without Tcl/Tk libraries (e.g. libtcl8.4.so) on your environment.
You must also check that your Tcl/Tk is installed properly. You must also check that your Tcl/Tk is installed properly.
@ -9,11 +8,9 @@ You must also check that your Tcl/Tk is installed properly.
-------------------------------------------- --------------------------------------------
( the following is written in EUC-JP ) ( the following is written in EUC-JP )
Ruby/Tk (tk.rb など) を使いたい場合にはtcltklib.so が正しく動いて Ruby/Tk (tk.rb など) を使いたい場合にはtcltklib.so が正しく動いていな
いなければなりません.もし 'require "tcltklib"' に失敗するようなら, ければなりませんコンパイル時に何か問題が生じた場合はREADME.tcltklib
tcltklib.so がインストールされていないのかもしれませんtcltklib の や README.ActiveTcl を見てください.
コンパイル時に何か問題が生じている場合はtcltklib の README ファイル
を見てください.
たとえ Ruby のライブラリディレクトリに tcltklib.so が存在していたとして たとえ Ruby のライブラリディレクトリに tcltklib.so が存在していたとして
も,実行環境に Tcl/Tk ライブラリ (libtcl8.4.so など) がなければ機能しま も,実行環境に Tcl/Tk ライブラリ (libtcl8.4.so など) がなければ機能しま
せんTcl/Tk が正しくインストールされているかもチェックしてください. せんTcl/Tk が正しくインストールされているかもチェックしてください.

View file

@ -16,18 +16,18 @@ some or all of the following options.
--with-tk-dir=<path> --with-tk-dir=<path>
equal to "--with-tk-include=<path>/include --with-tk-lib=<path>/lib" equal to "--with-tk-include=<path>/include --with-tk-lib=<path>/lib"
--with-tcl-include=<dir> the directry containts 'tcl.h' --with-tcl-include=<dir> the directry contains 'tcl.h'
--with-tk-include=<dir> the directry containts 'tk.h' --with-tk-include=<dir> the directry contains 'tk.h'
--with-tcl-lib=<dir> the directry containts 'libtcl<version>.so' --with-tcl-lib=<dir> the directry contains 'libtcl<version>.so'
--with-tk-lib=<dir> the directry containts 'libtk<version>.so' --with-tk-lib=<dir> the directry contains 'libtk<version>.so'
--enable-mac-tcltk-framework (MacOS X) use Tcl/Tk framework --enable-mac-tcltk-framework (MacOS X) use Tcl/Tk framework
(Obsolete. Please use '--enable-tcltk-framework'.) (Obsolete. Please use '--enable-tcltk-framework'.)
--enable-tcltk-framework use Tcl/Tk framework --enable-tcltk-framework use Tcl/Tk framework
--with-tcltk-framework=<dir> the directory containts Tcl/Tk framework; --with-tcltk-framework=<dir> the directory contains Tcl/Tk framework;
"<dir>/Tcl.framework" and "<dir>/Tk.framework". "<dir>/Tcl.framework" and "<dir>/Tk.framework".
When this option is given, it is assumed that When this option is given, it is assumed that
--enable-tcltk-framework option is given also. --enable-tcltk-framework option is given also.
@ -46,8 +46,8 @@ some or all of the following options.
--with-X11-dir=<path> --with-X11-dir=<path>
equal to "--with-X11-include=<path>/include --with-X11-lib=<path>/lib" equal to "--with-X11-include=<path>/include --with-X11-lib=<path>/lib"
--with-X11-include=<dir> the directry contains X11 header files --with-X11-include=<dir> the directry contais X11 header files
--with-X11-lib=<dir> the directry contains X11 libraries --with-X11-lib=<dir> the directry contais X11 libraries
If you forgot to give the options when do 'configure' on toplevel If you forgot to give the options when do 'configure' on toplevel

View file

@ -2,7 +2,8 @@
require 'mkmf' require 'mkmf'
is_win32 = (/mswin32|mingw|cygwin|bccwin32/ =~ RUBY_PLATFORM) #is_win32 = (/mswin32|mingw|cygwin|bccwin32/ =~ RUBY_PLATFORM)
is_win32 = (/mswin|mingw|cygwin|bccwin|wince/ =~ RUBY_PLATFORM)
#is_macosx = (/darwin/ =~ RUBY_PLATFORM) #is_macosx = (/darwin/ =~ RUBY_PLATFORM)
def find_framework(tcl_hdr, tk_hdr) def find_framework(tcl_hdr, tk_hdr)
@ -39,9 +40,13 @@ unless is_win32
have_library("m", "log") have_library("m", "log")
end end
dir_config("tk") tk_idir, tk_ldir = dir_config("tk")
dir_config("tcl") tcl_idir, tcl_ldir = dir_config("tcl")
dir_config("X11") x11_idir, x11_ldir = dir_config("X11")
tk_ldir2 = with_config("tk-lib")
tcl_ldir2 = with_config("tcl-lib")
x11_ldir2 = with_config("X11-lib")
tklib = with_config("tklib") tklib = with_config("tklib")
tcllib = with_config("tcllib") tcllib = with_config("tcllib")
@ -49,8 +54,9 @@ stubs = enable_config("tcltk_stubs") || with_config("tcltk_stubs")
use_X = with_config("X11", (! is_win32)) use_X = with_config("X11", (! is_win32))
def find_tcl(tcllib, stubs) def find_tcl(tcllib, stubs, *opt_paths)
paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"] default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"]
paths = opt_paths.compact.concat(default_paths)
if stubs if stubs
func = "Tcl_InitStubs" func = "Tcl_InitStubs"
lib = "tclstub" lib = "tclstub"
@ -60,20 +66,23 @@ def find_tcl(tcllib, stubs)
end end
if tcllib if tcllib
find_library(tcllib, func, *paths) find_library(tcllib, func, *paths)
elsif find_library(lib, func, *paths)
true
else else
%w[8.5 8.4 8.3 8.2 8.1 8.0 7.6].find { |ver| %w[8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6].find { |ver|
find_library("#{lib}#{ver}", func, *paths) or find_library("#{lib}#{ver}", func, *paths) or
find_library("#{lib}#{ver.delete('.')}", func, *paths) or find_library("#{lib}#{ver.delete('.')}", func, *paths) or
find_library("#{lib}#{ver}g", func, *paths) or
find_library("#{lib}#{ver.delete('.')}g", func, *paths) or
find_library("tcl#{ver}", func, *paths) or find_library("tcl#{ver}", func, *paths) or
find_library("tcl#{ver.delete('.')}", func, *paths) find_library("tcl#{ver.delete('.')}", func, *paths) or
} find_library("tcl#{ver}g", func, *paths) or
find_library("tcl#{ver.delete('.')}g", func, *paths)
} || find_library(lib, func, *paths)
end end
end end
def find_tk(tklib, stubs) def find_tk(tklib, stubs, *opt_paths)
paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"] default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"]
paths = opt_paths.compact.concat(default_paths)
if stubs if stubs
func = "Tk_InitStubs" func = "Tk_InitStubs"
lib = "tkstub" lib = "tkstub"
@ -83,18 +92,27 @@ def find_tk(tklib, stubs)
end end
if tklib if tklib
find_library(tklib, func, *paths) find_library(tklib, func, *paths)
elsif find_library(lib, func, *paths)
true
else else
%w[8.5 8.4 8.3 8.2 8.1 8.0 4.2].find { |ver| %w[8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2].find { |ver|
find_library("#{lib}#{ver}", func, *paths) or find_library("#{lib}#{ver}", func, *paths) or
find_library("#{lib}#{ver.delete('.')}", func, *paths) or find_library("#{lib}#{ver.delete('.')}", func, *paths) or
find_library("#{lib}#{ver}g", func, *paths) or
find_library("#{lib}#{ver.delete('.')}g", func, *paths) or
find_library("tk#{ver}", func, *paths) or find_library("tk#{ver}", func, *paths) or
find_library("tk#{ver.delete('.')}", func, *paths) find_library("tk#{ver.delete('.')}", func, *paths) or
} find_library("tk#{ver}g", func, *paths) or
find_library("tk#{ver.delete('.')}g", func, *paths)
} || find_library(lib, func, *paths)
end end
end end
def find_X11(*opt_paths)
default_paths =
[ "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib" ]
paths = opt_paths.compact.concat(default_paths)
find_library("X11", "XOpenDisplay", *paths)
end
def pthread_check() def pthread_check()
tcl_major_ver = nil tcl_major_ver = nil
tcl_minor_ver = nil tcl_minor_ver = nil
@ -273,13 +291,11 @@ EOF
end end
end end
if tcltk_framework || if have_header("tcl.h") && have_header("tk.h") &&
(have_header("tcl.h") && have_header("tk.h") && ( tcltk_framework ||
( !use_X || find_library("X11", "XOpenDisplay", ( ( !use_X || find_X11(x11_ldir2, x11_ldir) ) &&
"/usr/X11/lib", "/usr/lib/X11", find_tcl(tcllib, stubs, tcl_ldir2, tcl_ldir) &&
"/usr/X11R6/lib", "/usr/openwin/lib")) && find_tk(tklib, stubs, tk_ldir2, tk_ldir) ) )
find_tcl(tcllib, stubs) &&
find_tk(tklib, stubs))
$CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs
$CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM
@ -307,6 +323,8 @@ if tcltk_framework ||
$INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"] $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"]
# create # create
$defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"]
$defs << %[-DRUBY_RELEASE_DATE=\\"#{RUBY_RELEASE_DATE}\\"]
create_makefile("tcltklib") create_makefile("tcltklib")
end end
end end

View file

@ -114,7 +114,14 @@ MultiTkIp_OK.freeze
class MultiTkIp class MultiTkIp
BASE_DIR = File.dirname(__FILE__) BASE_DIR = File.dirname(__FILE__)
@@SLAVE_IP_ID = ['slave'.freeze, '0'.taint].freeze WITH_RUBY_VM = Object.const_defined?(:VM) && ::VM.class == Class
WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class
(@@SLAVE_IP_ID = ['slave'.freeze, '0'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
@@IP_TABLE = {}.taint unless defined?(@@IP_TABLE) @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)
@ -126,14 +133,18 @@ class MultiTkIp
unless defined?(@@TK_CMD_TBL) unless defined?(@@TK_CMD_TBL)
@@TK_CMD_TBL = Object.new.taint @@TK_CMD_TBL = Object.new.taint
@@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint) # @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint)
@@TK_CMD_TBL.instance_variable_set('@tbl', Hash.new{|hash,key|
fail IndexError,
"unknown command ID '#{key}'"
}.taint)
class << @@TK_CMD_TBL class << @@TK_CMD_TBL
allow = [ allow = [
'__send__', '__id__', 'freeze', 'inspect', 'kind_of?', '__send__', '__id__', 'freeze', 'inspect', 'kind_of?', 'object_id',
'[]', '[]=', 'delete', 'each', 'has_key?' '[]', '[]=', 'delete', 'each', 'has_key?'
] ]
instance_methods.each{|m| undef_method(m) unless allow.index(m)} instance_methods.each{|m| undef_method(m) unless allow.index(m.to_s)}
def kind_of?(klass) def kind_of?(klass)
@tbl.kind_of?(klass) @tbl.kind_of?(klass)
@ -206,7 +217,7 @@ class MultiTkIp
def initialize(ip, cmd) def initialize(ip, cmd)
@ip = ip @ip = ip
@cmd = cmd @cmd = cmd
freeze self.freeze
end end
attr_reader :ip, :cmd attr_reader :ip, :cmd
def inspect def inspect
@ -573,7 +584,11 @@ class MultiTkIp
# raise exception # raise exception
begin begin
bt = _toUTF8(e.backtrace.join("\n")) bt = _toUTF8(e.backtrace.join("\n"))
if MultiTkIp::WITH_ENCODING
bt.force_encoding('utf-8')
else
bt.instance_variable_set(:@encoding, 'utf-8') bt.instance_variable_set(:@encoding, 'utf-8')
end
rescue Exception rescue Exception
bt = e.backtrace.join("\n") bt = e.backtrace.join("\n")
end end
@ -695,6 +710,11 @@ class MultiTkIp
###################################### ######################################
unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!
RUN_EVENTLOOP_ON_MAIN_THREAD = false
end
if self.const_defined? :DEFAULT_MASTER_NAME if self.const_defined? :DEFAULT_MASTER_NAME
name = DEFAULT_MASTER_NAME.to_s name = DEFAULT_MASTER_NAME.to_s
else else
@ -723,7 +743,41 @@ class MultiTkIp
fail ArgumentError, "expecting a Hash object for the 2nd argument" fail ArgumentError, "expecting a Hash object for the 2nd argument"
end end
if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!
@interp = TclTkIp.new(name, _keys2opts(keys)) @interp = TclTkIp.new(name, _keys2opts(keys))
else ### Ruby 1.9 !!!!!!!!!!!
@interp_thread = Thread.new{
current = Thread.current
current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys))
#sleep
current[:mutex] = mutex = Mutex.new
current[:root_check] = cond_var = ConditionVariable.new
begin
current[:status] = interp.mainloop(true)
rescue Exception=>e
current[:status] = e
ensure
mutex.synchronize{ cond_var.broadcast }
end
current[:status] = interp.mainloop(false)
}
until @interp_thread[:interp]
Thread.pass
end
# INTERP_THREAD.run
@interp = @interp_thread[:interp]
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
@ip_name = nil @ip_name = nil
@callback_status = [].taint @callback_status = [].taint
@ -853,22 +907,26 @@ class MultiTkIp
Thread.new{ Thread.new{
current = Thread.current current = Thread.current
loop { loop {
mtx, ret, table, script = @init_ip_env_queue.deq mtx, cond, ret, table, script = @init_ip_env_queue.deq
begin begin
ret[0] = table.each{|tg, ip| ip._init_ip_env(script) } ret[0] = table.each{|tg, ip| ip._init_ip_env(script) }
rescue Exception => e rescue Exception => e
ret[0] = e ret[0] = e
ensure ensure
mtx.unlock mtx.synchronize{ cond.signal }
end end
mtx = cond = ret = table = script = nil # clear variables for GC
} }
} }
def self.__init_ip_env__(table, script) def self.__init_ip_env__(table, script)
ret = [] ret = []
mtx = Mutex.new.lock mtx = (Thread.current[:MultiTk_ip_Mutex] ||= Mutex.new)
@init_ip_env_queue.enq([mtx, ret, table, script]) cond = (Thread.current[:MultiTk_ip_CondVar] ||= ConditionVariable.new)
mtx.lock mtx.synchronize{
@init_ip_env_queue.enq([mtx, cond, ret, table, script])
cond.wait(mtx)
}
if ret[0].kind_of?(Exception) if ret[0].kind_of?(Exception)
raise ret[0] raise ret[0]
else else
@ -947,9 +1005,11 @@ class MultiTkIp
private :_parse_slaveopts private :_parse_slaveopts
def _create_slave_ip_name def _create_slave_ip_name
@@SLAVE_IP_ID.mutex.synchronize{
name = @@SLAVE_IP_ID.join('') name = @@SLAVE_IP_ID.join('')
@@SLAVE_IP_ID[1].succ! @@SLAVE_IP_ID[1].succ!
name.freeze name.freeze
}
end end
private :_create_slave_ip_name private :_create_slave_ip_name
@ -1206,7 +1266,20 @@ class MultiTkIp
if safeip == nil if safeip == nil
# create master-ip # create master-ip
unless WITH_RUBY_VM
@interp = TclTkIp.new(name, _keys2opts(tk_opts)) @interp = TclTkIp.new(name, _keys2opts(tk_opts))
else ### Ruby 1.9 !!!!!!!!!!!
@interp_thread = Thread.new{
Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
#sleep
TclTkLib.mainloop(true)
}
until @interp_thread[:interp]
Thread.pass
end
# INTERP_THREAD.run
@interp = @interp_thread[:interp]
end
@ip_name = nil @ip_name = nil
if safe if safe
@ -1221,6 +1294,8 @@ class MultiTkIp
@safe_base = true @safe_base = true
@interp, @ip_name = master.__create_safe_slave_obj(safe_opts, @interp, @ip_name = master.__create_safe_slave_obj(safe_opts,
name, tk_opts) name, tk_opts)
# @interp_thread = nil if RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!
@interp_thread = nil unless WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
if safe if safe
safe = master.safe_level if safe < master.safe_level safe = master.safe_level if safe < master.safe_level
@safe_level = [safe] @safe_level = [safe]
@ -1229,6 +1304,8 @@ class MultiTkIp
end end
else else
@interp, @ip_name = master.__create_trusted_slave_obj(name, tk_opts) @interp, @ip_name = master.__create_trusted_slave_obj(name, tk_opts)
# @interp_thread = nil if RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!
@interp_thread = nil unless WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
if safe if safe
safe = master.safe_level if safe < master.safe_level safe = master.safe_level if safe < master.safe_level
@safe_level = [safe] @safe_level = [safe]
@ -1263,11 +1340,11 @@ class MultiTkIp
@@DEFAULT_MASTER.assign_receiver_and_watchdog(self) @@DEFAULT_MASTER.assign_receiver_and_watchdog(self)
@@IP_TABLE[@threadgroup] = self @@IP_TABLE[@threadgroup] = self
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
@@TK_TABLE_LIST.size.times{ @@TK_TABLE_LIST.size.times{
(tbl = {}).tainted? || tbl.taint (tbl = {}).tainted? || tbl.taint
@tk_table_list << tbl @tk_table_list << tbl
} }
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
class << self class << self
undef :instance_eval undef :instance_eval
@ -1345,8 +1422,13 @@ class << MultiTkIp
alias __new new alias __new new
private :__new private :__new
def new_master(safe=nil, keys={}) def new_master(safe=nil, keys={})
if MultiTkIp::WITH_RUBY_VM
#### TODO !!!!!!
fail RuntimeError,
'sorry, still not support multiple master-interpreters on Ruby VM'
end
if safe.kind_of?(Hash) if safe.kind_of?(Hash)
keys = safe keys = safe
elsif safe.kind_of?(Integer) elsif safe.kind_of?(Integer)
@ -1563,8 +1645,13 @@ class MultiTkIp
return if slave? return if slave?
names.each{|name| names.each{|name|
name = name.to_s name = name.to_s
return if @interp.deleted?
@interp._invoke('rename', name, '') @interp._invoke('rename', name, '')
return if @interp.deleted?
@interp._invoke('interp', 'slaves').split.each{|slave| @interp._invoke('interp', 'slaves').split.each{|slave|
return if @interp.deleted?
@interp._invoke('interp', 'alias', slave, name, '') rescue nil @interp._invoke('interp', 'alias', slave, name, '') rescue nil
} }
} }
@ -1614,11 +1701,16 @@ class MultiTkIp
id = @@TK_TABLE_LIST.size id = @@TK_TABLE_LIST.size
obj = Object.new obj = Object.new
@@TK_TABLE_LIST << obj @@TK_TABLE_LIST << obj
obj.instance_eval <<-EOD obj.instance_variable_set(:@id, id)
def self.method_missing(m, *args) obj.instance_variable_set(:@mutex, Mutex.new)
MultiTkIp.tk_object_table(#{id}).__send__(m, *args) obj.instance_eval{
def self.mutex
@mutex
end end
EOD def self.method_missing(m, *args)
MultiTkIp.tk_object_table(@id).__send__(m, *args)
end
}
obj.freeze obj.freeze
@@IP_TABLE.each{|tg, ip| ip._add_new_tables } @@IP_TABLE.each{|tg, ip| ip._add_new_tables }
return obj return obj
@ -2338,6 +2430,11 @@ end
class MultiTkIp class MultiTkIp
def mainloop(check_root = true, restart_on_dead = true) def mainloop(check_root = true, restart_on_dead = true)
raise SecurityError, "no permission to manipulate" unless self.manipulable? raise SecurityError, "no permission to manipulate" unless self.manipulable?
unless WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
return @interp_thread.value if @interp_thread
end
#return self if self.slave? #return self if self.slave?
#return self if self != @@DEFAULT_MASTER #return self if self != @@DEFAULT_MASTER
if self != @@DEFAULT_MASTER if self != @@DEFAULT_MASTER
@ -2746,9 +2843,10 @@ class MultiTkIp
i = -1 i = -1
brace = 1 brace = 1
str.each_byte {|c| str.each_byte {|c|
c = c.chr
i += 1 i += 1
brace += 1 if c == ?{ brace += 1 if c == '{'
brace -= 1 if c == ?} brace -= 1 if c == '}'
break if brace == 0 break if brace == 0
} }
if i == 0 if i == 0
@ -3187,15 +3285,44 @@ end
# encoding convert # encoding convert
class MultiTkIp class << MultiTkIp
def encoding def encoding_table
raise SecurityError, "no permission to manipulate" unless self.manipulable? __getip.encoding_table
@interp.encoding
end end
end
class MultiTkIp
def encoding_table
@interp.encoding_table
end
def force_default_encoding=(mode)
raise SecurityError, "no permission to manipulate" unless self.manipulable?
@interp.force_default_encoding = mode
end
def force_default_encoding?
raise SecurityError, "no permission to manipulate" unless self.manipulable?
@interp.force_default_encoding?
end
def default_encoding=(enc)
raise SecurityError, "no permission to manipulate" unless self.manipulable?
@interp.default_encoding = enc
end
def encoding=(enc) def encoding=(enc)
raise SecurityError, "no permission to manipulate" unless self.manipulable? raise SecurityError, "no permission to manipulate" unless self.manipulable?
@interp.encoding = enc @interp.encoding = enc
end end
def encoding_name
raise SecurityError, "no permission to manipulate" unless self.manipulable?
@interp.encoding_name
end
def encoding_obj
raise SecurityError, "no permission to manipulate" unless self.manipulable?
@interp.encoding_obj
end
alias encoding encoding_name
alias default_encoding encoding_name
def encoding_convertfrom(str, enc=None) def encoding_convertfrom(str, enc=None)
raise SecurityError, "no permission to manipulate" unless self.manipulable? raise SecurityError, "no permission to manipulate" unless self.manipulable?
@ -3213,12 +3340,28 @@ end
# remove methods for security # remove methods for security
class MultiTkIp class MultiTkIp
INTERP_THREAD = @@DEFAULT_MASTER.instance_variable_get('@interp_thread')
INTERP_MUTEX = INTERP_THREAD[:mutex]
INTERP_ROOT_CHECK = INTERP_THREAD[:root_check]
# undef_method :instance_eval # undef_method :instance_eval
undef_method :instance_variable_get undef_method :instance_variable_get
undef_method :instance_variable_set undef_method :instance_variable_set
end end
module TkCore
if MultiTkIp::WITH_RUBY_VM &&
! MultiTkIp::RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!
INTERP_THREAD = MultiTkIp::INTERP_THREAD
INTERP_MUTEX = MultiTkIp::INTERP_MUTEX
INTERP_ROOT_CHECK = MultiTkIp::INTERP_ROOT_CHECK
end
end
class MultiTkIp
remove_const(:INTERP_THREAD)
remove_const(:INTERP_MUTEX)
remove_const(:INTERP_ROOT_CHECK)
end
# end of MultiTkIp definition # end of MultiTkIp definition
# defend against modification # defend against modification

View file

@ -265,7 +265,7 @@ class TclTkWidget < TclTkCommand
# (used in TclTkInterpreter#initialize()) # (used in TclTkInterpreter#initialize())
# need two arguments # need two arguments
fail("illegal # of parameter") if args.size != 2 fail("invalid # of parameter") if args.size != 2
# ip: interpreter(TclTkIp) # ip: interpreter(TclTkIp)
# exp: tcl/tk representation # exp: tcl/tk representation

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,19 @@
# #
# autoload # autoload
# #
############################################
#######################
# geometry manager # geometry manager
module Tk
autoload :Grid, 'tk/grid'
def Grid(*args); TkGrid.configure(*args); end
autoload :Pack, 'tk/pack'
def Pack(*args); TkPack.configure(*args); end
autoload :Place, 'tk/place'
def Place(*args); TkPlace.configure(*args); end
end
autoload :TkGrid, 'tk/grid' autoload :TkGrid, 'tk/grid'
def TkGrid(*args); TkGrid.configure(*args); end def TkGrid(*args); TkGrid.configure(*args); end
@ -14,19 +24,117 @@ autoload :TkPlace, 'tk/place'
def TkPlace(*args); TkPlace.configure(*args); end def TkPlace(*args); TkPlace.configure(*args); end
####################### ############################################
# others # classes on Tk module
module Tk
autoload :Button, 'tk/button'
autoload :Canvas, 'tk/canvas'
autoload :CheckButton, 'tk/checkbutton'
autoload :Checkbutton, 'tk/checkbutton'
autoload :Entry, 'tk/entry'
autoload :Frame, 'tk/frame'
autoload :Label, 'tk/label'
autoload :LabelFrame, 'tk/labelframe'
autoload :Labelframe, 'tk/labelframe'
autoload :Listbox, 'tk/listbox'
autoload :Menu, 'tk/menu'
autoload :MenuClone, 'tk/menu'
autoload :CloneMenu, 'tk/menu'
autoload :SystemMenu, 'tk/menu'
autoload :SysMenu_Help, 'tk/menu'
autoload :SysMenu_System, 'tk/menu'
autoload :SysMenu_Apple, 'tk/menu'
autoload :Menubutton, 'tk/menu'
autoload :MenuButton, 'tk/menu'
autoload :OptionMenubutton, 'tk/menu'
autoload :OptionMenBbutton, 'tk/menu'
autoload :Message, 'tk/message'
autoload :PanedWindow, 'tk/panedwindow'
autoload :Panedwindow, 'tk/panedwindow'
autoload :RadioButton, 'tk/radiobutton'
autoload :Radiobutton, 'tk/radiobutton'
autoload :Root, 'tk/root'
autoload :Scale, 'tk/scale'
autoload :Scrollbar, 'tk/scrollbar'
autoload :XScrollbar, 'tk/scrollbar'
autoload :YScrollbar, 'tk/scrollbar'
autoload :Spinbox, 'tk/spinbox'
autoload :Text, 'tk/text'
autoload :Toplevel, 'tk/toplevel'
end
############################################
# sub-module of Tk
module Tk
autoload :Clock, 'tk/clock'
autoload :OptionObj, 'tk/optionobj'
autoload :X_Scrollable, 'tk/scrollable'
autoload :Y_Scrollable, 'tk/scrollable'
autoload :Scrollable, 'tk/scrollable'
autoload :Wm, 'tk/wm'
autoload :Wm_for_General, 'tk/wm'
autoload :MacResource, 'tk/macpkg'
autoload :WinDDE, 'tk/winpkg'
autoload :WinRegistry, 'tk/winpkg'
autoload :ValidateConfigure, 'tk/validation'
autoload :ItemValidateConfigure, 'tk/validation'
autoload :EncodedString, 'tk/encodedstr'
def Tk.EncodedString(str, enc = nil); Tk::EncodedString.new(str, enc); end
autoload :BinaryString, 'tk/encodedstr'
def Tk.BinaryString(str); Tk::BinaryString.new(str); end
autoload :UTF8_String, 'tk/encodedstr'
def Tk.UTF8_String(str); Tk::UTF8_String.new(str); end
end
############################################
# toplevel classes/modules (fixed)
autoload :TkBgError, 'tk/bgerror' autoload :TkBgError, 'tk/bgerror'
autoload :TkBindTag, 'tk/bindtag' autoload :TkBindTag, 'tk/bindtag'
autoload :TkBindTagAll, 'tk/bindtag' autoload :TkBindTagAll, 'tk/bindtag'
autoload :TkDatabaseClass, 'tk/bindtag' autoload :TkDatabaseClass, 'tk/bindtag'
autoload :TkButton, 'tk/button'
autoload :TkConsole, 'tk/console' autoload :TkConsole, 'tk/console'
autoload :TkCanvas, 'tk/canvas' autoload :TkcItem, 'tk/canvas'
autoload :TkcArc, 'tk/canvas'
autoload :TkcBitmap, 'tk/canvas'
autoload :TkcImage, 'tk/canvas'
autoload :TkcLine, 'tk/canvas'
autoload :TkcOval, 'tk/canvas'
autoload :TkcPolygon, 'tk/canvas'
autoload :TkcRectangle, 'tk/canvas'
autoload :TkcText, 'tk/canvas'
autoload :TkcWindow, 'tk/canvas'
autoload :TkcTagAccess, 'tk/canvastag' autoload :TkcTagAccess, 'tk/canvastag'
autoload :TkcTag, 'tk/canvastag' autoload :TkcTag, 'tk/canvastag'
@ -36,9 +144,6 @@ autoload :TkcTagAll, 'tk/canvastag'
autoload :TkcTagCurrent, 'tk/canvastag' autoload :TkcTagCurrent, 'tk/canvastag'
autoload :TkcTagGroup, 'tk/canvastag' autoload :TkcTagGroup, 'tk/canvastag'
autoload :TkCheckButton, 'tk/checkbutton'
autoload :TkCheckbutton, 'tk/checkbutton'
autoload :TkClipboard, 'tk/clipboard' autoload :TkClipboard, 'tk/clipboard'
autoload :TkComposite, 'tk/composite' autoload :TkComposite, 'tk/composite'
@ -52,14 +157,10 @@ autoload :TkWarning, 'tk/dialog'
autoload :TkWarning2, 'tk/dialog' autoload :TkWarning2, 'tk/dialog'
autoload :TkWarningObj, 'tk/dialog' autoload :TkWarningObj, 'tk/dialog'
autoload :TkEntry, 'tk/entry'
autoload :TkEvent, 'tk/event' autoload :TkEvent, 'tk/event'
autoload :TkFont, 'tk/font' autoload :TkFont, 'tk/font'
autoload :TkTreatTagFont, 'tk/font' autoload :TkNamedFont, 'tk/font'
autoload :TkFrame, 'tk/frame'
autoload :TkImage, 'tk/image' autoload :TkImage, 'tk/image'
autoload :TkBitmapImage, 'tk/image' autoload :TkBitmapImage, 'tk/image'
@ -71,30 +172,12 @@ autoload :TkTreatItemFont, 'tk/itemfont'
autoload :TkKinput, 'tk/kinput' autoload :TkKinput, 'tk/kinput'
autoload :TkLabel, 'tk/label'
autoload :TkLabelFrame, 'tk/labelframe'
autoload :TkLabelframe, 'tk/labelframe'
autoload :TkListbox, 'tk/listbox'
autoload :TkMacResource, 'tk/macpkg'
autoload :TkMenu, 'tk/menu'
autoload :TkMenuClone, 'tk/menu'
autoload :TkSystemMenu, 'tk/menu' autoload :TkSystemMenu, 'tk/menu'
autoload :TkSysMenu_Help, 'tk/menu'
autoload :TkSysMenu_System, 'tk/menu'
autoload :TkSysMenu_Apple, 'tk/menu'
autoload :TkMenubutton, 'tk/menu'
autoload :TkOptionMenubutton, 'tk/menu'
autoload :TkMenubar, 'tk/menubar' autoload :TkMenubar, 'tk/menubar'
autoload :TkMenuSpec, 'tk/menuspec' autoload :TkMenuSpec, 'tk/menuspec'
autoload :TkMessage, 'tk/message'
autoload :TkManageFocus, 'tk/mngfocus' autoload :TkManageFocus, 'tk/mngfocus'
autoload :TkMsgCatalog, 'tk/msgcat' autoload :TkMsgCatalog, 'tk/msgcat'
@ -110,53 +193,46 @@ autoload :TkPackage, 'tk/package'
autoload :TkPalette, 'tk/palette' autoload :TkPalette, 'tk/palette'
autoload :TkPanedWindow, 'tk/panedwindow'
autoload :TkPanedwindow, 'tk/panedwindow'
autoload :TkRadioButton, 'tk/radiobutton'
autoload :TkRadiobutton, 'tk/radiobutton'
autoload :TkRoot, 'tk/root' autoload :TkRoot, 'tk/root'
autoload :TkScale, 'tk/scale'
autoload :TkScrollbar, 'tk/scrollbar'
autoload :TkXScrollbar, 'tk/scrollbar'
autoload :TkYScrollbar, 'tk/scrollbar'
autoload :TkScrollbox, 'tk/scrollbox' autoload :TkScrollbox, 'tk/scrollbox'
autoload :TkSelection, 'tk/selection' autoload :TkSelection, 'tk/selection'
autoload :TkSpinbox, 'tk/spinbox'
autoload :TkTreatTagFont, 'tk/tagfont' autoload :TkTreatTagFont, 'tk/tagfont'
autoload :TkText, 'tk/text'
autoload :TkTextImage, 'tk/textimage' autoload :TkTextImage, 'tk/textimage'
autoload :TktImage, 'tk/textimage'
autoload :TkTextMark, 'tk/textmark' autoload :TkTextMark, 'tk/textmark'
autoload :TkTextNamedMark, 'tk/textmark' autoload :TkTextNamedMark, 'tk/textmark'
autoload :TkTextMarkInsert, 'tk/textmark' autoload :TkTextMarkInsert, 'tk/textmark'
autoload :TkTextMarkCurrent, 'tk/textmark' autoload :TkTextMarkCurrent, 'tk/textmark'
autoload :TkTextMarkAnchor, 'tk/textmark' autoload :TkTextMarkAnchor, 'tk/textmark'
autoload :TktMark, 'tk/textmark'
autoload :TktNamedMark, 'tk/textmark'
autoload :TktMarkInsert, 'tk/textmark'
autoload :TktMarkCurrent, 'tk/textmark'
autoload :TktMarkAnchor, 'tk/textmark'
autoload :TkTextTag, 'tk/texttag' autoload :TkTextTag, 'tk/texttag'
autoload :TkTextNamedTag, 'tk/texttag' autoload :TkTextNamedTag, 'tk/texttag'
autoload :TkTextTagSel, 'tk/texttag' autoload :TkTextTagSel, 'tk/texttag'
autoload :TktTag, 'tk/texttag'
autoload :TktNamedTag, 'tk/texttag'
autoload :TktTagSel, 'tk/texttag'
autoload :TkTextWindow, 'tk/textwindow' autoload :TkTextWindow, 'tk/textwindow'
autoload :TktWindow, 'tk/textwindow'
autoload :TkAfter, 'tk/timer' autoload :TkAfter, 'tk/timer'
autoload :TkTimer, 'tk/timer' autoload :TkTimer, 'tk/timer'
autoload :TkRTTimer, 'tk/timer' autoload :TkRTTimer, 'tk/timer'
autoload :TkToplevel, 'tk/toplevel'
autoload :TkTextWin, 'tk/txtwin_abst' autoload :TkTextWin, 'tk/txtwin_abst'
autoload :TkValidation, 'tk/validation' autoload :TkValidation, 'tk/validation'
autoload :TkValidateCommand, 'tk/validation'
autoload :TkVariable, 'tk/variable' autoload :TkVariable, 'tk/variable'
autoload :TkVarAccess, 'tk/variable' autoload :TkVarAccess, 'tk/variable'
@ -166,31 +242,173 @@ autoload :TkNamedVirtualEvent,'tk/virtevent'
autoload :TkWinfo, 'tk/winfo' autoload :TkWinfo, 'tk/winfo'
autoload :TkWinDDE, 'tk/winpkg'
autoload :TkWinRegistry, 'tk/winpkg'
autoload :TkXIM, 'tk/xim' autoload :TkXIM, 'tk/xim'
####################### ############################################
# sub-module of Tk # toplevel classes/modules (switchable)
module Tk module Tk
autoload :Clock, 'tk/clock' @TOPLEVEL_ALIAS_TABLE = {}
autoload :OptionObj, 'tk/optionobj' @TOPLEVEL_ALIAS_TABLE[:Tk] = {
autoload :X_Scrollable, 'tk/scrollable' :TkButton => 'tk/button',
autoload :Y_Scrollable, 'tk/scrollable'
autoload :Scrollable, 'tk/scrollable'
autoload :Wm, 'tk/wm'
autoload :ValidateConfigure, 'tk/validation' :TkCanvas => 'tk/canvas',
autoload :ItemValidateConfigure, 'tk/validation'
autoload :EncodedString, 'tk/encodedstr' :TkCheckButton => 'tk/checkbutton',
def Tk.EncodedString(str, enc = nil); Tk::EncodedString.new(str, enc); end :TkCheckbutton => 'tk/checkbutton',
autoload :BinaryString, 'tk/encodedstr' # :TkDialog => 'tk/dialog',
def Tk.BinaryString(str); Tk::BinaryString.new(str); end # :TkDialog2 => 'tk/dialog',
# :TkDialogObj => 'tk/dialog',
# :TkWarning => 'tk/dialog',
# :TkWarning2 => 'tk/dialog',
# :TkWarningObj => 'tk/dialog',
autoload :UTF8_String, 'tk/encodedstr' :TkEntry => 'tk/entry',
def Tk.UTF8_String(str); Tk::UTF8_String.new(str); end
:TkFrame => 'tk/frame',
:TkLabel => 'tk/label',
:TkLabelFrame => 'tk/labelframe',
:TkLabelframe => 'tk/labelframe',
:TkListbox => 'tk/listbox',
:TkMacResource => 'tk/macpkg',
:TkMenu => 'tk/menu',
:TkMenuClone => 'tk/menu',
:TkCloneMenu => 'tk/menu',
# :TkSystemMenu => 'tk/menu',
:TkSysMenu_Help => 'tk/menu',
:TkSysMenu_System => 'tk/menu',
:TkSysMenu_Apple => 'tk/menu',
:TkMenubutton => 'tk/menu',
:TkMenuButton => 'tk/menu',
:TkOptionMenubutton => 'tk/menu',
:TkOptionMenuButton => 'tk/menu',
:TkMessage => 'tk/message',
:TkPanedWindow => 'tk/panedwindow',
:TkPanedwindow => 'tk/panedwindow',
:TkRadioButton => 'tk/radiobutton',
:TkRadiobutton => 'tk/radiobutton',
# :TkRoot => 'tk/root',
:TkScale => 'tk/scale',
:TkScrollbar => 'tk/scrollbar',
:TkXScrollbar => 'tk/scrollbar',
:TkYScrollbar => 'tk/scrollbar',
:TkSpinbox => 'tk/spinbox',
:TkText => 'tk/text',
:TkToplevel => 'tk/toplevel',
:TkWinDDE => 'tk/winpkg',
:TkWinRegistry => 'tk/winpkg',
}
@TOPLEVEL_ALIAS_OWNER = {}
@TOPLEVEL_ALIAS_SETUP_PROC = {}
@current_default_widget_set = nil
end end
############################################
# methods to control default widget set
############################################
class << Tk
def default_widget_set
@current_default_widget_set
end
def default_widget_set=(target)
target = target.to_sym
return target if target == @current_default_widget_set
if (cmd = @TOPLEVEL_ALIAS_SETUP_PROC[target])
cmd.call(target)
end
_replace_toplevel_aliases(target)
end
def __set_toplevel_aliases__(target, obj, *symbols)
@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)
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)
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)
end
@TOPLEVEL_ALIAS_OWNER[sym] = target
}
# update current alias
@current_default_widget_set = target
end
end
############################################
# setup default widget set => :Tk
Tk.default_widget_set = :Tk
############################################
# depend on the version of Tcl/Tk
# major, minor, type, type_name, patchlevel = TclTkLib.get_version
############################################
# Ttk (Tile) support
=begin
if major > 8 ||
(major == 8 && minor > 5) ||
(major == 8 && minor == 5 && type >= TclTkLib::RELEASE_TYPE::BETA)
# Tcl/Tk 8.5 beta or later
Object.autoload :Ttk, 'tkextlib/tile'
Tk.autoload :Tile, 'tkextlib/tile'
require 'tk/ttk_selector'
end
=end
Object.autoload :Ttk, 'tkextlib/tile'
Tk.autoload :Tile, 'tkextlib/tile'
require 'tk/ttk_selector'

View file

@ -8,30 +8,64 @@ class TkBindTag
#BTagID_TBL = {} #BTagID_TBL = {}
BTagID_TBL = TkCore::INTERP.create_table BTagID_TBL = TkCore::INTERP.create_table
Tk_BINDTAG_ID = ["btag".freeze, "00000".taint].freeze
TkCore::INTERP.init_ip_env{ BTagID_TBL.clear } (Tk_BINDTAG_ID = ["btag".freeze, "00000".taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
BTagID_TBL.mutex.synchronize{ BTagID_TBL.clear }
}
def TkBindTag.id2obj(id) def TkBindTag.id2obj(id)
BTagID_TBL[id]? BTagID_TBL[id]: id BTagID_TBL.mutex.synchronize{
(BTagID_TBL[id])? BTagID_TBL[id]: id
}
end end
=begin
def TkBindTag.new_by_name(name, *args, &b) def TkBindTag.new_by_name(name, *args, &b)
BTagID_TBL.mutex.synchronize{
return BTagID_TBL[name] if BTagID_TBL[name] return BTagID_TBL[name] if BTagID_TBL[name]
}
self.new.instance_eval{ self.new.instance_eval{
BTagID_TBL.mutex.synchronize{
BTagID_TBL.delete @id BTagID_TBL.delete @id
@id = name @id = name
BTagID_TBL[@id] = self BTagID_TBL[@id] = self
}
bind(*args, &b) if args != [] bind(*args, &b) if args != []
self self
} }
end end
=end
def TkBindTag.new_by_name(name, *args, &b)
obj = nil
BTagID_TBL.mutex.synchronize{
if BTagID_TBL[name]
obj = BTagID_TBL[name]
else
(obj = BTagID_TBL[name] = self.allocate).instance_eval{
@id = name
}
end
}
bind(*args, &b) if obj && args != []
obj
end
def initialize(*args, &b) def initialize(*args, &b)
Tk_BINDTAG_ID.mutex.synchronize{
# @id = Tk_BINDTAG_ID.join('') # @id = Tk_BINDTAG_ID.join('')
@id = Tk_BINDTAG_ID.join(TkCore::INTERP._ip_id_) @id = Tk_BINDTAG_ID.join(TkCore::INTERP._ip_id_)
Tk_BINDTAG_ID[1].succ! Tk_BINDTAG_ID[1].succ!
}
BTagID_TBL.mutex.synchronize{
BTagID_TBL[@id] = self BTagID_TBL[@id] = self
}
bind(*args, &b) if args != [] bind(*args, &b) if args != []
end end
@ -63,14 +97,37 @@ end
class TkDatabaseClass<TkBindTag class TkDatabaseClass<TkBindTag
=begin
def self.new(name, *args, &b) def self.new(name, *args, &b)
BTagID_TBL.mutex.synchronize{
return BTagID_TBL[name] if BTagID_TBL[name] return BTagID_TBL[name] if BTagID_TBL[name]
}
super(name, *args, &b) super(name, *args, &b)
end end
def initialize(name, *args, &b) def initialize(name, *args, &b)
@id = name @id = name
BTagID_TBL.mutex.synchronize{
BTagID_TBL[@id] = self BTagID_TBL[@id] = self
}
bind(*args, &b) if args != []
end
=end
def self.new(name, *args, &b)
BTagID_TBL.mutex.synchronize{
if BTagID_TBL[name]
BTagID_TBL[name]
else
BTagID_TBL[name] = self.allocate.instance_eval{
initialize(name, *args, &b)
self
}
end
}
end
def initialize(name, *args, &b)
@id = name
bind(*args, &b) if args != [] bind(*args, &b) if args != []
end end

View file

@ -4,7 +4,7 @@
require 'tk' require 'tk'
require 'tk/label' require 'tk/label'
class TkButton<TkLabel class Tk::Button<Tk::Label
TkCommandNames = ['button'.freeze].freeze TkCommandNames = ['button'.freeze].freeze
WidgetClassName = 'Button'.freeze WidgetClassName = 'Button'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -25,3 +25,6 @@ class TkButton<TkLabel
self self
end end
end end
#TkButton = Tk::Button unless Object.const_defined? :TkButton
Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)

View file

@ -1,6 +1,5 @@
# #
# tk/canvas.rb - Tk canvas classes # tk/canvas.rb - Tk canvas classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp> # by Yukihiro Matsumoto <matz@caelum.co.jp>
# #
require 'tk' require 'tk'
@ -40,7 +39,7 @@ module TkCanvasItemConfig
private :__item_pathname private :__item_pathname
end end
class TkCanvas<TkWindow class Tk::Canvas<TkWindow
include TkCanvasItemConfig include TkCanvasItemConfig
include Tk::Scrollable include Tk::Scrollable
@ -186,11 +185,17 @@ class TkCanvas<TkWindow
end end
def delete(*args) def delete(*args)
if TkcItem::CItemID_TBL[self.path] tbl = nil
TkcItem::CItemID_TBL.mutex.synchronize{
tbl = TkcItem::CItemID_TBL[self.path]
}
if tbl
args.each{|tag| args.each{|tag|
find('withtag', tag).each{|item| find('withtag', tag).each{|item|
if item.kind_of?(TkcItem) if item.kind_of?(TkcItem)
TkcItem::CItemID_TBL[self.path].delete(item.id) TkcItem::CItemID_TBL.mutex.synchronize{
tbl.delete(item.id)
}
end end
} }
} }
@ -573,6 +578,10 @@ class TkCanvas<TkWindow
end end
end end
#TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas
Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
class TkcItem<TkObject class TkcItem<TkObject
extend Tk extend Tk
include TkcTagAccess include TkcTagAccess
@ -581,9 +590,12 @@ class TkcItem<TkObject
CItemTypeName = nil CItemTypeName = nil
CItemTypeToClass = {} CItemTypeToClass = {}
CItemID_TBL = TkCore::INTERP.create_table CItemID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ CItemID_TBL.clear } TkCore::INTERP.init_ip_env{
CItemID_TBL.mutex.synchronize{ CItemID_TBL.clear }
}
def TkcItem.type2class(type) def TkcItem.type2class(type)
CItemTypeToClass[type] CItemTypeToClass[type]
@ -591,8 +603,13 @@ class TkcItem<TkObject
def TkcItem.id2obj(canvas, id) def TkcItem.id2obj(canvas, id)
cpath = canvas.path cpath = canvas.path
return id unless CItemID_TBL[cpath] CItemID_TBL.mutex.synchronize{
if CItemID_TBL[cpath]
CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id
else
id
end
}
end end
######################################## ########################################
@ -658,15 +675,17 @@ class TkcItem<TkObject
######################################## ########################################
def initialize(parent, *args) def initialize(parent, *args)
#unless parent.kind_of?(TkCanvas) #unless parent.kind_of?(Tk::Canvas)
# fail ArgumentError, "expect TkCanvas for 1st argument" # fail ArgumentError, "expect Tk::Canvas for 1st argument"
#end #end
@parent = @c = parent @parent = @c = parent
@path = parent.path @path = parent.path
@id = create_self(*args) # an integer number as 'canvas item id' @id = create_self(*args) # an integer number as 'canvas item id'
CItemID_TBL.mutex.synchronize{
CItemID_TBL[@path] = {} unless CItemID_TBL[@path] CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
CItemID_TBL[@path][@id] = self CItemID_TBL[@path][@id] = self
}
end end
def create_self(*args) def create_self(*args)
self.class.create(@c, *args) # return an integer number as 'canvas item id' self.class.create(@c, *args) # return an integer number as 'canvas item id'
@ -687,7 +706,9 @@ class TkcItem<TkObject
def delete def delete
@c.delete @id @c.delete @id
CItemID_TBL.mutex.synchronize{
CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]
}
self self
end end
alias remove delete alias remove delete

View file

@ -199,14 +199,26 @@ class TkcTag<TkObject
include TkcTagAccess include TkcTagAccess
CTagID_TBL = TkCore::INTERP.create_table CTagID_TBL = TkCore::INTERP.create_table
Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ CTagID_TBL.clear } (Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
CTagID_TBL.mutex.synchronize{ CTagID_TBL.clear }
}
def TkcTag.id2obj(canvas, id) def TkcTag.id2obj(canvas, id)
cpath = canvas.path cpath = canvas.path
return id unless CTagID_TBL[cpath] CTagID_TBL.mutex.synchronize{
if CTagID_TBL[cpath]
CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id
else
id
end
}
end end
def initialize(parent, mode=nil, *args) def initialize(parent, mode=nil, *args)
@ -215,11 +227,15 @@ class TkcTag<TkObject
#end #end
@c = parent @c = parent
@cpath = parent.path @cpath = parent.path
Tk_CanvasTag_ID.mutex.synchronize{
# @path = @id = Tk_CanvasTag_ID.join('') # @path = @id = Tk_CanvasTag_ID.join('')
@path = @id = Tk_CanvasTag_ID.join(TkCore::INTERP._ip_id_) @path = @id = Tk_CanvasTag_ID.join(TkCore::INTERP._ip_id_)
Tk_CanvasTag_ID[1].succ!
}
CTagID_TBL.mutex.synchronize{
CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
CTagID_TBL[@cpath][@id] = self CTagID_TBL[@cpath][@id] = self
Tk_CanvasTag_ID[1].succ! }
if mode if mode
tk_call_without_enc(@c.path, "addtag", @id, mode, *args) tk_call_without_enc(@c.path, "addtag", @id, mode, *args)
end end
@ -238,7 +254,9 @@ class TkcTag<TkObject
def delete def delete
@c.delete @id @c.delete @id
CTagID_TBL.mutex.synchronize{
CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath] CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath]
}
self self
end end
alias remove delete alias remove delete
@ -288,23 +306,38 @@ class TkcTag<TkObject
end end
class TkcTagString<TkcTag class TkcTagString<TkcTag
def self.new(parent, name, *args) def self.new(parent, name, mode=nil, *args)
obj = nil
CTagID_TBL.mutex.synchronize{
if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name] if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name]
return CTagID_TBL[parent.path][name] obj = CTagID_TBL[parent.path][name]
else else
super(parent, name, *args) # super(parent, name, *args)
(obj = self.allocate).instance_eval{
@c = parent
@cpath = parent.path
@path = @id = name
CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
CTagID_TBL[@cpath][@id] = self
}
end end
}
if obj && mode
tk_call_without_enc(@c.path, "addtag", @id, mode, *args)
end
obj
end end
def initialize(parent, name, mode=nil, *args) def initialize(parent, name, mode=nil, *args)
# dummy:: not called by 'new' method
#unless parent.kind_of?(TkCanvas) #unless parent.kind_of?(TkCanvas)
# fail ArgumentError, "expect TkCanvas for 1st argument" # fail ArgumentError, "expect TkCanvas for 1st argument"
#end #end
@c = parent @c = parent
@cpath = parent.path @cpath = parent.path
@path = @id = name @path = @id = name
CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
CTagID_TBL[@cpath][@id] = self
if mode if mode
tk_call_without_enc(@c.path, "addtag", @id, mode, *args) tk_call_without_enc(@c.path, "addtag", @id, mode, *args)
end end
@ -312,7 +345,11 @@ class TkcTagString<TkcTag
end end
TkcNamedTag = TkcTagString TkcNamedTag = TkcTagString
class TkcTagAll<TkcTag class TkcTagAll<TkcTagString
def self.new(parent)
super(parent, 'all')
end
=begin
def initialize(parent) def initialize(parent)
#unless parent.kind_of?(TkCanvas) #unless parent.kind_of?(TkCanvas)
# fail ArgumentError, "expect TkCanvas for 1st argument" # fail ArgumentError, "expect TkCanvas for 1st argument"
@ -320,12 +357,19 @@ class TkcTagAll<TkcTag
@c = parent @c = parent
@cpath = parent.path @cpath = parent.path
@path = @id = 'all' @path = @id = 'all'
CTagID_TBL.mutex.synchronize{
CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
CTagID_TBL[@cpath][@id] = self CTagID_TBL[@cpath][@id] = self
}
end end
=end
end end
class TkcTagCurrent<TkcTag class TkcTagCurrent<TkcTagString
def self.new(parent)
super(parent, 'current')
end
=begin
def initialize(parent) def initialize(parent)
#unless parent.kind_of?(TkCanvas) #unless parent.kind_of?(TkCanvas)
# fail ArgumentError, "expect TkCanvas for 1st argument" # fail ArgumentError, "expect TkCanvas for 1st argument"
@ -333,13 +377,21 @@ class TkcTagCurrent<TkcTag
@c = parent @c = parent
@cpath = parent.path @cpath = parent.path
@path = @id = 'current' @path = @id = 'current'
CTagID_TBL.mutex.synchronize{
CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
CTagID_TBL[@cpath][@id] = self CTagID_TBL[@cpath][@id] = self
}
end end
=end
end end
class TkcGroup<TkcTag class TkcGroup<TkcTag
Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint].freeze (Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
#def create_self(parent, *args) #def create_self(parent, *args)
def initialize(parent, *args) def initialize(parent, *args)
#unless parent.kind_of?(TkCanvas) #unless parent.kind_of?(TkCanvas)
@ -347,11 +399,15 @@ class TkcGroup<TkcTag
#end #end
@c = parent @c = parent
@cpath = parent.path @cpath = parent.path
Tk_cGroup_ID.mutex.synchronize{
# @path = @id = Tk_cGroup_ID.join('') # @path = @id = Tk_cGroup_ID.join('')
@path = @id = Tk_cGroup_ID.join(TkCore::INTERP._ip_id_) @path = @id = Tk_cGroup_ID.join(TkCore::INTERP._ip_id_)
Tk_cGroup_ID[1].succ!
}
CTagID_TBL.mutex.synchronize{
CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]
CTagID_TBL[@cpath][@id] = self CTagID_TBL[@cpath][@id] = self
Tk_cGroup_ID[1].succ! }
include(*args) if args != [] include(*args) if args != []
end end
#private :create_self #private :create_self

View file

@ -4,7 +4,7 @@
require 'tk' require 'tk'
require 'tk/radiobutton' require 'tk/radiobutton'
class TkCheckButton<TkRadioButton class Tk::CheckButton<Tk::RadioButton
TkCommandNames = ['checkbutton'.freeze].freeze TkCommandNames = ['checkbutton'.freeze].freeze
WidgetClassName = 'Checkbutton'.freeze WidgetClassName = 'Checkbutton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -22,4 +22,9 @@ class TkCheckButton<TkRadioButton
self self
end end
end end
TkCheckbutton = TkCheckButton
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)

View file

@ -34,7 +34,8 @@ module TkComposite
if klass if klass
# WidgetClassName is a known class # WidgetClassName is a known class
if klass <= TkFrame || klass < TkComposite #if klass <= TkFrame || klass < TkComposite
if klass <= TkFrame || klass < Tk::Frame || klass < TkComposite
# klass is valid for the base frame # klass is valid for the base frame
if self.class <= klass if self.class <= klass
# use my classname # use my classname
@ -50,7 +51,8 @@ module TkComposite
else else
# klass is invalid for the base frame # klass is invalid for the base frame
if self.class < TkFrame || self.class.superclass < TkComposite #if self.class < TkFrame || self.class.superclass < TkComposite
if self.class < TkFrame || self.class.superclass < Tk::Frame || self.class.superclass < TkComposite
# my class name is valid for the base frame -> use my classname # my class name is valid for the base frame -> use my classname
base_class_name = self.class.name base_class_name = self.class.name
if base_class_name == '' if base_class_name == ''
@ -69,7 +71,8 @@ module TkComposite
else else
# no valid WidgetClassName # no valid WidgetClassName
if self.class < TkFrame || self.class.superclass < TkComposite #if self.class < TkFrame || self.class.superclass < TkComposite
if self.class < TkFrame || self.class.superclass < Tk::Frame || self.class.superclass < TkComposite
# my class name is valid for the base frame -> use my classname # my class name is valid for the base frame -> use my classname
base_class_name = self.class.name base_class_name = self.class.name
if base_class_name == '' if base_class_name == ''
@ -108,8 +111,12 @@ module TkComposite
end end
if base_class_name if base_class_name
# @frame = Tk::Frame.new(parent, :class=>base_class_name)
# --> use current TkFrame class
@frame = TkFrame.new(parent, :class=>base_class_name) @frame = TkFrame.new(parent, :class=>base_class_name)
else else
# @frame = Tk::Frame.new(parent)
# --> use current TkFrame class
@frame = TkFrame.new(parent) @frame = TkFrame.new(parent)
end end
@path = @epath = @frame.path @path = @epath = @frame.path
@ -133,6 +140,11 @@ module TkComposite
def initialize_composite(*args) end def initialize_composite(*args) end
private :initialize_composite private :initialize_composite
def inspect
str = super
str.chop << ' @epath=' << @epath.inspect << '>'
end
def option_methods(*opts) def option_methods(*opts)
opts.each{|m_set, m_cget, m_info| opts.each{|m_set, m_cget, m_info|
m_set = m_set.to_s m_set = m_set.to_s

View file

@ -70,13 +70,89 @@ module Tk
# @encoding = ( enc || # @encoding = ( enc ||
# ((self.class::Encoding)? # ((self.class::Encoding)?
# self.class::Encoding : Tk.encoding_system) ) # self.class::Encoding : Tk.encoding_system) )
@encoding = ( enc || enc ||= (self.class::Encoding)?
((self.class::Encoding)?
self.class::Encoding : self.class::Encoding :
((Tk.encoding)? Tk.encoding : Tk.encoding_system) ) ) ((Tk.encoding)? Tk.encoding : Tk.encoding_system)
if TkCore::WITH_ENCODING
unless encobj = Tk::Encoding::ENCODING_TABLE.get_obj(enc)
fail ArgumentError, "unsupported Tk encoding '#{enc}'"
end
self.force_encoding(encobj)
else
@encoding = enc
end
end end
attr_reader :encoding if TkCore::WITH_ENCODING
alias encoding_obj encoding
alias __encoding encoding
def encoding
Tk::Encoding::ENCODING_TABLE.get_name(super())
end
else
def encoding
@encoding
end
alias encoding_obj encoding
end
if TkCore::WITH_ENCODING
# wrapper methods for compatibility
alias __instance_variable_get instance_variable_get
alias __instance_variable_set instance_variable_set
alias __instance_eval instance_eval
alias __instance_variables instance_variables
def instance_variable_get(key)
if (key.to_s == '@encoding')
self.encoding
else
super(key)
end
end
def instance_variable_set(key, value)
if (key.to_s == '@encoding')
if value
self.force_encoding(value)
else
self.force_encoding(Tk::Encoding::UNKNOWN)
end
value
else
super(key, value)
end
end
def instance_eval(*args, &b)
old_enc = @encoding = self.encoding
ret = super(*args, &b)
if @encoding
if @encoding != old_enc
# modified by user
self.force_encoding(@encoding)
end
remove_instance_variable(:@encoding)
else
begin
remove_instance_variable(:@encoding)
# user sets to nil -> use current default
self.force_encoding(Tk.encoding)
rescue NameError
# removed by user -> ignore, because user don't use @encoding
end
end
ret
end
end
def instance_variables
ret = super()
ret << :@encoding # fake !!
ret
end
end end
# def Tk.EncodedString(str, enc = nil) # def Tk.EncodedString(str, enc = nil)
# Tk::EncodedString.new(str, enc) # Tk::EncodedString.new(str, enc)

View file

@ -1,6 +1,5 @@
# #
# tk/entry.rb - Tk entry classes # tk/entry.rb - Tk entry classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp> # by Yukihiro Matsumoto <matz@caelum.co.jp>
require 'tk' require 'tk'
@ -8,7 +7,7 @@ require 'tk/label'
require 'tk/scrollable' require 'tk/scrollable'
require 'tk/validation' require 'tk/validation'
class TkEntry<TkLabel class Tk::Entry<Tk::Label
include X_Scrollable include X_Scrollable
include TkValidation include TkValidation
@ -115,3 +114,6 @@ class TkEntry<TkLabel
val val
end end
end end
#TkEntry = Tk::Entry unless Object.const_defined? :TkEntry
Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)

View file

@ -39,7 +39,9 @@ module TkEvent
RESIZEREQ = 0x200000 RESIZEREQ = 0x200000
CIRCREQ = 0x400000 CIRCREQ = 0x400000
MWHEEL = 0x10000000 MWHEEL = KEY
STRING_DATA = 0x80000000 # special flag for 'data' field
ALL = 0xFFFFFFFF ALL = 0xFFFFFFFF
@ -155,7 +157,7 @@ module TkEvent
'borderwidth' => (Grp::CREATE|Grp::CONFIG), 'borderwidth' => (Grp::CREATE|Grp::CONFIG),
'button' => Grp::BUTTON, 'button' => Grp::BUTTON,
'count' => Grp::EXPOSE, 'count' => Grp::EXPOSE,
'data' => Grp::VIRTUAL, 'data' => (Grp::VIRTUAL|Grp::STRING_DATA),
'delta' => Grp::MWHEEL, 'delta' => Grp::MWHEEL,
'detail' => (Grp::FOCUS|Grp::CROSSING), 'detail' => (Grp::FOCUS|Grp::CROSSING),
'focus' => Grp::CROSSING, 'focus' => Grp::CROSSING,
@ -223,7 +225,8 @@ module TkEvent
rescue rescue
next next
end end
next if !val || val == '??' # next if !val || val == '??'
next if !val || (val == '??' && (flag & Grp::STRING_DATA))
fields[key] = val fields[key] = val
} }
@ -298,31 +301,54 @@ module TkEvent
[ ?b, ?n, :num ], [ ?b, ?n, :num ],
[ ?c, ?n, :count ], [ ?c, ?n, :count ],
[ ?d, ?s, :detail ], [ ?d, ?s, :detail ],
# ?e
[ ?f, ?b, :focus ], [ ?f, ?b, :focus ],
# ?g
[ ?h, ?n, :height ], [ ?h, ?n, :height ],
[ ?i, ?s, :win_hex ], [ ?i, ?s, :win_hex ],
# ?j
[ ?k, ?n, :keycode ], [ ?k, ?n, :keycode ],
# ?l
[ ?m, ?s, :mode ], [ ?m, ?s, :mode ],
# ?n
[ ?o, ?b, :override ], [ ?o, ?b, :override ],
[ ?p, ?s, :place ], [ ?p, ?s, :place ],
# ?q
# ?r
[ ?s, ?x, :state ], [ ?s, ?x, :state ],
[ ?t, ?n, :time ], [ ?t, ?n, :time ],
# ?u
[ ?v, ?n, :value_mask ],
[ ?w, ?n, :width ], [ ?w, ?n, :width ],
[ ?x, ?n, :x ], [ ?x, ?n, :x ],
[ ?y, ?n, :y ], [ ?y, ?n, :y ],
# ?z
[ ?A, ?s, :char ], [ ?A, ?s, :char ],
[ ?B, ?n, :borderwidth ], [ ?B, ?n, :borderwidth ],
# ?C
[ ?D, ?n, :wheel_delta ], [ ?D, ?n, :wheel_delta ],
[ ?E, ?b, :send_event ], [ ?E, ?b, :send_event ],
# ?F
# ?G
# ?H
# ?I
# ?J
[ ?K, ?s, :keysym ], [ ?K, ?s, :keysym ],
# ?L
# ?M
[ ?N, ?n, :keysym_num ], [ ?N, ?n, :keysym_num ],
# ?O
[ ?P, ?s, :property ], [ ?P, ?s, :property ],
# ?Q
[ ?R, ?s, :rootwin_id ], [ ?R, ?s, :rootwin_id ],
[ ?S, ?s, :subwindow ], [ ?S, ?s, :subwindow ],
[ ?T, ?n, :type ], [ ?T, ?n, :type ],
# ?U
# ?V
[ ?W, ?w, :widget ], [ ?W, ?w, :widget ],
[ ?X, ?n, :x_root ], [ ?X, ?n, :x_root ],
[ ?Y, ?n, :y_root ], [ ?Y, ?n, :y_root ],
# ?Z
nil nil
] ]
@ -345,6 +371,22 @@ module TkEvent
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
# setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys
# #
# _get_subst_key() and _get_all_subst_keys() generates key-string # _get_subst_key() and _get_all_subst_keys() generates key-string

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
# #
require 'tk' require 'tk'
class TkFrame<TkWindow class Tk::Frame<TkWindow
TkCommandNames = ['frame'.freeze].freeze TkCommandNames = ['frame'.freeze].freeze
WidgetClassName = 'Frame'.freeze WidgetClassName = 'Frame'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -126,3 +126,6 @@ class TkFrame<TkWindow
end end
end end
end end
#TkFrame = Tk::Frame unless Object.const_defined? :TkFrame
Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)

View file

@ -10,9 +10,16 @@ class TkImage<TkObject
TkCommandNames = ['image'.freeze].freeze TkCommandNames = ['image'.freeze].freeze
Tk_IMGTBL = TkCore::INTERP.create_table Tk_IMGTBL = TkCore::INTERP.create_table
Tk_Image_ID = ['i'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ Tk_IMGTBL.clear } (Tk_Image_ID = ['i'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
Tk_IMGTBL.mutex.synchronize{ Tk_IMGTBL.clear }
}
def self.new(keys=nil) def self.new(keys=nil)
if keys.kind_of?(Hash) if keys.kind_of?(Hash)
@ -27,7 +34,10 @@ class TkImage<TkObject
obj = name obj = name
else else
name = _get_eval_string(name) name = _get_eval_string(name)
obj = nil
Tk_IMGTBL.mutex.synchronize{
obj = Tk_IMGTBL[name] obj = Tk_IMGTBL[name]
}
end end
if obj if obj
if !(keys[:without_creating] || keys['without_creating']) if !(keys[:without_creating] || keys['without_creating'])
@ -43,7 +53,13 @@ class TkImage<TkObject
end end
end end
end end
super(keys) (obj = self.allocate).instance_eval{
Tk_IMGTBL.mutex.synchronize{
initialize(keys)
Tk_IMGTBL[@path] = self
}
}
obj
end end
def initialize(keys=nil) def initialize(keys=nil)
@ -55,19 +71,22 @@ class TkImage<TkObject
without_creating = keys.delete('without_creating') without_creating = keys.delete('without_creating')
end end
unless @path unless @path
Tk_Image_ID.mutex.synchronize{
# @path = Tk_Image_ID.join('') # @path = Tk_Image_ID.join('')
@path = Tk_Image_ID.join(TkCore::INTERP._ip_id_) @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_)
Tk_Image_ID[1].succ! Tk_Image_ID[1].succ!
}
end end
unless without_creating unless without_creating
tk_call_without_enc('image', 'create', tk_call_without_enc('image', 'create',
@type, @path, *hash_kv(keys, true)) @type, @path, *hash_kv(keys, true))
end end
Tk_IMGTBL[@path] = self
end end
def delete def delete
Tk_IMGTBL.mutex.synchronize{
Tk_IMGTBL.delete(@id) if @id Tk_IMGTBL.delete(@id) if @id
}
tk_call_without_enc('image', 'delete', @path) tk_call_without_enc('image', 'delete', @path)
self self
end end
@ -85,9 +104,11 @@ class TkImage<TkObject
end end
def TkImage.names def TkImage.names
Tk_IMGTBL.mutex.synchronize{
Tk.tk_call_without_enc('image', 'names').split.collect!{|id| Tk.tk_call_without_enc('image', 'names').split.collect!{|id|
(Tk_IMGTBL[id])? Tk_IMGTBL[id] : id (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id
} }
}
end end
def TkImage.types def TkImage.types

View file

@ -115,6 +115,14 @@ module TkItemConfigMethod
include TkTreatItemFont include TkTreatItemFont
include TkItemConfigOptkeys include TkItemConfigOptkeys
def TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
@mode || false
end
def TkItemConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode)
fail SecurityError, "can't change the mode" if $SAFE>=4
@mode = (mode)? true: false
end
def __item_cget_cmd(id) def __item_cget_cmd(id)
# maybe need to override # maybe need to override
[self.path, 'itemcget', id] [self.path, 'itemcget', id]
@ -149,7 +157,7 @@ module TkItemConfigMethod
################################################ ################################################
def itemcget(tagOrId, option) def __itemcget_core(tagOrId, option)
orig_opt = option orig_opt = option
option = option.to_s option = option.to_s
@ -224,8 +232,27 @@ module TkItemConfigMethod
tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")), true) tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")), true)
end end
end end
private :__itemcget_core
def itemconfigure(tagOrId, slot, value=None) def itemcget(tagOrId, option)
unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
__itemcget_core(tagOrId, option)
else
begin
__itemcget_core(tagOrId, option)
rescue => e
begin
__itemconfiginfo_core(tagOrId)
# not tag error -> option is unknown
nil
rescue
fail e # tag error
end
end
end
end
def __itemconfigure_core(tagOrId, slot, value=None)
if slot.kind_of? Hash if slot.kind_of? Hash
slot = _symbolkey2str(slot) slot = _symbolkey2str(slot)
@ -288,6 +315,48 @@ module TkItemConfigMethod
end end
self self
end end
private :__itemconfigure_core
def __check_available_itemconfigure_options(tagOrId, keys)
id = tagid(tagOrId)
availables = self.current_itemconfiginfo(id).keys
# add non-standard keys
availables |= __font_optkeys.map{|k|
[k.to_s, "latin#{k}", "ascii#{k}", "kanji#{k}"]
}.flatten
availables |= __item_methodcall_optkeys(id).keys.map{|k| k.to_s}
availables |= __item_keyonly_optkeys(id).keys.map{|k| k.to_s}
keys = _symbolkey2str(keys)
keys.delete_if{|k, v| !(availables.include?(k))}
end
def itemconfigure(tagOrId, slot, value=None)
unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
__itemconfigure_core(tagOrId, slot, value)
else
if slot.kind_of?(Hash)
begin
__itemconfigure_core(tagOrId, slot)
rescue
slot = __check_available_configure_options(tagOrId, slot)
__itemconfigure_core(tagOrId, slot) unless slot.empty?
end
else
begin
__itemconfigure_core(tagOrId, slot, value)
rescue => e
begin
__itemconfiginfo_core(tagOrId)
rescue
fail e # tag error
end
end
end
end
self
end
def __itemconfiginfo_core(tagOrId, slot = nil) def __itemconfiginfo_core(tagOrId, slot = nil)
if TkComm::GET_CONFIGINFO_AS_ARRAY if TkComm::GET_CONFIGINFO_AS_ARRAY
@ -299,6 +368,10 @@ module TkItemConfigMethod
conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]
if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \
|| conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
fnt = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]
if TkFont.is_system_font?(fnt)
conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)
end
conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey) conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey)
elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \
&& conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \
@ -635,6 +708,10 @@ module TkItemConfigMethod
fontconf = ret.assoc(optkey) fontconf = ret.assoc(optkey)
if fontconf && fontconf.size > 2 if fontconf && fontconf.size > 2
ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/}
fnt = fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]
if TkFont.is_system_font?(fnt)
fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)
end
fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey) fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey)
ret.push(fontconf) ret.push(fontconf)
end end
@ -658,7 +735,11 @@ module TkItemConfigMethod
if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \
|| conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = fontobj(tagid(tagOrId), fontkey) fnt = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]
if TkFont.is_system_font?(fnt)
conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)
end
conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey)
{ conf.shift => conf } { conf.shift => conf }
elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \
&& conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
@ -1006,6 +1087,10 @@ module TkItemConfigMethod
ret.delete('latin' << optkey) ret.delete('latin' << optkey)
ret.delete('ascii' << optkey) ret.delete('ascii' << optkey)
ret.delete('kanji' << optkey) ret.delete('kanji' << optkey)
fnt = fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]
if TkFont.is_system_font?(fnt)
fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)
end
fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey) fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey)
ret[optkey] = fontconf ret[optkey] = fontconf
end end
@ -1023,7 +1108,21 @@ module TkItemConfigMethod
private :__itemconfiginfo_core private :__itemconfiginfo_core
def itemconfiginfo(tagOrId, slot = nil) def itemconfiginfo(tagOrId, slot = nil)
if slot && TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
begin
__itemconfiginfo_core(tagOrId, slot) __itemconfiginfo_core(tagOrId, slot)
rescue => e
begin
__itemconfiginfo_core(tagOrId)
# not tag error -> option is unknown
Array.new(__item_configinfo_struct.values.max).unshift(slot.to_s)
rescue
fail e # tag error
end
end
else
__itemconfiginfo_core(tagOrId, slot)
end
end end
def current_itemconfiginfo(tagOrId, slot = nil) def current_itemconfiginfo(tagOrId, slot = nil)

View file

@ -3,7 +3,7 @@
# #
require 'tk' require 'tk'
class TkLabel<TkWindow class Tk::Label<TkWindow
TkCommandNames = ['label'.freeze].freeze TkCommandNames = ['label'.freeze].freeze
WidgetClassName = 'Label'.freeze WidgetClassName = 'Label'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -16,3 +16,6 @@ class TkLabel<TkWindow
#end #end
#private :create_self #private :create_self
end end
#TkLabel = Tk::Label unless Object.const_defined? :TkLabel
Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)

View file

@ -4,7 +4,7 @@
require 'tk' require 'tk'
require 'tk/frame' require 'tk/frame'
class TkLabelFrame<TkFrame class Tk::LabelFrame<Tk::Frame
TkCommandNames = ['labelframe'.freeze].freeze TkCommandNames = ['labelframe'.freeze].freeze
WidgetClassName = 'Labelframe'.freeze WidgetClassName = 'Labelframe'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -22,4 +22,8 @@ class TkLabelFrame<TkFrame
end end
private :__val2ruby_optkeys private :__val2ruby_optkeys
end end
TkLabelframe = TkLabelFrame
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)

View file

@ -15,7 +15,7 @@ module TkListItemConfig
private :__item_listval_optkeys private :__item_listval_optkeys
end end
class TkListbox<TkTextWin class Tk::Listbox<TkTextWin
include TkListItemConfig include TkListItemConfig
include Scrollable include Scrollable
@ -277,3 +277,6 @@ class TkListbox<TkTextWin
end end
=end =end
end end
#TkListbox = Tk::Listbox unless Object.const_defined? :TkListbox
Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)

View file

@ -20,9 +20,14 @@ module Tk
end end
end end
module TkMacResource module Tk::MacResource
end
#TkMacResource = Tk::MacResource
Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)
module Tk::MacResource
extend Tk extend Tk
extend TkMacResource extend Tk::MacResource
TkCommandNames = ['resource'.freeze].freeze TkCommandNames = ['resource'.freeze].freeze

View file

@ -42,7 +42,7 @@ module TkMenuEntryConfig
private :itemconfiginfo, :current_itemconfiginfo private :itemconfiginfo, :current_itemconfiginfo
end end
class TkMenu<TkWindow class Tk::Menu<TkWindow
include Wm include Wm
include TkMenuEntryConfig include TkMenuEntryConfig
extend TkMenuSpec extend TkMenuSpec
@ -140,9 +140,9 @@ class TkMenu<TkWindow
type = keys.delete('type') if keys.has_key?('type') type = keys.delete('type') if keys.has_key?('type')
if keys.empty? if keys.empty?
TkMenuClone.new(self, parent, type) Tk::MenuClone.new(self, parent, type)
else else
TkMenuClone.new(self, parent, type, keys) Tk::MenuClone.new(self, parent, type, keys)
end end
end end
@ -202,6 +202,9 @@ class TkMenu<TkWindow
tk_send_without_enc('unpost') tk_send_without_enc('unpost')
self self
end end
def xposition(index)
number(tk_send_without_enc('xposition', _get_eval_enc_str(index)))
end
def yposition(index) def yposition(index)
number(tk_send_without_enc('yposition', _get_eval_enc_str(index))) number(tk_send_without_enc('yposition', _get_eval_enc_str(index)))
end end
@ -381,8 +384,11 @@ class TkMenu<TkWindow
=end =end
end end
#TkMenu = Tk::Menu unless Object.const_defined? :TkMenu
Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
class TkMenuClone<TkMenu
class Tk::MenuClone<Tk::Menu
=begin =begin
def initialize(parent, type=None) def initialize(parent, type=None)
widgetname = nil widgetname = nil
@ -436,9 +442,12 @@ class TkMenuClone<TkMenu
@src_menu @src_menu
end end
end end
TkCloneMenu = TkMenuClone 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)
module TkSystemMenu module Tk::SystemMenu
def initialize(parent, keys=nil) def initialize(parent, keys=nil)
if parent.kind_of? Hash if parent.kind_of? Hash
keys = _symbolkey2str(parent) keys = _symbolkey2str(parent)
@ -461,38 +470,60 @@ module TkSystemMenu
end end
end end
end end
TkSystemMenu = Tk::SystemMenu
class TkSysMenu_Help<TkMenu class Tk::SysMenu_Help<Tk::Menu
# for all platform # for all platform
include TkSystemMenu include Tk::SystemMenu
SYSMENU_NAME = 'help' SYSMENU_NAME = 'help'
end end
#TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help
Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
class TkSysMenu_System<TkMenu class Tk::SysMenu_System<Tk::Menu
# for Windows # for Windows
include TkSystemMenu include Tk::SystemMenu
SYSMENU_NAME = 'system' SYSMENU_NAME = 'system'
end end
#TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System
Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
class TkSysMenu_Apple<TkMenu class Tk::SysMenu_Apple<Tk::Menu
# for Machintosh # for Machintosh
include TkSystemMenu include Tk::SystemMenu
SYSMENU_NAME = 'apple' SYSMENU_NAME = 'apple'
end end
#TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple
Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
class TkMenubutton<TkLabel class Tk::Menubutton<Tk::Label
TkCommandNames = ['menubutton'.freeze].freeze TkCommandNames = ['menubutton'.freeze].freeze
WidgetClassName = 'Menubutton'.freeze WidgetClassName = 'Menubutton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
def create_self(keys) def create_self(keys)
if keys and keys != None if keys and keys != None
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
# tk_call_without_enc('menubutton', @path, *hash_kv(keys, true)) # tk_call_without_enc('menubutton', @path, *hash_kv(keys, true))
tk_call_without_enc(self.class::TkCommandNames[0], @path, tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true)) *hash_kv(keys, true))
else
begin
tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true))
rescue
tk_call_without_enc(self.class::TkCommandNames[0], @path)
keys = __check_available_configure_options(keys)
unless keys.empty?
tk_call_without_enc('destroy', @path)
tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true))
end
end
end
else else
# tk_call_without_enc('menubutton', @path) # tk_call_without_enc('menubutton', @path)
tk_call_without_enc(self.class::TkCommandNames[0], @path) tk_call_without_enc(self.class::TkCommandNames[0], @path)
@ -506,10 +537,13 @@ class TkMenubutton<TkLabel
private :__boolval_optkeys private :__boolval_optkeys
end end
TkMenuButton = TkMenubutton 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)
class TkOptionMenubutton<TkMenubutton class Tk::OptionMenubutton<Tk::Menubutton
TkCommandNames = ['tk_optionMenu'.freeze].freeze TkCommandNames = ['tk_optionMenu'.freeze].freeze
class OptionMenu<TkMenu class OptionMenu<TkMenu
@ -596,6 +630,9 @@ class TkOptionMenubutton<TkMenubutton
@menu.delete(index, last) @menu.delete(index, last)
self self
end end
def xposition(index)
@menu.xposition(index)
end
def yposition(index) def yposition(index)
@menu.yposition(index) @menu.yposition(index)
end end
@ -629,4 +666,9 @@ class TkOptionMenubutton<TkMenubutton
@menu.current_entryconfiginfo(index, key) @menu.current_entryconfiginfo(index, key)
end end
end end
TkOptionMenuButton = TkOptionMenubutton
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)

View file

@ -89,7 +89,7 @@ require 'tk/frame'
require 'tk/composite' require 'tk/composite'
require 'tk/menuspec' require 'tk/menuspec'
class TkMenubar<TkFrame class TkMenubar<Tk::Frame
include TkComposite include TkComposite
include TkMenuSpec include TkMenuSpec

View file

@ -61,8 +61,12 @@ module TkMenuSpec
tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff') tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')
if menu_name if menu_name
#menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
# --> use current TkMenu class
menu = TkMenu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff) menu = TkMenu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
else else
#menu = Tk::Menu.new(parent, :tearoff=>tearoff)
# --> use current TkMenu class
menu = TkMenu.new(parent, :tearoff=>tearoff) menu = TkMenu.new(parent, :tearoff=>tearoff)
end end
@ -150,7 +154,7 @@ module TkMenuSpec
def _use_menubar?(parent) def _use_menubar?(parent)
use_menubar = false use_menubar = false
if parent.kind_of?(TkRoot) || parent.kind_of?(TkToplevel) if parent.kind_of?(Tk::Root) || parent.kind_of?(Tk::Toplevel)
return true return true
else else
begin begin
@ -164,7 +168,11 @@ module TkMenuSpec
private :_use_menubar? private :_use_menubar?
def _create_menu_for_menubar(parent) def _create_menu_for_menubar(parent)
unless (mbar = parent.menu).kind_of?(TkMenu) #unless (mbar = parent.menu).kind_of?(TkMenu)
# --> use current TkMenu class
mbar = parent.menu
unless parent.menu.kind_of?(Tk::Menu) || parent.menu.kind_of?(TkMenu)
#mbar = Tk::Menu.new(parent, :tearoff=>false)
mbar = TkMenu.new(parent, :tearoff=>false) mbar = TkMenu.new(parent, :tearoff=>false)
parent.menu(mbar) parent.menu(mbar)
end end
@ -221,6 +229,8 @@ module TkMenuSpec
else else
# menubar by menubuttons # menubar by menubuttons
#mbtn = Tk::Menubutton.new(parent)
# --> use current TkMenubutton class
mbtn = TkMenubutton.new(parent) mbtn = TkMenubutton.new(parent)
menu_name = nil menu_name = nil

View file

@ -4,7 +4,7 @@
require 'tk' require 'tk'
require 'tk/label' require 'tk/label'
class TkMessage<TkLabel class Tk::Message<Tk::Label
TkCommandNames = ['message'.freeze].freeze TkCommandNames = ['message'.freeze].freeze
WidgetClassName = 'Message'.freeze WidgetClassName = 'Message'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -17,3 +17,6 @@ class TkMessage<TkLabel
#end #end
private :create_self private :create_self
end end
#TkMessage = Tk::Message unless Object.const_defined? :TkMessage
Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)

View file

@ -74,7 +74,11 @@ class TkMsgCatalog < TkObject
"\n---< backtrace of Ruby side >-----\n" + "\n---< backtrace of Ruby side >-----\n" +
_toUTF8(e.backtrace.join("\n")) + _toUTF8(e.backtrace.join("\n")) +
"\n---< backtrace of Tk side >-------" "\n---< backtrace of Tk side >-------"
if TkCore::WITH_ENCODING
msg.force_encoding('utf-8')
else
msg.instance_variable_set(:@encoding, 'utf-8') msg.instance_variable_set(:@encoding, 'utf-8')
end
rescue Exception rescue Exception
msg = e.class.inspect + ': ' + e.message + "\n" + msg = e.class.inspect + ': ' + e.message + "\n" +
"\n---< backtrace of Ruby side >-----\n" + "\n---< backtrace of Ruby side >-----\n" +

View file

@ -12,17 +12,24 @@ class TkNamespace < TkObject
].freeze ].freeze
Tk_Namespace_ID_TBL = TkCore::INTERP.create_table Tk_Namespace_ID_TBL = TkCore::INTERP.create_table
Tk_Namespace_ID = ["ns".freeze, "00000".taint].freeze
(Tk_Namespace_ID = ["ns".freeze, "00000".taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
Tk_NsCode_RetObjID_TBL = TkCore::INTERP.create_table Tk_NsCode_RetObjID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ TkCore::INTERP.init_ip_env{
Tk_Namespace_ID_TBL.clear Tk_Namespace_ID_TBL.mutex.synchronize{ Tk_Namespace_ID_TBL.clear }
Tk_NsCode_RetObjID_TBL.clear Tk_NsCode_RetObjID_TBL.mutex.synchronize{ Tk_NsCode_RetObjID_TBL.clear }
} }
def TkNamespace.id2obj(id) def TkNamespace.id2obj(id)
Tk_Namespace_ID_TBL.mutex.synchronize{
Tk_Namespace_ID_TBL[id]? Tk_Namespace_ID_TBL[id]: id Tk_Namespace_ID_TBL[id]? Tk_Namespace_ID_TBL[id]: id
}
end end
##################################### #####################################
@ -65,11 +72,13 @@ class TkNamespace < TkObject
def cget(slot) def cget(slot)
if slot == :namespace || slot == 'namespace' if slot == :namespace || slot == 'namespace'
ns = super(slot) ns = super(slot)
Tk_Namespace_ID_TBL.mutex.synchronize{
if TkNamespace::Tk_Namespace_ID_TBL.key?(ns) if TkNamespace::Tk_Namespace_ID_TBL.key?(ns)
TkNamespace::Tk_Namespace_ID_TBL[ns] TkNamespace::Tk_Namespace_ID_TBL[ns]
else else
ns ns
end end
}
else else
super(slot) super(slot)
end end
@ -79,9 +88,11 @@ class TkNamespace < TkObject
if slot if slot
if slot == :namespace || slot == 'namespace' if slot == :namespace || slot == 'namespace'
val = super(slot) val = super(slot)
Tk_Namespace_ID_TBL.mutex.synchronize{
if TkNamespace::Tk_Namespace_ID_TBL.key?(val) if TkNamespace::Tk_Namespace_ID_TBL.key?(val)
val = TkNamespace::Tk_Namespace_ID_TBL[val] val = TkNamespace::Tk_Namespace_ID_TBL[val]
end end
}
else else
val = super(slot) val = super(slot)
end end
@ -96,6 +107,7 @@ class TkNamespace < TkObject
info = super() info = super()
if TkComm::GET_CONFIGINFO_AS_ARRAY if TkComm::GET_CONFIGINFO_AS_ARRAY
Tk_Namespace_ID_TBL.mutex.synchronize{
info.map!{|inf| info.map!{|inf|
if inf[0] == 'namespace' && if inf[0] == 'namespace' &&
TkNamespace::Tk_Namespace_ID_TBL.key?(inf[-1]) TkNamespace::Tk_Namespace_ID_TBL.key?(inf[-1])
@ -104,11 +116,14 @@ class TkNamespace < TkObject
inf inf
end end
} }
}
else # ! TkComm::GET_CONFIGINFO_AS_ARRAY else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
val = info['namespace'] val = info['namespace']
Tk_Namespace_ID_TBL.mutex.synchronize{
if TkNamespace::Tk_Namespace_ID_TBL.key?(val) if TkNamespace::Tk_Namespace_ID_TBL.key?(val)
info['namespace'] = TkNamespace::Tk_Namespace_ID_TBL[val] info['namespace'] = TkNamespace::Tk_Namespace_ID_TBL[val]
end end
}
end end
info info
@ -215,9 +230,11 @@ class TkNamespace < TkObject
def initialize(name = nil, parent = nil) def initialize(name = nil, parent = nil)
unless name unless name
Tk_Namespace_ID.mutex.synchronize{
# name = Tk_Namespace_ID.join('') # name = Tk_Namespace_ID.join('')
name = Tk_Namespace_ID.join(TkCore::INTERP._ip_id_) name = Tk_Namespace_ID.join(TkCore::INTERP._ip_id_)
Tk_Namespace_ID[1].succ! Tk_Namespace_ID[1].succ!
}
end end
name = __tk_call('namespace', 'current') if name == '' name = __tk_call('namespace', 'current') if name == ''
if parent if parent
@ -252,7 +269,9 @@ class TkNamespace < TkObject
# create namespace # create namespace
__tk_call('namespace', 'eval', @fullname, '') __tk_call('namespace', 'eval', @fullname, '')
Tk_Namespace_ID_TBL.mutex.synchronize{
Tk_Namespace_ID_TBL[@fullname] = self Tk_Namespace_ID_TBL[@fullname] = self
}
end end
def self.children(*args) def self.children(*args)
@ -260,12 +279,14 @@ class TkNamespace < TkObject
# <pattern> must be glob-style pattern # <pattern> must be glob-style pattern
tk_split_simplelist(tk_call('namespace', 'children', *args)).collect{|ns| tk_split_simplelist(tk_call('namespace', 'children', *args)).collect{|ns|
# ns is fullname # ns is fullname
Tk_Namespace_ID_TBL.mutex.synchronize{
if Tk_Namespace_ID_TBL.key?(ns) if Tk_Namespace_ID_TBL.key?(ns)
Tk_Namespace_ID_TBL[ns] Tk_Namespace_ID_TBL[ns]
else else
ns ns
end end
} }
}
end end
def children(pattern=None) def children(pattern=None)
TkNamespace.children(@fullname, pattern) TkNamespace.children(@fullname, pattern)
@ -290,14 +311,24 @@ class TkNamespace < TkObject
def code(script = Proc.new) def code(script = Proc.new)
if script.kind_of?(String) if script.kind_of?(String)
cmd = proc{|*args| cmd = proc{|*args|
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
obj = ScopeArgs.new(@fullname,*args)
ret = obj.instance_exec(obj, script)
else
ret = ScopeArgs.new(@fullname,*args).instance_eval(script) ret = ScopeArgs.new(@fullname,*args).instance_eval(script)
end
id = ret.object_id id = ret.object_id
TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret
id id
} }
elsif script.kind_of?(Proc) elsif script.kind_of?(Proc)
cmd = proc{|*args| cmd = proc{|*args|
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
obj = ScopeArgs.new(@fullname,*args)
ret = obj.instance_exec(obj, &script)
else
ret = ScopeArgs.new(@fullname,*args).instance_eval(&script) ret = ScopeArgs.new(@fullname,*args).instance_eval(&script)
end
id = ret.object_id id = ret.object_id
TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret
id id
@ -319,11 +350,13 @@ class TkNamespace < TkObject
def self.current def self.current
ns = self.current_path ns = self.current_path
Tk_Namespace_ID_TBL.mutex.synchronize{
if Tk_Namespace_ID_TBL.key?(ns) if Tk_Namespace_ID_TBL.key?(ns)
Tk_Namespace_ID_TBL[ns] Tk_Namespace_ID_TBL[ns]
else else
ns ns
end end
}
end end
def current_namespace def current_namespace
# ns_tk_call('namespace', 'current') # ns_tk_call('namespace', 'current')
@ -335,12 +368,14 @@ class TkNamespace < TkObject
def self.delete(*ns_list) def self.delete(*ns_list)
tk_call('namespace', 'delete', *ns_list) tk_call('namespace', 'delete', *ns_list)
ns_list.each{|ns| ns_list.each{|ns|
Tk_Namespace_ID_TBL.mutex.synchronize{
if ns.kind_of?(TkNamespace) if ns.kind_of?(TkNamespace)
Tk_Namespace_ID_TBL.delete(ns.path) Tk_Namespace_ID_TBL.delete(ns.path)
else else
Tk_Namespace_ID_TBL.delete(ns.to_s) Tk_Namespace_ID_TBL.delete(ns.to_s)
end end
} }
}
end end
def delete def delete
TkNamespece.delete(@fullname) TkNamespece.delete(@fullname)
@ -371,7 +406,7 @@ class TkNamespace < TkObject
def self.eval(namespace, cmd = Proc.new, *args) def self.eval(namespace, cmd = Proc.new, *args)
#tk_call('namespace', 'eval', namespace, cmd, *args) #tk_call('namespace', 'eval', namespace, cmd, *args)
TkNamespace.new(namespece).eval(cmd, *args) TkNamespace.new(namespace).eval(cmd, *args)
end end
=begin =begin
def eval(cmd = Proc.new, *args) def eval(cmd = Proc.new, *args)
@ -444,11 +479,13 @@ class TkNamespace < TkObject
def self.parent(namespace=None) def self.parent(namespace=None)
ns = tk_call('namespace', 'parent', namespace) ns = tk_call('namespace', 'parent', namespace)
Tk_Namespace_ID_TBL.mutex.synchronize{
if Tk_Namespace_ID_TBL.key?(ns) if Tk_Namespace_ID_TBL.key?(ns)
Tk_Namespace_ID_TBL[ns] Tk_Namespace_ID_TBL[ns]
else else
ns ns
end end
}
end end
def parent def parent
tk_call('namespace', 'parent', @fullname) tk_call('namespace', 'parent', @fullname)

View file

@ -8,7 +8,11 @@ module TkOptionDB
extend Tk extend Tk
TkCommandNames = ['option'.freeze].freeze TkCommandNames = ['option'.freeze].freeze
CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint].freeze (CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
module Priority module Priority
WidgetDefault = 20 WidgetDefault = 20
@ -250,8 +254,10 @@ module TkOptionDB
def __create_new_class(klass, func, safe = 4, add = false, parent = nil) def __create_new_class(klass, func, safe = 4, add = false, parent = nil)
if klass.kind_of?(TkWindow) if klass.kind_of?(TkWindow)
carrier = klass.path carrier = klass.path
CmdClassID.mutex.synchronize{
klass = CmdClassID.join(TkCore::INTERP._ip_id_) klass = CmdClassID.join(TkCore::INTERP._ip_id_)
CmdClassID[1].succ! CmdClassID[1].succ!
}
parent = nil # ignore parent parent = nil # ignore parent
else else
klass = klass.to_s if klass.kind_of?(Symbol) klass = klass.to_s if klass.kind_of?(Symbol)
@ -312,7 +318,7 @@ module TkOptionDB
:singleton_methods, :remove_const, :remove_method, :undef_method, :singleton_methods, :remove_const, :remove_method, :undef_method,
:to_s, :inspect, :display, :method, :methods, :respond_to?, :to_s, :inspect, :display, :method, :methods, :respond_to?,
:instance_variable_get, :instance_variable_set, :instance_method, :instance_variable_get, :instance_variable_set, :instance_method,
:instance_eval, :instance_variables, :kind_of?, :is_a?, :instance_eval, :instance_exec, :instance_variables, :kind_of?, :is_a?,
:private_methods, :protected_methods, :public_methods ].each{|m| :private_methods, :protected_methods, :public_methods ].each{|m|
alias_method(m, :__null_method) alias_method(m, :__null_method)
} }
@ -362,7 +368,7 @@ module TkOptionDB
def new_proc_class_random(klass, func, safe = 4, add = false, &b) def new_proc_class_random(klass, func, safe = 4, add = false, &b)
eval_under_random_base(){ eval_under_random_base(){
TkOption.new_proc_class(klass, func, safe, add, self, &b) TkOptionDB.new_proc_class(klass, func, safe, add, self, &b)
} }
end end
module_function :new_proc_class_random module_function :new_proc_class_random

View file

@ -136,4 +136,8 @@ module TkPackage
def vsatisfies(version1, version2) def vsatisfies(version1, version2)
bool(tk_call('package', 'vsatisfies', version1, version2)) bool(tk_call('package', 'vsatisfies', version1, version2))
end end
def prefer(setting = None)
tk_call('package', 'prefer', setting)
end
end end

View file

@ -3,7 +3,7 @@
# #
require 'tk' require 'tk'
class TkPanedWindow<TkWindow class Tk::PanedWindow<TkWindow
TkCommandNames = ['panedwindow'.freeze].freeze TkCommandNames = ['panedwindow'.freeze].freeze
WidgetClassName = 'Panedwindow'.freeze WidgetClassName = 'Panedwindow'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -229,4 +229,9 @@ class TkPanedWindow<TkWindow
list(tk_send_without_enc('panes')) list(tk_send_without_enc('panes'))
end end
end end
TkPanedwindow = TkPanedWindow
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)

View file

@ -4,7 +4,7 @@
require 'tk' require 'tk'
require 'tk/button' require 'tk/button'
class TkRadioButton<TkButton class Tk::RadioButton<Tk::Button
TkCommandNames = ['radiobutton'.freeze].freeze TkCommandNames = ['radiobutton'.freeze].freeze
WidgetClassName = 'Radiobutton'.freeze WidgetClassName = 'Radiobutton'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -63,4 +63,9 @@ class TkRadioButton<TkButton
end end
end end
end end
TkRadiobutton = TkRadioButton
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)

View file

@ -5,7 +5,7 @@ require 'tk'
require 'tk/wm' require 'tk/wm'
require 'tk/menuspec' require 'tk/menuspec'
class TkRoot<TkWindow class Tk::Root<TkWindow
include Wm include Wm
include TkMenuSpec include TkMenuSpec
@ -14,28 +14,7 @@ class TkRoot<TkWindow
end end
private :__methodcall_optkeys private :__methodcall_optkeys
=begin def Root.new(keys=nil, &b)
ROOT = []
def TkRoot.new(keys=nil)
if ROOT[0]
Tk_WINDOWS["."] = ROOT[0]
return ROOT[0]
end
new = super(:without_creating=>true, :widgetname=>'.')
if keys # wm commands
keys.each{|k,v|
if v.kind_of? Array
new.send(k,*v)
else
new.send(k,v)
end
}
end
ROOT[0] = new
Tk_WINDOWS["."] = new
end
=end
def TkRoot.new(keys=nil, &b)
unless TkCore::INTERP.tk_windows['.'] unless TkCore::INTERP.tk_windows['.']
TkCore::INTERP.tk_windows['.'] = TkCore::INTERP.tk_windows['.'] =
super(:without_creating=>true, :widgetname=>'.'){} super(:without_creating=>true, :widgetname=>'.'){}
@ -62,7 +41,13 @@ class TkRoot<TkWindow
} }
end end
root.instance_eval(&b) if block_given? if block_given?
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
root.instance_exec(root, &b)
else
root.instance_eval(&b)
end
end
root root
end end
@ -102,7 +87,9 @@ class TkRoot<TkWindow
self.menu self.menu
end end
def TkRoot.destroy def Root.destroy
TkCore::INTERP._invoke('destroy', '.') TkCore::INTERP._invoke('destroy', '.')
end end
end end
TkRoot = Tk::Root unless Object.const_defined? :TkRoot

View file

@ -3,7 +3,7 @@
# #
require 'tk' require 'tk'
class TkScale<TkWindow class Tk::Scale<TkWindow
TkCommandNames = ['scale'.freeze].freeze TkCommandNames = ['scale'.freeze].freeze
WidgetClassName = 'Scale'.freeze WidgetClassName = 'Scale'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -14,9 +14,24 @@ class TkScale<TkWindow
cmd = keys.delete('command') cmd = keys.delete('command')
keys['command'] = proc{|val| cmd.call(val.to_f)} keys['command'] = proc{|val| cmd.call(val.to_f)}
end end
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
#tk_call_without_enc('scale', @path, *hash_kv(keys, true)) #tk_call_without_enc('scale', @path, *hash_kv(keys, true))
tk_call_without_enc(self.class::TkCommandNames[0], @path, tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true)) *hash_kv(keys, true))
else
begin
tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true))
rescue
tk_call_without_enc(self.class::TkCommandNames[0], @path)
keys = __check_available_configure_options(keys)
unless keys.empty?
tk_call_without_enc('destroy', @path)
tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true))
end
end
end
else else
#tk_call_without_enc('scale', @path) #tk_call_without_enc('scale', @path)
tk_call_without_enc(self.class::TkCommandNames[0], @path) tk_call_without_enc(self.class::TkCommandNames[0], @path)
@ -84,3 +99,6 @@ class TkScale<TkWindow
val val
end end
end end
#TkScale = Tk::Scale unless Object.const_defined? :TkScale
Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)

View file

@ -3,7 +3,7 @@
# #
require 'tk' require 'tk'
class TkScrollbar<TkWindow class Tk::Scrollbar<TkWindow
TkCommandNames = ['scrollbar'.freeze].freeze TkCommandNames = ['scrollbar'.freeze].freeze
WidgetClassName = 'Scrollbar'.freeze WidgetClassName = 'Scrollbar'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -19,9 +19,24 @@ class TkScrollbar<TkWindow
} }
if keys and keys != None if keys and keys != None
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
#tk_call_without_enc('scrollbar', @path, *hash_kv(keys, true)) #tk_call_without_enc('scrollbar', @path, *hash_kv(keys, true))
tk_call_without_enc(self.class::TkCommandNames[0], @path, tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true)) *hash_kv(keys, true))
else
begin
tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true))
rescue
tk_call_without_enc(self.class::TkCommandNames[0], @path)
keys = __check_available_configure_options(keys)
unless keys.empty?
tk_call_without_enc('destroy', @path)
tk_call_without_enc(self.class::TkCommandNames[0], @path,
*hash_kv(keys, true))
end
end
end
else else
#tk_call_without_enc('scrollbar', @path) #tk_call_without_enc('scrollbar', @path)
tk_call_without_enc(self.class::TkCommandNames[0], @path) tk_call_without_enc(self.class::TkCommandNames[0], @path)
@ -103,9 +118,33 @@ class TkScrollbar<TkWindow
def activate(element=None) def activate(element=None)
tk_send_without_enc('activate', element) tk_send_without_enc('activate', element)
end end
def moveto(fraction)
tk_send_without_enc('moveto', fraction)
self
end end
class TkXScrollbar<TkScrollbar def scroll(*args)
tk_send_without_enc('scroll', *args)
self
end
def scroll_units(num)
scroll(num, 'units')
self
end
def scroll_pages(num)
scroll(num, 'pages')
self
end
end
#TkScrollbar = Tk::Scrollbar unless Object.const_defined? :TkScrollbar
Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)
class Tk::XScrollbar<Tk::Scrollbar
def create_self(keys) def create_self(keys)
keys = {} unless keys keys = {} unless keys
keys['orient'] = 'horizontal' keys['orient'] = 'horizontal'
@ -114,7 +153,11 @@ class TkXScrollbar<TkScrollbar
private :create_self private :create_self
end end
class TkYScrollbar<TkScrollbar #TkXScrollbar = Tk::XScrollbar unless Object.const_defined? :TkXScrollbar
Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)
class Tk::YScrollbar<Tk::Scrollbar
def create_self(keys) def create_self(keys)
keys = {} unless keys keys = {} unless keys
keys['orient'] = 'vertical' keys['orient'] = 'vertical'
@ -122,3 +165,6 @@ class TkYScrollbar<TkScrollbar
end end
private :create_self private :create_self
end end
#TkYScrollbar = Tk::YScrollbar unless Object.const_defined? :TkYScrollbar
Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)

View file

@ -1,16 +1,19 @@
# #
# tk/scrollbox.rb - Tk Listbox with Scrollbar # tk/scrollbox.rb - Tk Listbox with Scrollbar
# as an example of Composite Widget # as an example of Composite Widget
# $Date$
# by Yukihiro Matsumoto <matz@netlab.co.jp> # by Yukihiro Matsumoto <matz@netlab.co.jp>
# #
require 'tk' require 'tk'
require 'tk/listbox' require 'tk/listbox'
class TkScrollbox<TkListbox class TkScrollbox<Tk::Listbox
include TkComposite include TkComposite
def initialize_composite(keys=nil) def initialize_composite(keys=nil)
#list = Tk::Listbox.new(@frame)
# -> use current TkListbox class
list = TkListbox.new(@frame) list = TkListbox.new(@frame)
#scroll = Tk::Scrollbar.new(@frame)
# -> use current TkScrollbar class
scroll = TkScrollbar.new(@frame) scroll = TkScrollbar.new(@frame)
@path = list.path @path = list.path

View file

@ -1,12 +1,11 @@
# #
# tk/spinbox.rb - Tk spinbox classes # tk/spinbox.rb - Tk spinbox classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp> # by Yukihiro Matsumoto <matz@caelum.co.jp>
# #
require 'tk' require 'tk'
require 'tk/entry' require 'tk/entry'
class TkSpinbox<TkEntry class Tk::Spinbox<Tk::Entry
TkCommandNames = ['spinbox'.freeze].freeze TkCommandNames = ['spinbox'.freeze].freeze
WidgetClassName = 'Spinbox'.freeze WidgetClassName = 'Spinbox'.freeze
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
@ -38,6 +37,22 @@ class TkSpinbox<TkEntry
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL); _setup_subst_table(KEY_TBL, PROC_TBL);
def self.ret_val(val) def self.ret_val(val)
@ -97,3 +112,6 @@ class TkSpinbox<TkEntry
_fromUTF8(tk_send_without_enc('set', _get_eval_enc_str(str))) _fromUTF8(tk_send_without_enc('set', _get_eval_enc_str(str)))
end end
end end
#TkSpinbox = Tk::Spinbox unless Object.const_defined? :TkSpinbox
Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)

View file

@ -1,6 +1,5 @@
# #
# tk/text.rb - Tk text classes # tk/text.rb - Tk text classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp> # by Yukihiro Matsumoto <matz@caelum.co.jp>
require 'tk' require 'tk'
require 'tk/itemfont' require 'tk/itemfont'
@ -60,7 +59,7 @@ module TkTextTagConfig
private :itemconfiginfo, :current_itemconfiginfo private :itemconfiginfo, :current_itemconfiginfo
end end
class TkText<TkTextWin class Tk::Text<TkTextWin
ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze
#include TkTreatTextTagFont #include TkTreatTextTagFont
include TkTextTagConfig include TkTextTagConfig
@ -74,9 +73,9 @@ class TkText<TkTextWin
mod = mod.to_s mod = mod.to_s
if mod =~ /^\s*[+-]?\d/ if mod =~ /^\s*[+-]?\d/
TkText::IndexString.new(String.new(id) << ' + ' << mod) Tk::Text::IndexString.new(String.new(id) << ' + ' << mod)
else else
TkText::IndexString.new(String.new(id) << ' ' << mod) Tk::Text::IndexString.new(String.new(id) << ' ' << mod)
end end
end end
@ -85,20 +84,20 @@ class TkText<TkTextWin
mod = mod.to_s mod = mod.to_s
if mod =~ /^\s*[+-]?\d/ if mod =~ /^\s*[+-]?\d/
TkText::IndexString.new(String.new(id) << ' - ' << mod) Tk::Text::IndexString.new(String.new(id) << ' - ' << mod)
elsif mod =~ /^\s*[-]\s+(\d.*)$/ elsif mod =~ /^\s*[-]\s+(\d.*)$/
TkText::IndexString.new(String.new(id) << ' - -' << $1) Tk::Text::IndexString.new(String.new(id) << ' - -' << $1)
else else
TkText::IndexString.new(String.new(id) << ' ' << mod) Tk::Text::IndexString.new(String.new(id) << ' ' << mod)
end end
end end
def chars(mod) def chars(mod)
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' chars') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' chars')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' chars') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' chars')
end end
end end
alias char chars alias char chars
@ -107,9 +106,9 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display chars') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display chars')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display chars') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display chars')
end end
end end
alias display_char display_chars alias display_char display_chars
@ -118,9 +117,9 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any chars') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any chars')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any chars') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any chars')
end end
end end
alias any_char any_chars alias any_char any_chars
@ -129,9 +128,9 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' indices') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' indices')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' indices') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' indices')
end end
end end
@ -139,9 +138,9 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display indices') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display indices')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display indices') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display indices')
end end
end end
@ -149,18 +148,18 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any indices') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any indices')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any indices') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any indices')
end end
end end
def lines(mod) def lines(mod)
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' lines') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' lines')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' lines') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' lines')
end end
end end
alias line lines alias line lines
@ -169,9 +168,9 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display_lines') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display_lines')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display lines') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display lines')
end end
end end
alias display_line display_lines alias display_line display_lines
@ -180,43 +179,43 @@ class TkText<TkTextWin
# Tk8.5 feature # Tk8.5 feature
fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer)
if mod < 0 if mod < 0
TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any_lines') Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any_lines')
else else
TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any lines') Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any lines')
end end
end end
alias any_line any_lines alias any_line any_lines
def linestart def linestart
TkText::IndexString.new(String.new(id) << ' linestart') Tk::Text::IndexString.new(String.new(id) << ' linestart')
end end
def lineend def lineend
TkText::IndexString.new(String.new(id) << ' lineend') Tk::Text::IndexString.new(String.new(id) << ' lineend')
end end
def display_linestart def display_linestart
# Tk8.5 feature # Tk8.5 feature
TkText::IndexString.new(String.new(id) << ' display linestart') Tk::Text::IndexString.new(String.new(id) << ' display linestart')
end end
def display_lineend def display_lineend
# Tk8.5 feature # Tk8.5 feature
TkText::IndexString.new(String.new(id) << ' display lineend') Tk::Text::IndexString.new(String.new(id) << ' display lineend')
end end
def wordstart def wordstart
TkText::IndexString.new(String.new(id) << ' wordstart') Tk::Text::IndexString.new(String.new(id) << ' wordstart')
end end
def wordend def wordend
TkText::IndexString.new(String.new(id) << ' wordend') Tk::Text::IndexString.new(String.new(id) << ' wordend')
end end
def display_wordstart def display_wordstart
# Tk8.5 feature # Tk8.5 feature
TkText::IndexString.new(String.new(id) << ' display wordstart') Tk::Text::IndexString.new(String.new(id) << ' display wordstart')
end end
def display_wordend def display_wordend
# Tk8.5 feature # Tk8.5 feature
TkText::IndexString.new(String.new(id) << ' display wordend') Tk::Text::IndexString.new(String.new(id) << ' display wordend')
end end
end end
@ -251,7 +250,11 @@ class TkText<TkTextWin
def self.new(*args, &block) def self.new(*args, &block)
obj = super(*args){} obj = super(*args){}
obj.init_instance_variable obj.init_instance_variable
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
obj.instance_exec(obj, &block) if defined? yield
else
obj.instance_eval(&block) if defined? yield obj.instance_eval(&block) if defined? yield
end
obj obj
end end
@ -261,8 +264,12 @@ class TkText<TkTextWin
end end
def __destroy_hook__ def __destroy_hook__
TkTextTag::TTagID_TBL.mutex.synchronize{
TkTextTag::TTagID_TBL.delete(@path) TkTextTag::TTagID_TBL.delete(@path)
}
TkTextTag::TMarkID_TBL.mutex.synchronize{
TkTextMark::TMarkID_TBL.delete(@path) TkTextMark::TMarkID_TBL.delete(@path)
}
end end
def create_self(keys) def create_self(keys)
@ -285,15 +292,15 @@ class TkText<TkTextWin
private :__strval_optkeys private :__strval_optkeys
def self.at(x, y) def self.at(x, y)
TkText::IndexString.at(x, y) Tk::Text::IndexString.at(x, y)
end end
def at(x, y) def at(x, y)
TkText::IndexString.at(x, y) Tk::Text::IndexString.at(x, y)
end end
def index(idx) def index(idx)
TkText::IndexString.new(tk_send_without_enc('index', Tk::Text::IndexString.new(tk_send_without_enc('index',
_get_eval_enc_str(idx))) _get_eval_enc_str(idx)))
end end
@ -713,6 +720,7 @@ class TkText<TkTextWin
def tag_delete(*tags) def tag_delete(*tags)
tk_send_without_enc('tag', 'delete', tk_send_without_enc('tag', 'delete',
*(tags.collect{|tag| _get_eval_enc_str(tag)})) *(tags.collect{|tag| _get_eval_enc_str(tag)}))
TkTextTag::TTagID_TBL.mutex.synchronize{
if TkTextTag::TTagID_TBL[@path] if TkTextTag::TTagID_TBL[@path]
tags.each{|tag| tags.each{|tag|
if tag.kind_of?(TkTextTag) if tag.kind_of?(TkTextTag)
@ -722,6 +730,7 @@ class TkText<TkTextWin
end end
} }
end end
}
self self
end end
alias deltag tag_delete alias deltag tag_delete
@ -968,7 +977,7 @@ class TkText<TkTextWin
false, true) false, true)
r = [] r = []
while key=l.shift while key=l.shift
r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] r.push [Tk::Text::IndexString.new(key), Tk::Text::IndexString.new(l.shift)]
end end
r r
end end
@ -978,7 +987,7 @@ class TkText<TkTextWin
_get_eval_enc_str(tag), _get_eval_enc_str(tag),
_get_eval_enc_str(first), _get_eval_enc_str(first),
_get_eval_enc_str(last))).collect{|idx| _get_eval_enc_str(last))).collect{|idx|
TkText::IndexString.new(idx) Tk::Text::IndexString.new(idx)
} }
end end
@ -987,7 +996,7 @@ class TkText<TkTextWin
_get_eval_enc_str(tag), _get_eval_enc_str(tag),
_get_eval_enc_str(first), _get_eval_enc_str(first),
_get_eval_enc_str(last))).collect{|idx| _get_eval_enc_str(last))).collect{|idx|
TkText::IndexString.new(idx) Tk::Text::IndexString.new(idx)
} }
end end
@ -1183,6 +1192,11 @@ class TkText<TkTextWin
end end
def _ktext_length(txt) def _ktext_length(txt)
if TkCore::WITH_ENCODING ### Ruby 1.9 !!!!!!!!!!!!!
return txt.length
end
###########################
if $KCODE !~ /n/i if $KCODE !~ /n/i
return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length
end end
@ -1232,7 +1246,7 @@ class TkText<TkTextWin
if ret == "" if ret == ""
nil nil
else else
TkText::IndexString.new(ret) Tk::Text::IndexString.new(ret)
end end
end end
@ -1267,7 +1281,7 @@ class TkText<TkTextWin
if ret == "" if ret == ""
nil nil
else else
TkText::IndexString.new(ret) Tk::Text::IndexString.new(ret)
end end
end end
@ -1456,10 +1470,10 @@ class TkText<TkTextWin
# retrieve index # retrieve index
idx = str.index(/ /, i) idx = str.index(/ /, i)
if idx if idx
result.push(TkText::IndexString.new(str[i..(idx-1)])) result.push(Tk::Text::IndexString.new(str[i..(idx-1)]))
i = idx + 1 i = idx + 1
else else
result.push(TkText::IndexString.new(str[i..-1])) result.push(Tk::Text::IndexString.new(str[i..-1]))
break break
end end
end end
@ -1527,13 +1541,17 @@ class TkText<TkTextWin
end end
end end
#TkText = Tk::Text unless Object.const_defined? :TkText
Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)
####################################### #######################################
class TkText::Peer < TkText class Tk::Text::Peer < Tk::Text
# Tk8.5 feature # Tk8.5 feature
def initialize(text, parent=nil, keys={}) def initialize(text, parent=nil, keys={})
unless text.kind_of?(TkText) unless text.kind_of?(Tk::Text)
fail ArgumentError, "TkText is expected for 1st argument" fail ArgumentError, "Tk::Text is expected for 1st argument"
end end
@src_text = text @src_text = text
super(parent, keys) super(parent, keys)

View file

@ -5,11 +5,11 @@ require 'tk'
require 'tk/text' require 'tk/text'
class TkTextImage<TkObject class TkTextImage<TkObject
include TkText::IndexModMethods include Tk::Text::IndexModMethods
def initialize(parent, index, keys) def initialize(parent, index, keys)
#unless parent.kind_of?(TkText) #unless parent.kind_of?(Tk::Text)
# fail ArgumentError, "expect TkText for 1st argument" # fail ArgumentError, "expect Tk::Text for 1st argument"
#end #end
@t = parent @t = parent
if index == 'end' || index == :end if index == 'end' || index == :end
@ -34,7 +34,7 @@ class TkTextImage<TkObject
end end
def id def id
TkText::IndexString.new(@id) Tk::Text::IndexString.new(@id)
end end
def mark def mark
@path @path
@ -80,3 +80,5 @@ class TkTextImage<TkObject
value value
end end
end end
TktImage = TkTextImage

View file

@ -5,38 +5,54 @@ require 'tk'
require 'tk/text' require 'tk/text'
class TkTextMark<TkObject class TkTextMark<TkObject
include TkText::IndexModMethods include Tk::Text::IndexModMethods
TMarkID_TBL = TkCore::INTERP.create_table TMarkID_TBL = TkCore::INTERP.create_table
Tk_TextMark_ID = ['mark'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TMarkID_TBL.clear } (Tk_TextMark_ID = ['mark'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
TMarkID_TBL.mutex.synchronize{ TMarkID_TBL.clear }
}
def TkTextMark.id2obj(text, id) def TkTextMark.id2obj(text, id)
tpath = text.path tpath = text.path
return id unless TMarkID_TBL[tpath] TMarkID_TBL.mutex.synchronize{
if TMarkID_TBL[tpath]
TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id
else
id
end
}
end end
def initialize(parent, index) def initialize(parent, index)
#unless parent.kind_of?(TkText) #unless parent.kind_of?(Tk::Text)
# fail ArgumentError, "expect TkText for 1st argument" # fail ArgumentError, "expect Tk::Text for 1st argument"
#end #end
@parent = @t = parent @parent = @t = parent
@tpath = parent.path @tpath = parent.path
Tk_TextMark_ID.mutex.synchronize{
# @path = @id = Tk_TextMark_ID.join('') # @path = @id = Tk_TextMark_ID.join('')
@path = @id = Tk_TextMark_ID.join(TkCore::INTERP._ip_id_).freeze @path = @id = Tk_TextMark_ID.join(TkCore::INTERP._ip_id_).freeze
Tk_TextMark_ID[1].succ!
}
TMarkID_TBL.mutex.synchronize{
TMarkID_TBL[@id] = self TMarkID_TBL[@id] = self
TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath] TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]
TMarkID_TBL[@tpath][@id] = self TMarkID_TBL[@tpath][@id] = self
Tk_TextMark_ID[1].succ! }
tk_call_without_enc(@t.path, 'mark', 'set', @id, tk_call_without_enc(@t.path, 'mark', 'set', @id,
_get_eval_enc_str(index)) _get_eval_enc_str(index))
@t._addtag id, self @t._addtag id, self
end end
def id def id
TkText::IndexString.new(@id) Tk::Text::IndexString.new(@id)
end end
def exist? def exist?
@ -49,15 +65,15 @@ class TkTextMark<TkObject
end end
=begin =begin
# move to TkText::IndexModMethods module # move to Tk::Text::IndexModMethods module
def +(mod) def +(mod)
return chars(mod) if mod.kind_of?(Numeric) return chars(mod) if mod.kind_of?(Numeric)
mod = mod.to_s mod = mod.to_s
if mod =~ /^\s*[+-]?\d/ if mod =~ /^\s*[+-]?\d/
TkText::IndexString.new(@id + ' + ' + mod) Tk::Text::IndexString.new(@id + ' + ' + mod)
else else
TkText::IndexString.new(@id + ' ' + mod) Tk::Text::IndexString.new(@id + ' ' + mod)
end end
end end
@ -66,11 +82,11 @@ class TkTextMark<TkObject
mod = mod.to_s mod = mod.to_s
if mod =~ /^\s*[+-]?\d/ if mod =~ /^\s*[+-]?\d/
TkText::IndexString.new(@id + ' - ' + mod) Tk::Text::IndexString.new(@id + ' - ' + mod)
elsif mod =~ /^\s*[-]\s+(\d.*)$/ elsif mod =~ /^\s*[-]\s+(\d.*)$/
TkText::IndexString.new(@id + ' - -' + $1) Tk::Text::IndexString.new(@id + ' - -' + $1)
else else
TkText::IndexString.new(@id + ' ' + mod) Tk::Text::IndexString.new(@id + ' ' + mod)
end end
end end
=end =end
@ -121,46 +137,68 @@ class TkTextMark<TkObject
end end
end end
end end
TktMark = TkTextMark
class TkTextNamedMark<TkTextMark class TkTextNamedMark<TkTextMark
def self.new(parent, name, *args) def self.new(parent, name, index=nil)
TMarkID_TBL.mutex.synchronize{
if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name] if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name]
return TMarkID_TBL[parent.path][name] obj = TMarkID_TBL[parent.path][name]
else else
super(parent, name, *args) # super(parent, name, *args)
end (obj = self.allocate).instance_eval{
end
def initialize(parent, name, index=nil)
#unless parent.kind_of?(TkText)
# fail ArgumentError, "expect TkText for 1st argument"
#end
@parent = @t = parent @parent = @t = parent
@tpath = parent.path @tpath = parent.path
@path = @id = name @path = @id = name
TMarkID_TBL[@id] = self TMarkID_TBL[@id] = self
TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath] TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]
TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id] TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id]
@t._addtag @id, self
}
obj
end
if obj && index
tk_call_without_enc(parent.path, 'mark', 'set', name,
_get_eval_enc_str(index))
end
obj
}
end
def initialize(parent, name, index=nil)
# dummy:: not called by 'new' method
#unless parent.kind_of?(Tk::Text)
# fail ArgumentError, "expect Tk::Text for 1st argument"
#end
@parent = @t = parent
@tpath = parent.path
@path = @id = name
tk_call_without_enc(@t.path, 'mark', 'set', @id, tk_call_without_enc(@t.path, 'mark', 'set', @id,
_get_eval_enc_str(index)) if index _get_eval_enc_str(index)) if index
@t._addtag id, self @t._addtag @id, self
end end
end end
TktNamedMark = TkTextNamedMark
class TkTextMarkInsert<TkTextNamedMark class TkTextMarkInsert<TkTextNamedMark
def self.new(parent,*args) def self.new(parent,*args)
super(parent, 'insert', *args) super(parent, 'insert', *args)
end end
end end
TktMarkInsert = TkTextMarkInsert
class TkTextMarkCurrent<TkTextNamedMark class TkTextMarkCurrent<TkTextNamedMark
def self.new(parent,*args) def self.new(parent,*args)
super(parent, 'current', *args) super(parent, 'current', *args)
end end
end end
TktMarkCurrent = TkTextMarkCurrent
class TkTextMarkAnchor<TkTextNamedMark class TkTextMarkAnchor<TkTextNamedMark
def self.new(parent,*args) def self.new(parent,*args)
super(parent, 'anchor', *args) super(parent, 'anchor', *args)
end end
end end
TktMarkAnchor = TkTextMarkAnchor

View file

@ -7,17 +7,29 @@ require 'tk/tagfont'
class TkTextTag<TkObject class TkTextTag<TkObject
include TkTreatTagFont include TkTreatTagFont
include TkText::IndexModMethods include Tk::Text::IndexModMethods
TTagID_TBL = TkCore::INTERP.create_table TTagID_TBL = TkCore::INTERP.create_table
Tk_TextTag_ID = ['tag'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TTagID_TBL.clear } (Tk_TextTag_ID = ['tag'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
TTagID_TBL.mutex.synchronize{ TTagID_TBL.clear }
}
def TkTextTag.id2obj(text, id) def TkTextTag.id2obj(text, id)
tpath = text.path tpath = text.path
return id unless TTagID_TBL[tpath] TTagID_TBL.mutex.synchronize{
if TTagID_TBL[tpath]
TTagID_TBL[tpath][id]? TTagID_TBL[tpath][id]: id TTagID_TBL[tpath][id]? TTagID_TBL[tpath][id]: id
else
id
end
}
end end
def initialize(parent, *args) def initialize(parent, *args)
@ -26,12 +38,16 @@ class TkTextTag<TkObject
#end #end
@parent = @t = parent @parent = @t = parent
@tpath = parent.path @tpath = parent.path
Tk_TextTag_ID.mutex.synchronize{
# @path = @id = Tk_TextTag_ID.join('') # @path = @id = Tk_TextTag_ID.join('')
@path = @id = Tk_TextTag_ID.join(TkCore::INTERP._ip_id_).freeze @path = @id = Tk_TextTag_ID.join(TkCore::INTERP._ip_id_).freeze
# TTagID_TBL[@id] = self Tk_TextTag_ID[1].succ!
}
TTagID_TBL.mutex.synchronize{
TTagID_TBL[@id] = self
TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath] TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]
TTagID_TBL[@tpath][@id] = self TTagID_TBL[@tpath][@id] = self
Tk_TextTag_ID[1].succ! }
#tk_call @t.path, "tag", "configure", @id, *hash_kv(keys) #tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
if args != [] if args != []
keys = args.pop keys = args.pop
@ -47,7 +63,7 @@ class TkTextTag<TkObject
end end
def id def id
TkText::IndexString.new(@id) Tk::Text::IndexString.new(@id)
end end
def exist? def exist?
@ -60,11 +76,11 @@ class TkTextTag<TkObject
end end
def first def first
TkText::IndexString.new(@id + '.first') Tk::Text::IndexString.new(@id + '.first')
end end
def last def last
TkText::IndexString.new(@id + '.last') Tk::Text::IndexString.new(@id + '.last')
end end
def add(*indices) def add(*indices)
@ -83,7 +99,7 @@ class TkTextTag<TkObject
l = tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'ranges', @id)) l = tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'ranges', @id))
r = [] r = []
while key=l.shift while key=l.shift
r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] r.push [Tk::Text::IndexString.new(key), Tk::Text::IndexString.new(l.shift)]
end end
r r
end end
@ -92,7 +108,7 @@ class TkTextTag<TkObject
simplelist(tk_call_without_enc(@t.path, 'tag', 'nextrange', @id, simplelist(tk_call_without_enc(@t.path, 'tag', 'nextrange', @id,
_get_eval_enc_str(first), _get_eval_enc_str(first),
_get_eval_enc_str(last))).collect{|idx| _get_eval_enc_str(last))).collect{|idx|
TkText::IndexString.new(idx) Tk::Text::IndexString.new(idx)
} }
end end
@ -100,7 +116,7 @@ class TkTextTag<TkObject
simplelist(tk_call_without_enc(@t.path, 'tag', 'prevrange', @id, simplelist(tk_call_without_enc(@t.path, 'tag', 'prevrange', @id,
_get_eval_enc_str(first), _get_eval_enc_str(first),
_get_eval_enc_str(last))).collect{|idx| _get_eval_enc_str(last))).collect{|idx|
TkText::IndexString.new(idx) Tk::Text::IndexString.new(idx)
} }
end end
@ -221,15 +237,34 @@ class TkTextTag<TkObject
def destroy def destroy
tk_call_without_enc(@t.path, 'tag', 'delete', @id) tk_call_without_enc(@t.path, 'tag', 'delete', @id)
TTagID_TBL.mutex.synchronize{
TTagID_TBL[@tpath].delete(@id) if TTagID_TBL[@tpath] TTagID_TBL[@tpath].delete(@id) if TTagID_TBL[@tpath]
}
self self
end end
end end
TktTag = TkTextTag
class TkTextNamedTag<TkTextTag class TkTextNamedTag<TkTextTag
def self.new(parent, name, *args) def self.new(parent, name, *args)
tagobj = nil
TTagID_TBL.mutex.synchronize{
if TTagID_TBL[parent.path] && TTagID_TBL[parent.path][name] if TTagID_TBL[parent.path] && TTagID_TBL[parent.path][name]
tagobj = TTagID_TBL[parent.path][name] tagobj = TTagID_TBL[parent.path][name]
else
# super(parent, name, *args)
(tagobj = self.allocate).instance_eval{
@parent = @t = parent
@tpath = parent.path
@path = @id = name
TTagID_TBL[@id] = self
TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]
TTagID_TBL[@tpath][@id] = self unless TTagID_TBL[@tpath][@id]
@t._addtag @id, self
}
end
}
if args != [] if args != []
keys = args.pop keys = args.pop
if keys.kind_of?(Hash) if keys.kind_of?(Hash)
@ -240,21 +275,20 @@ class TkTextNamedTag<TkTextTag
tagobj.add(*args) tagobj.add(*args)
end end
end end
return tagobj
else tagobj
super(parent, name, *args)
end
end end
def initialize(parent, name, *args) def initialize(parent, name, *args)
#unless parent.kind_of?(TkText) # dummy:: not called by 'new' method
# fail ArgumentError, "expect TkText for 1st argument"
#unless parent.kind_of?(Tk::Text)
# fail ArgumentError, "expect Tk::Text for 1st argument"
#end #end
@parent = @t = parent @parent = @t = parent
@tpath = parent.path @tpath = parent.path
@path = @id = name @path = @id = name
TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]
TTagID_TBL[@tpath][@id] = self unless TTagID_TBL[@tpath][@id]
#if mode #if mode
# tk_call @t.path, "addtag", @id, *args # tk_call @t.path, "addtag", @id, *args
#end #end
@ -268,12 +302,14 @@ class TkTextNamedTag<TkTextTag
add(*args) add(*args)
end end
end end
@t._addtag id, self @t._addtag @id, self
end end
end end
TktNamedTag = TkTextNamedTag
class TkTextTagSel<TkTextNamedTag class TkTextTagSel<TkTextNamedTag
def self.new(parent, *args) def self.new(parent, *args)
super(parent, 'sel', *args) super(parent, 'sel', *args)
end end
end end
TktTagSel = TkTextTagSel

View file

@ -5,11 +5,11 @@ require 'tk'
require 'tk/text' require 'tk/text'
class TkTextWindow<TkObject class TkTextWindow<TkObject
include TkText::IndexModMethods include Tk::Text::IndexModMethods
def initialize(parent, index, keys = {}) def initialize(parent, index, keys = {})
#unless parent.kind_of?(TkText) #unless parent.kind_of?(Tk::Text)
# fail ArgumentError, "expect TkText for 1st argument" # fail ArgumentError, "expect Tk::Text for 1st argument"
#end #end
@t = parent @t = parent
if index == 'end' || index == :end if index == 'end' || index == :end
@ -55,7 +55,7 @@ class TkTextWindow<TkObject
end end
def id def id
TkText::IndexString.new(_epath(@id)) Tk::Text::IndexString.new(_epath(@id))
end end
def mark def mark
@path @path
@ -147,3 +147,5 @@ class TkTextWindow<TkObject
value value
end end
end end
TktWindow = TkTextWindow

View file

@ -11,7 +11,12 @@ class TkTimer
TkCommandNames = ['after'.freeze].freeze TkCommandNames = ['after'.freeze].freeze
Tk_CBID = ['a'.freeze, '00000'.taint].freeze (Tk_CBID = ['a'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
Tk_CBTBL = {}.taint Tk_CBTBL = {}.taint
TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL') TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')
@ -96,9 +101,9 @@ class TkTimer
return self return self
end end
@after_script = "rb_after #{@id}" @after_script = "rb_after #{@id}"
@after_id = tk_call_without_enc('after', sleep, @after_script)
@current_args = args @current_args = args
@current_script = [sleep, @after_script] @current_script = [sleep, @after_script]
@after_id = tk_call_without_enc('after', sleep, @after_script)
self self
end end
@ -138,9 +143,11 @@ class TkTimer
end end
def initialize(*args, &b) def initialize(*args, &b)
Tk_CBID.mutex.synchronize{
# @id = Tk_CBID.join('') # @id = Tk_CBID.join('')
@id = Tk_CBID.join(TkCore::INTERP._ip_id_) @id = Tk_CBID.join(TkCore::INTERP._ip_id_)
Tk_CBID[1].succ! Tk_CBID[1].succ!
}
@wait_var = TkVariable.new(0) @wait_var = TkVariable.new(0)

View file

@ -5,7 +5,7 @@ require 'tk'
require 'tk/wm' require 'tk/wm'
require 'tk/menuspec' require 'tk/menuspec'
class TkToplevel<TkWindow class Tk::Toplevel<TkWindow
include Wm include Wm
include TkMenuSpec include TkMenuSpec
@ -117,9 +117,10 @@ class TkToplevel<TkWindow
end end
if @classname.kind_of? TkBindTag if @classname.kind_of? TkBindTag
@db_class = @classname @db_class = @classname
@classname = @classname.id keys['class'] = @classname = @classname.id
elsif @classname elsif @classname
@db_class = TkDatabaseClass.new(@classname) @db_class = TkDatabaseClass.new(@classname)
keys['class'] = @classname
else else
@db_class = self.class @db_class = self.class
@classname = @db_class::WidgetClassName @classname = @db_class::WidgetClassName
@ -165,9 +166,10 @@ class TkToplevel<TkWindow
end end
if @classname.kind_of? TkBindTag if @classname.kind_of? TkBindTag
@db_class = @classname @db_class = @classname
@classname = @classname.id keys['class'] = @classname = @classname.id
elsif @classname elsif @classname
@db_class = TkDatabaseClass.new(@classname) @db_class = TkDatabaseClass.new(@classname)
keys['class'] = @classname
else else
@db_class = self.class @db_class = self.class
@classname = @db_class::WidgetClassName @classname = @db_class::WidgetClassName
@ -255,3 +257,6 @@ class TkToplevel<TkWindow
end end
end end
end end
#TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel
Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)

View file

@ -249,6 +249,22 @@ class TkValidateCommand
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL); _setup_subst_table(KEY_TBL, PROC_TBL);
# #

View file

@ -16,7 +16,18 @@ class TkVariable
#TkVar_ID_TBL = {} #TkVar_ID_TBL = {}
TkVar_CB_TBL = TkCore::INTERP.create_table TkVar_CB_TBL = TkCore::INTERP.create_table
TkVar_ID_TBL = TkCore::INTERP.create_table TkVar_ID_TBL = TkCore::INTERP.create_table
Tk_VARIABLE_ID = ["v".freeze, "00000".taint].freeze (Tk_VARIABLE_ID = ["v".freeze, "00000".taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
TkVar_CB_TBL.mutex.synchronize{ TkVar_CB_TBL.clear }
TkVar_ID_TBL.mutex.synchronize{ TkVar_ID_TBL.clear }
}
major, minor, type, type_name, patchlevel = TclTkLib.get_version
USE_OLD_TRACE_OPTION_STYLE = (major < 8) || (major == 8 && minor < 4)
#TkCore::INTERP.add_tk_procs('rb_var', 'args', #TkCore::INTERP.add_tk_procs('rb_var', 'args',
# "ruby [format \"TkVariable.callback %%Q!%s!\" $args]") # "ruby [format \"TkVariable.callback %%Q!%s!\" $args]")
@ -44,10 +55,10 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL')
def TkVariable.callback(id, name1, name2, op) def TkVariable.callback(id, name1, name2, op)
#name1,name2,op = tk_split_list(args) #name1,name2,op = tk_split_list(args)
#name1,name2,op = tk_split_simplelist(args) #name1,name2,op = tk_split_simplelist(args)
if TkVar_CB_TBL[id] if cb_obj = TkVar_CB_TBL[id]
#_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) #_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op))
begin begin
_get_eval_string(TkVar_CB_TBL[id].trace_callback(name2, op)) _get_eval_string(cb_obj.trace_callback(name2, op))
rescue SystemExit rescue SystemExit
exit(0) exit(0)
rescue Interrupt rescue Interrupt
@ -59,7 +70,11 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL')
"\n---< backtrace of Ruby side >-----\n" + "\n---< backtrace of Ruby side >-----\n" +
_toUTF8(e.backtrace.join("\n")) + _toUTF8(e.backtrace.join("\n")) +
"\n---< backtrace of Tk side >-------" "\n---< backtrace of Tk side >-------"
if TkCore::WITH_ENCODING
msg.force_encoding('utf-8')
else
msg.instance_variable_set(:@encoding, 'utf-8') msg.instance_variable_set(:@encoding, 'utf-8')
end
rescue Exception rescue Exception
msg = e.class.inspect + ': ' + e.message + "\n" + msg = e.class.inspect + ': ' + e.message + "\n" +
"\n---< backtrace of Ruby side >-----\n" + "\n---< backtrace of Ruby side >-----\n" +
@ -267,11 +282,15 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL')
def initialize(val="", type=nil) def initialize(val="", type=nil)
# @id = Tk_VARIABLE_ID.join('') # @id = Tk_VARIABLE_ID.join('')
begin begin
Tk_VARIABLE_ID.mutex.synchronize{
@id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_) @id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_)
Tk_VARIABLE_ID[1].succ! Tk_VARIABLE_ID[1].succ!
}
end until INTERP._invoke_without_enc('info', 'globals', @id).empty? end until INTERP._invoke_without_enc('info', 'globals', @id).empty?
TkVar_ID_TBL.mutex.synchronize{
TkVar_ID_TBL[@id] = self TkVar_ID_TBL[@id] = self
}
@var = @id @var = @id
@elem = nil @elem = nil
@ -1263,56 +1282,101 @@ end
end end
end end
def _check_trace_opt(opts)
if opts.kind_of?(Array)
opt_str = opts.map{|s| s.to_s}.join(' ')
else
opt_str = opts.to_s
end
fail ArgumentError, 'null trace option' if opt_str.empty?
if opt_str =~ /[^arwu\s]/
# new format (Tcl/Tk8.4+?)
if opts.kind_of?(Array)
opt_ary = opts.map{|opt| opt.to_s.strip}
else
opt_ary = opt_str.split(/\s+|\|/)
opt_ary.delete('')
end
if USE_OLD_TRACE_OPTION_STYLE
opt_ary.uniq.map{|opt|
case opt
when 'array'
'a'
when 'read'
'r'
when 'write'
'w'
when 'unset'
'u'
else
fail ArgumentError, "unsupported trace option '#{opt}' on Tcl/Tk#{Tk::TCL_PATCHLEVEL}"
end
}.join
else
opt_ary
end
else
# old format
opt_ary = opt_str.delete('^arwu').split(//).uniq
if USE_OLD_TRACE_OPTION_STYLE
opt_ary.join
else
opt_ary.map{|c|
case c
when 'a'
'array'
when 'r'
'read'
when 'w'
'write'
when 'u'
'unset'
end
}
end
end
end
private :_check_trace_opt
def trace(opts, cmd = Proc.new) def trace(opts, cmd = Proc.new)
@trace_var = [] if @trace_var == nil opts = _check_trace_opt(opts)
#opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') (@trace_var ||= []).unshift([opts,cmd])
opts = opts.to_s
opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('')
@trace_var.unshift([opts,cmd])
if @trace_opts == nil if @trace_opts == nil
TkVar_CB_TBL[@id] = self TkVar_CB_TBL[@id] = self
@trace_opts = opts.dup @trace_opts = opts
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, if USE_OLD_TRACE_OPTION_STYLE
'rb_var ' << @id) Tk.tk_call_without_enc('trace', 'variable',
=begin @id, @trace_opts, 'rb_var ' << @id)
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var')
else else
# TCL_VERSION <= 8.3 Tk.tk_call_without_enc('trace', 'add', 'variable',
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end end
=end
else else
newopts = @trace_opts.dup newopts = @trace_opts.dup
#opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} if USE_OLD_TRACE_OPTION_STYLE
opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
if newopts != @trace_opts if newopts != @trace_opts
Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts,
'rb_var ' << @id)
@trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts,
'rb_var ' << @id)
=begin
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var')
@trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var')
else
# TCL_VERSION <= 8.3
Tk.tk_call_without_enc('trace', 'vdelete', Tk.tk_call_without_enc('trace', 'vdelete',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
@trace_opts.replace(newopts) @trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'variable', Tk.tk_call_without_enc('trace', 'variable',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end end
=end else
newopts |= opts
unless (newopts - @trace_opts).empty?
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
@trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
end end
end end
end
self self
end end
@ -1321,65 +1385,54 @@ end
fail(RuntimeError, fail(RuntimeError,
"invalid for a TkVariable which denotes an element of Tcl's array") "invalid for a TkVariable which denotes an element of Tcl's array")
end end
@trace_elem = {} if @trace_elem == nil
@trace_elem[elem] = [] if @trace_elem[elem] == nil opts = _check_trace_opt(opts)
opts = opts.to_s
opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') ((@trace_elem ||= {})[elem] ||= []).unshift([opts,cmd])
@trace_elem[elem].unshift([opts,cmd])
if @trace_opts == nil if @trace_opts == nil
TkVar_CB_TBL[@id] = self TkVar_CB_TBL[@id] = self
@trace_opts = opts.dup @trace_opts = opts
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, if USE_OLD_TRACE_OPTION_STYLE
'rb_var ' << @id)
=begin
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'add', 'variable', Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
else else
# TCL_VERSION <= 8.3
Tk.tk_call_without_enc('trace', 'variable', Tk.tk_call_without_enc('trace', 'variable',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end end
=end
else else
newopts = @trace_opts.dup newopts = @trace_opts.dup
# opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} if USE_OLD_TRACE_OPTION_STYLE
opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
if newopts != @trace_opts if newopts != @trace_opts
Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts,
'rb_var ' << @id)
@trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts,
'rb_var ' << @id)
=begin
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var')
@trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var')
else
# TCL_VERSION <= 8.3
Tk.tk_call_without_enc('trace', 'vdelete', Tk.tk_call_without_enc('trace', 'vdelete',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
@trace_opts.replace(newopts) @trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'variable', Tk.tk_call_without_enc('trace', 'variable',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end end
=end else
newopts |= opts
unless (newopts - @trace_opts).empty?
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
@trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
end end
end end
end
self self
end end
def trace_vinfo def trace_info
return [] unless @trace_var return [] unless @trace_var
@trace_var.dup @trace_var.dup
end end
alias trace_vinfo trace_info
def _trace_vinfo_for_element(elem) def trace_info_for_element(elem)
if @elem if @elem
fail(RuntimeError, fail(RuntimeError,
"invalid for a TkVariable which denotes an element of Tcl's array") "invalid for a TkVariable which denotes an element of Tcl's array")
@ -1388,141 +1441,180 @@ end
return [] unless @trace_elem[elem] return [] unless @trace_elem[elem]
@trace_elem[elem].dup @trace_elem[elem].dup
end end
alias trace_vinfo_for_element trace_info_for_element
def trace_vdelete(opts,cmd) def trace_remove(opts,cmd)
return self unless @trace_var.kind_of? Array return self unless @trace_var.kind_of? Array
opts = opts.to_s
opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') opts = _check_trace_opt(opts)
idx = -1 idx = -1
if USE_OLD_TRACE_OPTION_STYLE
newopts = '' newopts = ''
@trace_var.each_with_index{|e, i| @trace_var.each_with_index{|e, i|
if idx < 0 && e[0] == opts && e[1] == cmd if idx < 0 && e[1] == cmd
diff = false
['a', 'r', 'w', 'u'].each{|c|
break if (diff = e[0].index(c) ^ opts.index(c))
}
unless diff
#find
idx = i idx = i
next next
end end
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} end
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
} }
else
newopts = []
@trace_var.each_with_index{|e, i|
if idx < 0 && e[1] == cmd &&
e[0].size == opts.size && (e[0] - opts).empty?
# find
idx = i
next
end
newopts |= e[0]
}
end
if idx >= 0 if idx >= 0
@trace_var.delete_at(idx) @trace_var.delete_at(idx)
else else
return self return self
end end
@trace_elem.each{|elem| (@trace_elem ||= {}).each{|elem|
@trace_elem[elem].each{|e| @trace_elem[elem].each{|e|
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} if USE_OLD_TRACE_OPTION_STYLE
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
else
newopts |= e[0]
end
} }
} }
newopts = newopts.to_s if USE_OLD_TRACE_OPTION_STYLE
newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') diff = false
if newopts != @trace_opts @trace_opts.each_byte{|c| break if (diff = ! newopts.index(c))}
Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, if diff
'rb_var ' << @id)
=begin
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var')
else
# TCL_VERSION <= 8.3
Tk.tk_call_without_enc('trace', 'vdelete', Tk.tk_call_without_enc('trace', 'vdelete',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end
=end
@trace_opts.replace(newopts) @trace_opts.replace(newopts)
if @trace_opts != '' unless @trace_opts.empty?
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts,
'rb_var ' << @id)
=begin
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var')
else
# TCL_VERSION <= 8.3
Tk.tk_call_without_enc('trace', 'variable', Tk.tk_call_without_enc('trace', 'variable',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end
end
else
unless (@trace_opts - newopts).empty?
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
@trace_opts.replace(newopts)
unless @trace_opts.empty?
Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
end end
=end
end end
end end
self self
end end
alias trace_delete trace_remove
alias trace_vdelete trace_remove
def trace_vdelete_for_element(elem,opts,cmd) def trace_remove_for_element(elem,opts,cmd)
if @elem if @elem
fail(RuntimeError, fail(RuntimeError,
"invalid for a TkVariable which denotes an element of Tcl's array") "invalid for a TkVariable which denotes an element of Tcl's array")
end end
return self unless @trace_elem.kind_of? Hash return self unless @trace_elem.kind_of? Hash
return self unless @trace_elem[elem].kind_of? Array return self unless @trace_elem[elem].kind_of? Array
opts = opts.to_s
opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') opts = _check_trace_opt(opts)
idx = -1 idx = -1
if USE_OLD_TRACE_OPTION_STYLE
@trace_elem[elem].each_with_index{|e, i| @trace_elem[elem].each_with_index{|e, i|
if idx < 0 && e[0] == opts && e[1] == cmd if idx < 0 && e[1] == cmd
diff = false
['a', 'r', 'w', 'u'].each{|c|
break if (diff = e[0].index(c) ^ opts.index(c))
}
unless diff
#find
idx = i
next
end
end
}
else
@trace_elem[elem].each_with_index{|e, i|
if idx < 0 && e[1] == cmd &&
e[0].size == opts.size && (e[0] - opts).empty?
# find
idx = i idx = i
next next
end end
} }
end
if idx >= 0 if idx >= 0
@trace_elem[elem].delete_at(idx) @trace_elem[elem].delete_at(idx)
else else
return self return self
end end
if USE_OLD_TRACE_OPTION_STYLE
newopts = '' newopts = ''
@trace_var.each{|e| @trace_var.each{|e|
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
} }
@trace_elem.each{|elem| @trace_elem.each{|elem|
@trace_elem[elem].each{|e| @trace_elem[elem].each{|e|
# e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)}
} }
} }
else
newopts = []
@trace_var.each{|e|
newopts |= e[0]
}
@trace_elem.each{|elem|
@trace_elem[elem].each{|e|
e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
}
}
end
newopts = newopts.to_s if USE_OLD_TRACE_OPTION_STYLE
newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') diff = false
if newopts != @trace_opts @trace_opts.each_byte{|c| break if (diff = ! newopts.index(c))}
Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, if diff
'rb_var ' << @id)
=begin
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION
# TCL_VERSION >= 8.4
Tk.tk_call_without_enc('trace', 'remove', 'variable',
@id, @trace_opts, 'rb_var')
else
# TCL_VERSION <= 8.3
Tk.tk_call_without_enc('trace', 'vdelete', Tk.tk_call_without_enc('trace', 'vdelete',
@id, @trace_opts, 'rb_var') @id, @trace_opts, 'rb_var ' << @id)
end
=end
@trace_opts.replace(newopts) @trace_opts.replace(newopts)
if @trace_opts != '' unless @trace_opts.empty?
Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, Tk.tk_call_without_enc('trace', 'variable',
'rb_var ' << @id) @id, @trace_opts, 'rb_var ' << @id)
=begin end
if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION end
# TCL_VERSION >= 8.4 else
Tk.tk_call_without_enc('trace', 'add', 'variable', unless (@trace_opts - newopts).empty?
@id, @trace_opts, 'rb_var') Tk.tk_call_without_enc('trace', 'remove', 'variable',
else @id, @trace_opts, 'rb_var ' << @id)
# TCL_VERSION <= 8.3 @trace_opts.replace(newopts)
Tk.tk_call_without_enc('trace', 'variable', @id, unless @trace_opts.empty?
@trace_opts, 'rb_var') Tk.tk_call_without_enc('trace', 'add', 'variable',
@id, @trace_opts, 'rb_var ' << @id)
end end
=end
end end
end end
self self
end end
alias trace_delete_for_element trace_remove_for_element
alias trace_vdelete_for_element trace_remove_for_element
end end
class TkVarAccess<TkVariable class TkVarAccess<TkVariable
@ -1532,12 +1624,23 @@ class TkVarAccess<TkVariable
return name return name
end end
name = name.to_s
v = nil
TkVar_ID_TBL.mutex.synchronize{
if v = TkVar_ID_TBL[name] if v = TkVar_ID_TBL[name]
v.value = args[0] unless args.empty? v.value = args[0] unless args.empty?
return v return v
else
(v = self.allocate).instance_eval{
@id = name
TkVar_ID_TBL[@id] = self
@var = @id
}
end end
}
super(name, *args) v.instance_eval{ initialize(name, *args) }
v
end end
def self.new_hash(name, *args) def self.new_hash(name, *args)
@ -1549,27 +1652,38 @@ class TkVarAccess<TkVariable
return name return name
end end
name = name.to_s
v = nil
TkVar_ID_TBL.mutex.synchronize{
if v = TkVar_ID_TBL[name] if v = TkVar_ID_TBL[name]
unless v.is_hash? unless v.is_hash?
fail ArgumentError, "already exist as a scalar variable" fail ArgumentError, "already exist as a scalar variable"
end end
v.value = args[0] unless args.empty? v.value = args[0] unless args.empty?
return v return v
else
(v = self.allocate).instance_eval{
@id = name
TkVar_ID_TBL[@id] = self
@var = @id
}
end end
}
INTERP._invoke_without_enc('global', name) INTERP._invoke_without_enc('global', name)
if args.empty? && INTERP._invoke_without_enc('array', 'exist', name) == '0' if args.empty? && INTERP._invoke_without_enc('array', 'exist', name) == '0'
self.new(name, {}) # force creating v.instance_eval{ initialize(name, {}) } # force creating
else else
self.new(name, *args) v.instance_eval{ initialize(name, *args) }
end end
v
end end
def initialize(varname, val=nil) def initialize(varname, val=nil)
@id = varname # @id = varname
TkVar_ID_TBL[@id] = self # TkVar_ID_TBL[@id] = self
@var = @id # @var = @id
@elem = nil @elem = nil
@def_default = false @def_default = false

View file

@ -9,10 +9,17 @@ class TkVirtualEvent<TkObject
TkCommandNames = ['event'.freeze].freeze TkCommandNames = ['event'.freeze].freeze
TkVirtualEventID = ["VirtEvent".freeze, "00000".taint].freeze (TkVirtualEventID = ["VirtEvent".freeze, "00000".taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkVirtualEventTBL = TkCore::INTERP.create_table TkVirtualEventTBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear } TkCore::INTERP.init_ip_env{
TkVirtualEventTBL.mutex.synchronize{ TkVirtualEventTBL.clear }
}
class PreDefVirtEvent<self class PreDefVirtEvent<self
def self.new(event, *sequences) def self.new(event, *sequences)
@ -21,22 +28,30 @@ class TkVirtualEvent<TkObject
elsif event !~ /^<.*>$/ elsif event !~ /^<.*>$/
event = '<' + event + '>' event = '<' + event + '>'
end end
TkVirtualEvent::TkVirtualEventTBL.mutex.synchronize{
if TkVirtualEvent::TkVirtualEventTBL.has_key?(event) if TkVirtualEvent::TkVirtualEventTBL.has_key?(event)
TkVirtualEvent::TkVirtualEventTBL[event] TkVirtualEvent::TkVirtualEventTBL[event]
else else
super(event, *sequences) # super(event, *sequences)
(obj = self.allocate).instance_eval{
initialize(event, *sequences)
TkVirtualEvent::TkVirtualEventTBL[@id] = self
}
end end
}
end end
def initialize(event, *sequences) def initialize(event, *sequences)
@path = @id = event @path = @id = event
TkVirtualEvent::TkVirtualEventTBL[@id] = self _add_sequences(sequences)
add(*sequences)
end end
end end
def TkVirtualEvent.getobj(event) def TkVirtualEvent.getobj(event)
obj = nil
TkVirtualEventTBL.mutex.synchronize{
obj = TkVirtualEventTBL[event] obj = TkVirtualEventTBL[event]
}
if obj if obj
obj obj
else else
@ -55,19 +70,31 @@ class TkVirtualEvent<TkObject
end end
def initialize(*sequences) def initialize(*sequences)
TkVirtualEventID.mutex.synchronize{
# @path = @id = '<' + TkVirtualEventID.join('') + '>' # @path = @id = '<' + TkVirtualEventID.join('') + '>'
@path = @id = '<' + TkVirtualEventID.join(TkCore::INTERP._ip_id_) + '>' @path = @id = '<' + TkVirtualEventID.join(TkCore::INTERP._ip_id_) + '>'
TkVirtualEventID[1].succ! TkVirtualEventID[1].succ!
add(*sequences) }
_add_sequences(sequences)
end end
def _add_sequences(seq_ary)
unless seq_ary.empty?
tk_call_without_enc('event', 'add', "<#{@id}>",
*(seq_ary.collect{|seq|
"<#{tk_event_sequence(seq)}>"
}) )
end
self
end
private :_add_sequences
def add(*sequences) def add(*sequences)
if sequences != [] if sequences != []
tk_call_without_enc('event', 'add', "<#{@id}>", _add_sequences(sequences)
*(sequences.collect{|seq| TkVirtualEventTBL.mutex.synchronize{
"<#{tk_event_sequence(seq)}>"
}) )
TkVirtualEventTBL[@id] = self TkVirtualEventTBL[@id] = self
}
end end
self self
end end
@ -75,20 +102,26 @@ class TkVirtualEvent<TkObject
def delete(*sequences) def delete(*sequences)
if sequences == [] if sequences == []
tk_call_without_enc('event', 'delete', "<#{@id}>") tk_call_without_enc('event', 'delete', "<#{@id}>")
TkVirtualEventTBL.mutex.synchronize{
TkVirtualEventTBL.delete(@id) TkVirtualEventTBL.delete(@id)
}
else else
tk_call_without_enc('event', 'delete', "<#{@id}>", tk_call_without_enc('event', 'delete', "<#{@id}>",
*(sequences.collect{|seq| *(sequences.collect{|seq|
"<#{tk_event_sequence(seq)}>" "<#{tk_event_sequence(seq)}>"
}) ) }) )
TkVirtualEventTBL.delete(@id) if info == [] if tk_call_without_enc('event','info',"<#{@id}>").empty?
TkVirtualEventTBL.mutex.synchronize{
TkVirtualEventTBL.delete(@id)
}
end
end end
self self
end end
def info def info
tk_call_without_enc('event','info',"<#{@id}>").split(/\s+/).collect!{|seq| tk_call_without_enc('event','info',"<#{@id}>").split(/\s+/).collect!{|seq|
l = seq.scan(/<*[^<>]+>*/).collect!{|subseq| lst = seq.scan(/<*[^<>]+>*/).collect!{|subseq|
case (subseq) case (subseq)
when /^<<[^<>]+>>$/ when /^<<[^<>]+>>$/
TkVirtualEvent.getobj(subseq[1..-2]) TkVirtualEvent.getobj(subseq[1..-2])
@ -98,7 +131,7 @@ class TkVirtualEvent<TkObject
subseq.split('') subseq.split('')
end end
}.flatten }.flatten
(l.size == 1) ? l[0] : l (lst.size == 1) ? lst[0] : lst
} }
end end
end end

View file

@ -7,9 +7,14 @@
# #
require 'tk' require 'tk'
module TkWinDDE module Tk::WinDDE
end
#TkWinDDE = Tk::WinDDE
Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)
module Tk::WinDDE
extend Tk extend Tk
extend TkWinDDE extend Tk::WinDDE
TkCommandNames = ['dde'.freeze].freeze TkCommandNames = ['dde'.freeze].freeze
@ -85,9 +90,14 @@ module TkWinDDE
:poke, :request, :services, :eval :poke, :request, :services, :eval
end end
module TkWinRegistry module Tk::WinRegistry
end
#TkWinRegistry = Tk::WinRegistry
Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)
module Tk::WinRegistry
extend Tk extend Tk
extend TkWinRegistry extend Tk::WinRegistry
TkCommandNames = ['registry'.freeze].freeze TkCommandNames = ['registry'.freeze].freeze

View file

@ -5,273 +5,407 @@ require 'tk'
module Tk module Tk
module Wm module Wm
include TkComm #include TkComm
extend TkCore
TkCommandNames = ['wm'.freeze].freeze TkCommandNames = ['wm'.freeze].freeze
TOPLEVEL_METHODCALL_OPTKEYS = {} TOPLEVEL_METHODCALL_OPTKEYS = {}
def aspect(*args) def Wm.aspect(win, *args)
if args.length == 0 if args.length == 0
list(tk_call_without_enc('wm', 'aspect', path)) list(tk_call_without_enc('wm', 'aspect', win.epath))
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call('wm', 'aspect', path, *args) tk_call('wm', 'aspect', win.epath, *args)
self win
end end
end end
def aspect(*args)
Wm.aspect(self, *args)
end
alias wm_aspect aspect
TOPLEVEL_METHODCALL_OPTKEYS['aspect'] = 'aspect' TOPLEVEL_METHODCALL_OPTKEYS['aspect'] = 'aspect'
def attributes(slot=nil,value=None) def Wm.attributes(win, slot=nil,value=TkComm::None)
if slot == nil if slot == nil
lst = tk_split_list(tk_call('wm', 'attributes', path)) lst = tk_split_list(tk_call('wm', 'attributes', win.epath))
info = {} info = {}
while key = lst.shift while key = lst.shift
info[key[1..-1]] = lst.shift info[key[1..-1]] = lst.shift
end end
info info
elsif slot.kind_of? Hash elsif slot.kind_of? Hash
tk_call('wm', 'attributes', path, *hash_kv(slot)) tk_call('wm', 'attributes', win.epath, *hash_kv(slot))
self win
elsif value == None elsif value == TkComm::None
tk_call('wm', 'attributes', path, "-#{slot}") tk_call('wm', 'attributes', win.epath, "-#{slot}")
else else
tk_call('wm', 'attributes', path, "-#{slot}", value) tk_call('wm', 'attributes', win.epath, "-#{slot}", value)
self win
end end
end end
def attributes(slot=nil,value=TkComm::None)
Wm.attributes(self, slot, value)
end
alias wm_attributes attributes
TOPLEVEL_METHODCALL_OPTKEYS['attributes'] = 'attributes' TOPLEVEL_METHODCALL_OPTKEYS['attributes'] = 'attributes'
def client(name=None) def Wm.client(win, name=TkComm::None)
if name == None if name == TkComm::None
tk_call('wm', 'client', path) tk_call('wm', 'client', win.epath)
else else
name = '' if name == nil name = '' if name == nil
tk_call('wm', 'client', path, name) tk_call('wm', 'client', win.epath, name)
self win
end end
end end
def client(name=TkComm::None)
Wm.client(self, name)
end
alias wm_client client
TOPLEVEL_METHODCALL_OPTKEYS['client'] = 'client' TOPLEVEL_METHODCALL_OPTKEYS['client'] = 'client'
def colormapwindows(*args) def Wm.colormapwindows(win, *args)
if args.size == 0 if args.size == 0
list(tk_call_without_enc('wm', 'colormapwindows', path)) list(tk_call_without_enc('wm', 'colormapwindows', win.epath))
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call_without_enc('wm', 'colormapwindows', path, *args) tk_call_without_enc('wm', 'colormapwindows', win.epath, *args)
self win
end end
end end
def colormapwindows(*args)
Wm.colormapwindows(self, *args)
end
alias wm_colormapwindows colormapwindows
TOPLEVEL_METHODCALL_OPTKEYS['colormapwindows'] = 'colormapwindows' TOPLEVEL_METHODCALL_OPTKEYS['colormapwindows'] = 'colormapwindows'
def wm_command(value=nil) def Wm.command(win, value=nil)
if value if value
tk_call('wm', 'command', path, value) tk_call('wm', 'command', epath, value)
self win
else else
#procedure(tk_call('wm', 'command', path)) #procedure(tk_call('wm', 'command', epath))
tk_call('wm', 'command', path) tk_call('wm', 'command', epath)
end end
end end
def wm_command(value=nil)
Wm.command(self, value)
end
TOPLEVEL_METHODCALL_OPTKEYS['wm_command'] = 'wm_command' TOPLEVEL_METHODCALL_OPTKEYS['wm_command'] = 'wm_command'
def deiconify(ex = true) def Wm.deiconify(win, ex = true)
if ex if ex
tk_call_without_enc('wm', 'deiconify', path) tk_call_without_enc('wm', 'deiconify', win.epath)
else else
self.iconify Wm.iconify(win)
end end
self win
end end
def deiconify(ex = true)
Wm.deiconify(self, ex)
end
alias wm_deiconify deiconify
def focusmodel(mode = nil) def Wm.focusmodel(win, mode = nil)
if mode if mode
tk_call_without_enc('wm', 'focusmodel', path, mode) tk_call_without_enc('wm', 'focusmodel', win.epath, mode)
self win
else else
tk_call_without_enc('wm', 'focusmodel', path) tk_call_without_enc('wm', 'focusmodel', win.epath)
end end
end end
def focusmodel(mode = nil)
Wm.focusmodel(self, mode)
end
alias wm_focusmodel focusmodel
TOPLEVEL_METHODCALL_OPTKEYS['focusmodel'] = 'focusmodel' TOPLEVEL_METHODCALL_OPTKEYS['focusmodel'] = 'focusmodel'
def frame def Wm.forget(win)
tk_call_without_enc('wm', 'frame', path) # Tcl/Tk 8.5+
# work with dockable frames
tk_call_without_enc('wm', 'forget', win.epath)
win
end
def wm_forget
Wm.forget(self)
end end
def geometry(geom=nil) def Wm.frame(win)
tk_call_without_enc('wm', 'frame', win.epath)
end
def frame
Wm.frame(self)
end
alias wm_frame frame
def Wm.geometry(win, geom=nil)
if geom if geom
tk_call_without_enc('wm', 'geometry', path, geom) tk_call_without_enc('wm', 'geometry', win.epath, geom)
self win
else else
tk_call_without_enc('wm', 'geometry', path) tk_call_without_enc('wm', 'geometry', win.epath)
end end
end end
def geometry(geom=nil)
Wm.geometry(self, geom)
end
alias wm_geometry geometry
TOPLEVEL_METHODCALL_OPTKEYS['geometry'] = 'geometry' TOPLEVEL_METHODCALL_OPTKEYS['geometry'] = 'geometry'
def wm_grid(*args) def Wm.grid(win, *args)
if args.size == 0 if args.size == 0
list(tk_call_without_enc('wm', 'grid', path)) list(tk_call_without_enc('wm', 'grid', win.epath))
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call_without_enc('wm', 'grid', path, *args) tk_call_without_enc('wm', 'grid', win.epath, *args)
self win
end end
end end
def wm_grid(*args)
Wm.grid(self, *args)
end
TOPLEVEL_METHODCALL_OPTKEYS['wm_grid'] = 'wm_grid' TOPLEVEL_METHODCALL_OPTKEYS['wm_grid'] = 'wm_grid'
def group(leader = nil) def Wm.group(win, leader = nil)
if leader if leader
tk_call('wm', 'group', path, leader) tk_call('wm', 'group', win.epath, leader)
self win
else else
window(tk_call('wm', 'group', path)) window(tk_call('wm', 'group', win.epath))
end end
end end
def group(leader = nil)
Wm.group(self, leader)
end
alias wm_group group
TOPLEVEL_METHODCALL_OPTKEYS['group'] = 'group' TOPLEVEL_METHODCALL_OPTKEYS['group'] = 'group'
def iconbitmap(bmp=nil) def Wm.iconbitmap(win, bmp=nil)
if bmp if bmp
tk_call_without_enc('wm', 'iconbitmap', path, bmp) tk_call_without_enc('wm', 'iconbitmap', win.epath, bmp)
self win
else else
image_obj(tk_call_without_enc('wm', 'iconbitmap', path)) image_obj(tk_call_without_enc('wm', 'iconbitmap', win.epath))
end end
end end
def iconbitmap(bmp=nil)
Wm.iconbitmap(self, bmp)
end
alias wm_iconbitmap iconbitmap
TOPLEVEL_METHODCALL_OPTKEYS['iconbitmap'] = 'iconbitmap' TOPLEVEL_METHODCALL_OPTKEYS['iconbitmap'] = 'iconbitmap'
def iconphoto(*imgs) def Wm.iconphoto(win, *imgs)
if imgs.empty? if imgs.empty?
win.instance_eval{
@wm_iconphoto = nil unless defined? @wm_iconphoto @wm_iconphoto = nil unless defined? @wm_iconphoto
return @wm_iconphoto return @wm_iconphoto
}
end end
imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array) imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array)
tk_call_without_enc('wm', 'iconphoto', path, *imgs) tk_call_without_enc('wm', 'iconphoto', win.epath, *imgs)
@wm_iconphoto = imgs win.instance_eval{ @wm_iconphoto = imgs }
self win
end end
def iconphoto(*imgs)
Wm.iconphoto(self, *imgs)
end
alias wm_iconphoto iconphoto
TOPLEVEL_METHODCALL_OPTKEYS['iconphoto'] = 'iconphoto' TOPLEVEL_METHODCALL_OPTKEYS['iconphoto'] = 'iconphoto'
def iconphoto_default(*imgs) def Wm.iconphoto_default(win, *imgs)
imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array) imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array)
tk_call_without_enc('wm', 'iconphoto', path, '-default', *imgs) tk_call_without_enc('wm', 'iconphoto', win.epath, '-default', *imgs)
self win
end end
def iconphoto_default(*imgs)
Wm.iconphoto_default(self, *imgs)
end
alias wm_iconphoto_default iconphoto_default
def iconify(ex = true) def Wm.iconify(win, ex = true)
if ex if ex
tk_call_without_enc('wm', 'iconify', path) tk_call_without_enc('wm', 'iconify', win.epath)
else else
self.deiconify Wm.deiconify(win)
end end
self win
end end
def iconify(ex = true)
Wm.iconify(self, ex)
end
alias wm_iconify iconify
def iconmask(bmp=nil) def Wm.iconmask(win, bmp=nil)
if bmp if bmp
tk_call_without_enc('wm', 'iconmask', path, bmp) tk_call_without_enc('wm', 'iconmask', win.epath, bmp)
self win
else else
image_obj(tk_call_without_enc('wm', 'iconmask', path)) image_obj(tk_call_without_enc('wm', 'iconmask', win.epath))
end end
end end
def iconmask(bmp=nil)
Wm.iconmask(self, bmp)
end
alias wm_iconmask iconmask
TOPLEVEL_METHODCALL_OPTKEYS['iconmask'] = 'iconmask' TOPLEVEL_METHODCALL_OPTKEYS['iconmask'] = 'iconmask'
def iconname(name=nil) def Wm.iconname(win, name=nil)
if name if name
tk_call('wm', 'iconname', path, name) tk_call('wm', 'iconname', win.epath, name)
self win
else else
tk_call('wm', 'iconname', path) tk_call('wm', 'iconname', win.epath)
end end
end end
def iconname(name=nil)
Wm.iconname(self, name)
end
alias wm_iconname iconname
TOPLEVEL_METHODCALL_OPTKEYS['iconname'] = 'iconname' TOPLEVEL_METHODCALL_OPTKEYS['iconname'] = 'iconname'
def iconposition(*args) def Wm.iconposition(win, *args)
if args.size == 0 if args.size == 0
list(tk_call_without_enc('wm', 'iconposition', path)) list(tk_call_without_enc('wm', 'iconposition', win.epath))
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call_without_enc('wm', 'iconposition', path, *args) tk_call_without_enc('wm', 'iconposition', win.epath, *args)
self win
end end
end end
def iconposition(*args)
Wm.iconposition(self, *args)
end
alias wm_iconposition iconposition
TOPLEVEL_METHODCALL_OPTKEYS['iconposition'] = 'iconposition' TOPLEVEL_METHODCALL_OPTKEYS['iconposition'] = 'iconposition'
def iconwindow(win = nil) def Wm.iconwindow(win, iconwin = nil)
if win if iconwin
tk_call_without_enc('wm', 'iconwindow', path, win) tk_call_without_enc('wm', 'iconwindow', win.epath, iconwin)
self win
else else
w = tk_call_without_enc('wm', 'iconwindow', path) w = tk_call_without_enc('wm', 'iconwindow', win.epath)
(w == '')? nil: window(w) (w == '')? nil: window(w)
end end
end end
def iconwindow(iconwin = nil)
Wm.iconwindow(self, iconwin)
end
alias wm_iconwindow iconwindow
TOPLEVEL_METHODCALL_OPTKEYS['iconwindow'] = 'iconwindow' TOPLEVEL_METHODCALL_OPTKEYS['iconwindow'] = 'iconwindow'
def maxsize(*args) def Wm.manage(win)
# Tcl/Tk 8.5+ feature
tk_call_without_enc('wm', 'manage', win.epath)
win
end
def wm_manage
Wm.manage(self)
end
=begin
def Wm.manage(win, use_id = nil)
# Tcl/Tk 8.5+ feature
# --------------------------------------------------------------
# In the future release, I want to support to embed the 'win'
# into the container which has window-id 'use-id'.
# It may give users frexibility on controlling their GUI.
# However, it may be difficult for current Tcl/Tk (Tcl/Tk8.5.1),
# because it seems to require to modify Tcl/Tk's source code.
# --------------------------------------------------------------
if use_id
tk_call_without_enc('wm', 'manage', win.epath, '-use', use_id)
else
tk_call_without_enc('wm', 'manage', win.epath)
end
win
end
=end
def Wm.maxsize(win, *args)
if args.size == 0 if args.size == 0
list(tk_call_without_enc('wm', 'maxsize', path)) list(tk_call_without_enc('wm', 'maxsize', win.epath))
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call_without_enc('wm', 'maxsize', path, *args) tk_call_without_enc('wm', 'maxsize', win.epath, *args)
self win
end end
end end
def maxsize(*args)
Wm.maxsize(self, *args)
end
alias wm_maxsize maxsize
TOPLEVEL_METHODCALL_OPTKEYS['maxsize'] = 'maxsize' TOPLEVEL_METHODCALL_OPTKEYS['maxsize'] = 'maxsize'
def minsize(*args) def Wm.minsize(win, *args)
if args.size == 0 if args.size == 0
list(tk_call_without_enc('wm', 'minsize', path)) list(tk_call_without_enc('wm', 'minsize', win.epath))
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call_without_enc('wm', 'minsize', path, *args) tk_call_without_enc('wm', 'minsize', win.path, *args)
self win
end end
end end
def minsize(*args)
Wm.minsize(self, *args)
end
alias wm_minsize minsize
TOPLEVEL_METHODCALL_OPTKEYS['minsize'] = 'minsize' TOPLEVEL_METHODCALL_OPTKEYS['minsize'] = 'minsize'
def overrideredirect(mode=None) def Wm.overrideredirect(win, mode=TkComm::None)
if mode == None if mode == TkComm::None
bool(tk_call_without_enc('wm', 'overrideredirect', path)) bool(tk_call_without_enc('wm', 'overrideredirect', win.epath))
else else
tk_call_without_enc('wm', 'overrideredirect', path, mode) tk_call_without_enc('wm', 'overrideredirect', win.epath, mode)
self win
end end
end end
def overrideredirect(mode=TkComm::None)
Wm.overrideredirect(self, mode=TkComm::None)
end
alias wm_overrideredirect overrideredirect
TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect' TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect'
def positionfrom(who=None) def Wm.positionfrom(win, who=TkComm::None)
if who == None if who == TkComm::None
r = tk_call_without_enc('wm', 'positionfrom', path) r = tk_call_without_enc('wm', 'positionfrom', win.epath)
(r == "")? nil: r (r == "")? nil: r
else else
tk_call_without_enc('wm', 'positionfrom', path, who) tk_call_without_enc('wm', 'positionfrom', win.epath, who)
self win
end end
end end
def positionfrom(who=TkComm::None)
Wm.positionfrom(self, who)
end
alias wm_positionfrom positionfrom
TOPLEVEL_METHODCALL_OPTKEYS['positionfrom'] = 'positionfrom' TOPLEVEL_METHODCALL_OPTKEYS['positionfrom'] = 'positionfrom'
def protocol(name=nil, cmd=nil, &b) def Wm.protocol(win, name=nil, cmd=nil, &b)
if cmd if cmd
tk_call_without_enc('wm', 'protocol', path, name, cmd) tk_call_without_enc('wm', 'protocol', win.epath, name, cmd)
self win
elsif b elsif b
tk_call_without_enc('wm', 'protocol', path, name, proc(&b)) tk_call_without_enc('wm', 'protocol', win.epath, name, proc(&b))
self win
elsif name elsif name
result = tk_call_without_enc('wm', 'protocol', path, name) result = tk_call_without_enc('wm', 'protocol', win.epath, name)
(result == "")? nil : tk_tcl2ruby(result) (result == "")? nil : tk_tcl2ruby(result)
else else
tk_split_simplelist(tk_call_without_enc('wm', 'protocol', path)) tk_split_simplelist(tk_call_without_enc('wm', 'protocol', win.epath))
end end
end end
def protocol(name=nil, cmd=nil, &b)
Wm.protocol(self, name, cmd, &b)
end
alias wm_protocol protocol
def protocols(kv=nil) def Wm.protocols(win, kv=nil)
unless kv unless kv
ret = {} ret = {}
self.protocol.each{|name| Wm.protocol(win).each{|name|
ret[name] = self.protocol(name) ret[name] = Wm.protocol(win, name)
} }
return ret return ret
end end
@ -279,82 +413,140 @@ module Tk
unless kv.kind_of?(Hash) unless kv.kind_of?(Hash)
fail ArgumentError, 'expect a hash of protocol=>command' fail ArgumentError, 'expect a hash of protocol=>command'
end end
kv.each{|k, v| self.protocol(k, v)} kv.each{|k, v| Wm.protocol(win, k, v)}
self win
end end
def protocols(kv=nil)
Wm.protocols(self, kv)
end
alias wm_protocols protocols
TOPLEVEL_METHODCALL_OPTKEYS['protocols'] = 'protocols' TOPLEVEL_METHODCALL_OPTKEYS['protocols'] = 'protocols'
def resizable(*args) def Wm.resizable(win, *args)
if args.length == 0 if args.length == 0
list(tk_call_without_enc('wm', 'resizable', path)).collect{|e| bool(e)} list(tk_call_without_enc('wm', 'resizable', win.epath)).map!{|e| bool(e)}
else else
args = args[0] if args.length == 1 && args[0].kind_of?(Array) args = args[0] if args.length == 1 && args[0].kind_of?(Array)
tk_call_without_enc('wm', 'resizable', path, *args) tk_call_without_enc('wm', 'resizable', win.epath, *args)
self win
end end
end end
def resizable(*args)
Wm.resizable(self, *args)
end
alias wm_resizable resizable
TOPLEVEL_METHODCALL_OPTKEYS['resizable'] = 'resizable' TOPLEVEL_METHODCALL_OPTKEYS['resizable'] = 'resizable'
def sizefrom(who=None) def Wm.sizefrom(win, who=TkComm::None)
if who == None if who == TkComm::None
r = tk_call_without_enc('wm', 'sizefrom', path) r = tk_call_without_enc('wm', 'sizefrom', win.epath)
(r == "")? nil: r (r == "")? nil: r
else else
tk_call_without_enc('wm', 'sizefrom', path, who) tk_call_without_enc('wm', 'sizefrom', win.epath, who)
self win
end end
end end
def sizefrom(who=TkComm::None)
Wm.sizefrom(self, who)
end
alias wm_sizefrom sizefrom
TOPLEVEL_METHODCALL_OPTKEYS['sizefrom'] = 'sizefrom' TOPLEVEL_METHODCALL_OPTKEYS['sizefrom'] = 'sizefrom'
def Wm.stackorder(win)
list(tk_call('wm', 'stackorder', win.epath))
end
def stackorder def stackorder
list(tk_call('wm', 'stackorder', path)) Wm.stackorder(self)
end end
alias wm_stackorder stackorder
def stackorder_isabove(win) def Wm.stackorder_isabove(win, target)
bool(tk_call('wm', 'stackorder', path, 'isabove', win)) bool(tk_call('wm', 'stackorder', win.epath, 'isabove', target))
end end
def Wm.stackorder_is_above(win, target)
def stackorder_isbelow(win) Wm.stackorder_isabove(win, target)
bool(tk_call('wm', 'stackorder', path, 'isbelow', win))
end end
def stackorder_isabove(target)
Wm.stackorder_isabove(self, target)
end
alias stackorder_is_above stackorder_isabove
alias wm_stackorder_isabove stackorder_isabove
alias wm_stackorder_is_above stackorder_isabove
def state(st=nil) def Wm.stackorder_isbelow(win, target)
bool(tk_call('wm', 'stackorder', win.epath, 'isbelow', target))
end
def Wm.stackorder_is_below(win, target)
Wm.stackorder_isbelow(win, target)
end
def stackorder_isbelow(target)
Wm.stackorder_isbelow(self, target)
end
alias stackorder_is_below stackorder_isbelow
alias wm_stackorder_isbelow stackorder_isbelow
alias wm_stackorder_is_below stackorder_isbelow
def Wm.state(win, st=nil)
if st if st
tk_call_without_enc('wm', 'state', path, st) tk_call_without_enc('wm', 'state', win.epath, st)
self win
else else
tk_call_without_enc('wm', 'state', path) tk_call_without_enc('wm', 'state', win.epath)
end end
end end
def state(st=nil)
Wm.state(self, st)
end
alias wm_state state
TOPLEVEL_METHODCALL_OPTKEYS['state'] = 'state' TOPLEVEL_METHODCALL_OPTKEYS['state'] = 'state'
def title(str=nil) def Wm.title(win, str=nil)
if str if str
tk_call('wm', 'title', path, str) tk_call('wm', 'title', win.epath, str)
self win
else else
tk_call('wm', 'title', path) tk_call('wm', 'title', win.epath)
end end
end end
def title(str=nil)
Wm.title(self, str)
end
alias wm_title title
TOPLEVEL_METHODCALL_OPTKEYS['title'] = 'title' TOPLEVEL_METHODCALL_OPTKEYS['title'] = 'title'
def transient(master=nil) def Wm.transient(win, master=nil)
if master if master
tk_call_without_enc('wm', 'transient', path, master) tk_call_without_enc('wm', 'transient', win.epath, master)
self win
else else
window(tk_call_without_enc('wm', 'transient', path)) window(tk_call_without_enc('wm', 'transient', win.epath))
end end
end end
def transient(master=nil)
Wm.transient(self, master)
end
alias wm_transient transient
TOPLEVEL_METHODCALL_OPTKEYS['transient'] = 'transient' TOPLEVEL_METHODCALL_OPTKEYS['transient'] = 'transient'
def withdraw(ex = true) def Wm.withdraw(win, ex = true)
if ex if ex
tk_call_without_enc('wm', 'withdraw', path) tk_call_without_enc('wm', 'withdraw', win.epath)
else else
self.deiconify Wm.deiconify(win)
end
self
end end
win
end
def withdraw(ex = true)
Wm.withdraw(self, ex)
end
alias wm_withdraw withdraw
end
module Wm_for_General
Wm.instance_methods.each{|m|
if (m = m.to_s) =~ /^wm_(.*)$/
eval "def #{m}(*args); Tk::Wm.#{$1}(self, *args); end"
end
}
end end
end end

View file

@ -83,7 +83,7 @@ BLT 2.4z http://sourceforge.net/projects/blt
TkTreeCtrl CVS/Hd(2005-12-02) TkTreeCtrl CVS/Hd(2005-12-02)
http://sourceforge.net/projects/tktreectrl ==> treectrl http://sourceforge.net/projects/tktreectrl ==> treectrl
Tile 0.7.8 Tile 0.8.0/8.5.1
http://sourceforge.net/projects/tktable ==> tile http://sourceforge.net/projects/tktable ==> tile

View file

@ -13,7 +13,16 @@ module Tk::BLT
TkCommandNames = ['::blt::bitmap'.freeze].freeze TkCommandNames = ['::blt::bitmap'.freeze].freeze
BITMAP_ID_TBL = TkCore::INTERP.create_table BITMAP_ID_TBL = TkCore::INTERP.create_table
BITMAP_ID = ['blt_bitmap_id'.freeze, '00000'.taint].freeze
(BITMAP_ID = ['blt_bitmap_id'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
BITMAP_ID_TBL.mutex.synchronize{ BITMAP_ID_TBL.clear }
}
def self.data(name) def self.data(name)
dat = tk_simple_list(tk_call('::blt::bitmap', 'data', name)) dat = tk_simple_list(tk_call('::blt::bitmap', 'data', name))
@ -64,9 +73,13 @@ module Tk::BLT
if name if name
@id = name @id = name
else else
BITMAP_ID.mutex.synchronize{
@id = BITMAP_ID.join(TkCore::INTERP._ip_id_) @id = BITMAP_ID.join(TkCore::INTERP._ip_id_)
BITMAP_ID[1].succ! BITMAP_ID[1].succ!
}
BITMAP_ID_TBL.mutex.synchronize{
BITMAP_ID_TBL[@id] = self BITMAP_ID_TBL[@id] = self
}
end end
@path = @id @path = @id

View file

@ -19,7 +19,7 @@ module Tk::BLT
class Shield < TkWindow class Shield < TkWindow
def self.shield_path(win) def self.shield_path(win)
win = window(win) unless win.kind_of?(TkWindow) win = window(win) unless win.kind_of?(TkWindow)
if win.kind_of?(TkToplevel) if win.kind_of?(Tk::Toplevel)
win.path + '._Busy' win.path + '._Busy'
else else
win.path + '_Busy' win.path + '_Busy'

View file

@ -327,13 +327,24 @@ module Tk::BLT
################# #################
class Axis < TkObject class Axis < TkObject
OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint].freeze (OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint]).instance_eval{
OBJ_TBL={} @mutex = Mutex.new
def mutex; @mutex; end
freeze
}
AxisID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{
AxisID_TBL.mutex.synchronize{ AxisID_TBL.clear }
}
def self.id2obj(chart, id) def self.id2obj(chart, id)
cpath = chart.path cpath = chart.path
return id unless OBJ_TBL[cpath] AxisID_TBL.mutex.synchronize{
OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id return id unless AxisID_TBL[cpath]
AxisID_TBL[cpath][id]? AxisID_TBL[cpath][id]: id
}
end end
def self.new(chart, axis=nil, keys={}) def self.new(chart, axis=nil, keys={})
@ -341,12 +352,48 @@ module Tk::BLT
keys = axis keys = axis
axis = nil axis = nil
end end
OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] if keys
return OBJ_TBL[chart.path][axis] if axis && OBJ_TBL[chart.path][axis] keys = _symbolkey2str(keys)
super(chart, axis, keys) not_create = keys.delete('without_creating')
else
not_create = false
end
obj = nil
AxisID_TBL.mutex.synchronize{
chart_path = chart.path
AxisID_TBL[chart_path] ||= {}
if axis && AxisID_TBL[chart_path][axis]
obj = AxisID_TBL[chart_path][axis]
else
(obj = self.allocate).instance_eval{
if axis
@axis = @id = axis.to_s
else
OBJ_ID.mutex.synchronize{
@axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
OBJ_ID[1].succ!
}
end
@path = @id
@parent = @chart = chart
@cpath = @chart.path
Axis::AxisID_TBL[@cpath][@axis] = self
unless not_create
tk_call(@chart, 'axis', 'create', @axis, keys)
return obj
end
}
end
}
obj.configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, axis=nil, keys={}) def initialize(chart, axis=nil, keys={})
# dummy:: not called by 'new' method
if axis.kind_of?(Hash) if axis.kind_of?(Hash)
keys = axis keys = axis
axis = nil axis = nil
@ -354,13 +401,15 @@ module Tk::BLT
if axis if axis
@axis = @id = axis.to_s @axis = @id = axis.to_s
else else
OBJ_ID.mutex.synchronize{
@axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
OBJ_ID[1].succ! OBJ_ID[1].succ!
}
end end
@path = @id @path = @id
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
Axis::OBJ_TBL[@cpath][@axis] = self # Axis::AxisID_TBL[@cpath][@axis] = self
keys = _symbolkey2str(keys) keys = _symbolkey2str(keys)
unless keys.delete('without_creating') unless keys.delete('without_creating')
# @chart.axis_create(@axis, keys) # @chart.axis_create(@axis, keys)
@ -438,17 +487,34 @@ module Tk::BLT
################# #################
class Crosshairs < TkObject class Crosshairs < TkObject
OBJ_TBL={} CrosshairsID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{
CrosshairsID_TBL.mutex.synchronize{ CrosshairsID_TBL.clear }
}
def self.new(chart, keys={}) def self.new(chart, keys={})
return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] obj = nil
super(chart, keys) CrosshairsID_TBL.mutex.synchronize{
unless (obj = CrosshairsID_TBL[chart.path])
(obj = self.allocate).instance_eval{
@parent = @chart = chart
@cpath = @chart.path
@path = @id = 'crosshairs'
Crosshairs::CrosshairsID_TBL[@cpath] = self
}
end
}
chart.crosshair_configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, keys={}) def initialize(chart, keys={})
# dummy:: not called by 'new' method
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
Crosshairs::OBJ_TBL[@cpath] = self # Crosshairs::CrosshairsID_TBL[@cpath] = self
@chart.crosshair_configure(keys) unless keys.empty? @chart.crosshair_configure(keys) unless keys.empty?
@path = @id = 'crosshairs' @path = @id = 'crosshairs'
end end
@ -500,12 +566,18 @@ module Tk::BLT
ElementTypeName = 'element' ElementTypeName = 'element'
ElementTypeToClass = { ElementTypeName=>self } ElementTypeToClass = { ElementTypeName=>self }
ElementID_TBL = TkCore::INTERP.create_table ElementID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ ElementID_TBL.clear } TkCore::INTERP.init_ip_env{
ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear }
}
OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint].freeze (OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint]).instance_eval{
OBJ_TBL={} @mutex = Mutex.new
def mutex; @mutex; end
freeze
}
def Element.type2class(type) def Element.type2class(type)
ElementTypeToClass[type] ElementTypeToClass[type]
@ -513,8 +585,10 @@ module Tk::BLT
def Element.id2obj(chart, id) def Element.id2obj(chart, id)
cpath = chart.path cpath = chart.path
return id unless OBJ_TBL[cpath] ElementID_TBL.mutex.synchronize{
OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id return id unless ElementID_TBL[cpath]
ElementID_TBL[cpath][id]? ElementID_TBL[cpath][id]: id
}
end end
def self.new(chart, element=nil, keys={}) def self.new(chart, element=nil, keys={})
@ -522,14 +596,49 @@ module Tk::BLT
keys = element keys = element
element = nil element = nil
end end
OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] if keys
if element && OBJ_TBL[chart.path][element] keys = _symbolkey2str(keys)
return OBJ_TBL[chart.path][element] not_create = keys.delete('without_creating')
else
not_create = false
end end
super(chart, element, keys)
obj = nil
ElementID_TBL.mutex.synchronize{
chart_path = chart.path
ElementID_TBL[chart_path] ||= {}
if element && ElementID_TBL[chart_path][element]
obj = ElementID_TBL[chart_path][element]
else
(obj = self.allocate).instance_eval{
if element
@element = @id = element.to_s
else
OBJ_ID.mutex.synchronize{
@element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
OBJ_ID[1].succ!
}
end
@path = @id
@parent = @chart = chart
@cpath = @chart.path
@typename = self.class::ElementTypeName
Element::ElementID_TBL[@cpath][@element] = self
unless not_create
tk_call(@chart, @typename, 'create', @element, keys)
return obj
end
}
end
}
obj.configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, element=nil, keys={}) def initialize(chart, element=nil, keys={})
# dummy:: not called by 'new' method
if element.kind_of?(Hash) if element.kind_of?(Hash)
keys = element keys = element
element = nil element = nil
@ -537,14 +646,16 @@ module Tk::BLT
if element if element
@element = @id = element.to_s @element = @id = element.to_s
else else
OBJ_ID.mutex.synchronize{
@element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
OBJ_ID[1].succ! OBJ_ID[1].succ!
}
end end
@path = @id @path = @id
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
@typename = self.class::ElementTypeName @typename = self.class::ElementTypeName
Element::OBJ_TBL[@cpath][@element] = self # Element::ElementID_TBL[@cpath][@element] = self
keys = _symbolkey2str(keys) keys = _symbolkey2str(keys)
unless keys.delete('without_creating') unless keys.delete('without_creating')
# @chart.element_create(@element, keys) # @chart.element_create(@element, keys)
@ -622,17 +733,33 @@ module Tk::BLT
################# #################
class GridLine < TkObject class GridLine < TkObject
OBJ_TBL={} GridLineID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{
GridLineID_TBL.mutex.synchronize{ GridLineID_TBL.clear }
}
def self.new(chart, keys={}) def self.new(chart, keys={})
return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] obj = nil
super(chart, keys) GridLineID_TBL.mutex.synchronize{
unless (obj = GridLineID_TBL[chart.path])
(obj = self.allocate).instance_eval{
@parent = @chart = chart
@cpath = @chart.path
@path = @id = 'grid'
GridLine::GridLineID_TBL[@cpath] = self
}
end
}
chart.gridline_configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, keys={}) def initialize(chart, keys={})
# dummy:: not called by 'new' method
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
GridLine::OBJ_TBL[@cpath] = self # GridLine::GridLineID_TBL[@cpath] = self
@chart.gridline_configure(keys) unless keys.empty? @chart.gridline_configure(keys) unless keys.empty?
@path = @id = 'grid' @path = @id = 'grid'
end end
@ -676,18 +803,35 @@ module Tk::BLT
################# #################
class Legend < TkObject class Legend < TkObject
OBJ_TBL={} LegendID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{
LegendID_TBL.mutex.synchronize{ LegendID_TBL.clear }
}
def self.new(chart, keys={}) def self.new(chart, keys={})
return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] obj = nil
super(chart, keys) LegenedID_TBL.mutex.synchronize{
unless (obj = LegenedID_TBL[chart.path])
(obj = self.allocate).instance_eval{
@parent = @chart = chart
@cpath = @chart.path
@path = @id = 'crosshairs'
Legend::LegenedID_TBL[@cpath] = self
}
end
}
chart.legend_configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, keys={}) def initialize(chart, keys={})
# dummy:: not called by 'new' method
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
Crosshairs::OBJ_TBL[@cpath] = self # Legend::LegendID_TBL[@cpath] = self
@chart.crosshair_configure(keys) unless keys.empty? @chart.legend_configure(keys) unless keys.empty?
@path = @id = 'legend' @path = @id = 'legend'
end end
@ -729,13 +873,24 @@ module Tk::BLT
################# #################
class Pen < TkObject class Pen < TkObject
OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint].freeze (OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint]).instance_eval{
OBJ_TBL={} @mutex = Mutex.new
def mutex; @mutex; end
freeze
}
PenID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{
PenID_TBL.mutex.synchronize{ PenID_TBL.clear }
}
def self.id2obj(chart, id) def self.id2obj(chart, id)
cpath = chart.path cpath = chart.path
return id unless OBJ_TBL[cpath] PenID_TBL.mutex.synchronize{
OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id return id unless PenID_TBL[cpath]
PenID_TBL[cpath][id]? PenID_TBL[cpath][id]: id
}
end end
def self.new(chart, pen=nil, keys={}) def self.new(chart, pen=nil, keys={})
@ -743,9 +898,43 @@ module Tk::BLT
keys = pen keys = pen
pen = nil pen = nil
end end
OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] if keys
return OBJ_TBL[chart.path][pen] if pen && OBJ_TBL[chart.path][pen] keys = _symbolkey2str(keys)
super(chart, pen, keys) not_create = keys.delete('without_creating')
else
not_create = false
end
obj = nil
PenID_TBL.mutex.synchronize{
chart_path = chart.path
PenID_TBL[chart_path] ||= {}
if pen && PenID_TBL[chart_path][pen]
obj = PenID_TBL[chart_path][pen]
else
(obj = self.allocate).instance_eval{
if pen
@pen = @id = pen.to_s
else
OBJ_ID.mutex.synchronize{
@pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
OBJ_ID[1].succ!
}
end
@path = @id
@parent = @chart = chart
@cpath = @chart.path
Pen::PenID_TBL[@cpath][@pen] = self
unless not_create
tk_call(@chart, 'pen', 'create', @pen, keys)
return obj
end
}
end
}
obj.configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, pen=nil, keys={}) def initialize(chart, pen=nil, keys={})
@ -756,13 +945,15 @@ module Tk::BLT
if pen if pen
@pen = @id = pen.to_s @pen = @id = pen.to_s
else else
OBJ_ID.mutex.synchronize{
@pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze
OBJ_ID[1].succ! OBJ_ID[1].succ!
}
end end
@path = @id @path = @id
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
Pen::OBJ_TBL[@cpath][@pen] = self Pen::PenID_TBL[@cpath][@pen] = self
keys = _symbolkey2str(keys) keys = _symbolkey2str(keys)
unless keys.delete('without_creating') unless keys.delete('without_creating')
# @chart.pen_create(@pen, keys) # @chart.pen_create(@pen, keys)
@ -805,17 +996,34 @@ module Tk::BLT
################# #################
class Postscript < TkObject class Postscript < TkObject
OBJ_TBL={} PostscriptID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{
PostscriptID_TBL.mutex.synchronize{ PostscriptID_TBL.clear }
}
def self.new(chart, keys={}) def self.new(chart, keys={})
return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] obj = nil
super(chart, keys) PostscriptID_TBL.mutex.synchronize{
unless (obj = PostscriptID_TBL[chart.path])
(obj = self.allocate).instance_eval{
@parent = @chart = chart
@cpath = @chart.path
@path = @id = 'postscript'
Postscript::PostscriptID_TBL[@cpath] = self
}
end
}
chart.postscript_configure(keys) if obj && ! keys.empty?
obj
end end
def initialize(chart, keys={}) def initialize(chart, keys={})
# dummy:: not called by 'new' method
@parent = @chart = chart @parent = @chart = chart
@cpath = @chart.path @cpath = @chart.path
Postscript::OBJ_TBL[@cpath] = self # Postscript::PostscriptID_TBL[@cpath] = self
@chart.postscript_configure(keys) unless keys.empty? @chart.postscript_configure(keys) unless keys.empty?
@path = @id = 'postscript' @path = @id = 'postscript'
end end
@ -870,7 +1078,9 @@ module Tk::BLT
MarkerTypeToClass = {} MarkerTypeToClass = {}
MarkerID_TBL = TkCore::INTERP.create_table MarkerID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ MarkerID_TBL.clear } TkCore::INTERP.init_ip_env{
MarkerID_TBL.mutex.synchronize{ MarkerID_TBL.clear }
}
def Marker.type2class(type) def Marker.type2class(type)
MarkerTypeToClass[type] MarkerTypeToClass[type]
@ -878,8 +1088,13 @@ module Tk::BLT
def Marker.id2obj(chart, id) def Marker.id2obj(chart, id)
cpath = chart.path cpath = chart.path
return id unless MarkerID_TBL[cpath] MarkerID_TBL.mutex.synchronize{
if MarkerID_TBL[cpath]
MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id
else
id
end
}
end end
def self._parse_create_args(keys) def self._parse_create_args(keys)
@ -943,11 +1158,11 @@ module Tk::BLT
@parent = @chart = chart @parent = @chart = chart
@cpath = chart.path @cpath = chart.path
@id = id @id = id
unless Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{
Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] = {} Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {}
end
Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self
} }
}
obj obj
end end
@ -956,10 +1171,10 @@ module Tk::BLT
@cpath = parent.path @cpath = parent.path
@path = @id = create_self(*args) # an integer number as 'item id' @path = @id = create_self(*args) # an integer number as 'item id'
unless Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{
Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] = {} Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {}
end
Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self
}
end end
def create_self(*args) def create_self(*args)
self.class.create(@chart, *args) # return an integer as 'item id' self.class.create(@chart, *args) # return an integer as 'item id'
@ -1037,14 +1252,14 @@ module Tk::BLT
################# #################
def __destroy_hook__ def __destroy_hook__
Axis::OBJ_TBL.delete(@path) Axis::AxisID_TBL.delete(@path)
Crosshairs::OBJ_TBL.delete(@path) Crosshairs::CrosshairsID_TBL.delete(@path)
Element::OBJ_TBL.delete(@path) Element::ElementID_TBL.delete(@path)
GridLine::OBJ_TBL.delete(@path) GridLine::GridLineID_TBL.delete(@path)
Legend::OBJ_TBL.delete(@path) Legend::LegendID_TBL.delete(@path)
Pen::OBJ_TBL.delete(@path) Pen::PenID_TBL.delete(@path)
Postscript::OBJ_TBL.delete(@path) Postscript::PostscriptID_TBL.delete(@path)
Marker::OBJ_TBL.delete(@path) Marker::MarkerID_TBL.delete(@path)
super() super()
end end

View file

@ -81,6 +81,22 @@ module Tk::BLT
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL) _setup_subst_table(KEY_TBL, PROC_TBL)
def self.ret_val(val) def self.ret_val(val)
@ -107,6 +123,22 @@ module Tk::BLT
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL) _setup_subst_table(KEY_TBL, PROC_TBL)
def self.ret_val(val) def self.ret_val(val)
@ -145,6 +177,22 @@ module Tk::BLT
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL) _setup_subst_table(KEY_TBL, PROC_TBL)
end end

View file

@ -14,7 +14,7 @@ module Tk::BLT
end end
end end
class TkCanvas class Tk::Canvas
alias __BLT_EPS_item_strval_optkeys __item_strval_optkeys alias __BLT_EPS_item_strval_optkeys __item_strval_optkeys
def __item_strval_optkeys(id) def __item_strval_optkeys(id)
__BLT_EPS_item_strval_optkeys(id) + [ __BLT_EPS_item_strval_optkeys(id) + [

View file

@ -12,14 +12,26 @@ module Tk::BLT
include TkTreatItemFont include TkTreatItemFont
TabID_TBL = TkCore::INTERP.create_table TabID_TBL = TkCore::INTERP.create_table
TabsetTab_ID = ['blt_tabset_tab'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TabID_TBL.clear } (TabsetTab_ID = ['blt_tabset_tab'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
TabID_TBL.mutex.synchronize{ TabID_TBL.clear }
}
def self.id2obj(tabset, id) def self.id2obj(tabset, id)
tpath = tabset.path tpath = tabset.path
return id unless TabID_TBL[tpath] TabID_TBL.mutex.synchronize{
if TabID_TBL[tpath]
TabID_TBL[tpath][id]? TabID_TBL[tpath]: id TabID_TBL[tpath][id]? TabID_TBL[tpath]: id
else
id
end
}
end end
def self.new(parent, pos=nil, name=nil, keys={}) def self.new(parent, pos=nil, name=nil, keys={})
@ -32,12 +44,20 @@ module Tk::BLT
keys = name keys = name
name = nil name = nil
end end
obj = nil
TabID_TBL.mutex.synchronize{
if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name] if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]
TabID_TBL[parent.path][name] obj = TabID_TBL[parent.path][name]
obj.configure if keys && ! keys.empty?
else else
super(parent, pos, name, keys) (obj = self.allocate).instance_eval{
initialize(parent, pos, name, keys)
TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
TabID_TBL[@tpath][@id] = self
}
end end
}
obj
end end
def initialize(parent, pos, name, keys) def initialize(parent, pos, name, keys)
@ -45,9 +65,6 @@ module Tk::BLT
@tpath = parent.path @tpath = parent.path
if name if name
@path = @id = name @path = @id = name
TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
TabID_TBL[@tpath][@id] = self
unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?) unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)
if pos if pos
idx = tk_call(@tpath, 'index', '-name', @id) idx = tk_call(@tpath, 'index', '-name', @id)
@ -58,19 +75,19 @@ module Tk::BLT
end end
end end
tk_call(@tpath, 'tab', 'configure', @id, keys) tk_call(@tpath, 'tab', 'configure', @id, keys)
return
end
else else
@path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)
TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
TabID_TBL[@tpath][@id] = self
TabsetTab_ID[1].succ!
end
pos = 'end' unless pos pos = 'end' unless pos
tk_call(@tpath, 'insert', pos, @id, keys) tk_call(@tpath, 'insert', pos, @id, keys)
end end
else
TabsetTab_ID.mutex.synchronize{
@path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)
TabsetTab_ID[1].succ!
}
pos = 'end' unless pos
tk_call(@tpath, 'insert', pos, @id, keys)
end
end
#def bind(context, cmd=Proc.new, *args) #def bind(context, cmd=Proc.new, *args)
# @t.tab_bind(@id, context, cmd, *args) # @t.tab_bind(@id, context, cmd, *args)
@ -123,7 +140,9 @@ module Tk::BLT
def delete() def delete()
@t.delete(@id) @t.delete(@id)
TabID_TBL.mutex.synchronize{
TabID_TBL[@tpath].delete(@id) TabID_TBL[@tpath].delete(@id)
}
self self
end end
@ -184,7 +203,9 @@ module Tk::BLT
WidgetClassNames[WidgetClassName] = self WidgetClassNames[WidgetClassName] = self
def __destroy_hook__ def __destroy_hook__
Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{
Tk::BLT::Tabset::Tab::TabID_TBL.delete(@path) Tk::BLT::Tabset::Tab::TabID_TBL.delete(@path)
}
end end
######################################## ########################################
@ -291,11 +312,15 @@ module Tk::BLT
def delete(first, last=None) def delete(first, last=None)
tk_send('delete', tagindex(first), tagindex(last)) tk_send('delete', tagindex(first), tagindex(last))
if first.kind_of?(Tk::BLT::Tabset::Tab) if first.kind_of?(Tk::BLT::Tabset::Tab)
TabID_TBL.mutex.synchronize{
TabID_TBL[@path].delete(first.id) TabID_TBL[@path].delete(first.id)
}
end end
# middle tabs of the range are unknown # middle tabs of the range are unknown
if last.kind_of?(Tk::BLT::Tabset::Tab) if last.kind_of?(Tk::BLT::Tabset::Tab)
TabID_TBL.mutex.synchronize{
TabID_TBL[@path].delete(last.id) TabID_TBL[@path].delete(last.id)
}
end end
self self
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class Button < TkButton class Button < Tk::Button
TkCommandNames = ['::blt::tile::button'.freeze].freeze TkCommandNames = ['::blt::tile::button'.freeze].freeze
end end
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class CheckButton < TkCheckButton class CheckButton < Tk::CheckButton
TkCommandNames = ['::blt::tile::checkbutton'.freeze].freeze TkCommandNames = ['::blt::tile::checkbutton'.freeze].freeze
end end
Checkbutton = CheckButton Checkbutton = CheckButton

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class Frame < TkFrame class Frame < Tk::Frame
TkCommandNames = ['::blt::tile::frame'.freeze].freeze TkCommandNames = ['::blt::tile::frame'.freeze].freeze
end end
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class Label < TkLabel class Label < Tk::Label
TkCommandNames = ['::blt::tile::label'.freeze].freeze TkCommandNames = ['::blt::tile::label'.freeze].freeze
end end
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class RadioButton < TkRadioButton class RadioButton < Tk::RadioButton
TkCommandNames = ['::blt::tile::radiobutton'.freeze].freeze TkCommandNames = ['::blt::tile::radiobutton'.freeze].freeze
end end
Radiobutton = RadioButton Radiobutton = RadioButton

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class Scrollbar < TkScrollbar class Scrollbar < Tk::Scrollbar
TkCommandNames = ['::blt::tile::scrollbar'.freeze].freeze TkCommandNames = ['::blt::tile::scrollbar'.freeze].freeze
end end
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/blt/tile.rb'
module Tk::BLT module Tk::BLT
module Tile module Tile
class Toplevel < TkToplevel class Toplevel < Tk::Toplevel
TkCommandNames = ['::blt::tile::toplevel'.freeze].freeze TkCommandNames = ['::blt::tile::toplevel'.freeze].freeze
end end
end end

View file

@ -14,51 +14,75 @@ module Tk::BLT
class Node < TkObject class Node < TkObject
TreeNodeID_TBL = TkCore::INTERP.create_table TreeNodeID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ TreeNodeID_TBL.clear }
TkCore::INTERP.init_ip_env{
TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear }
}
def self.id2obj(tree, id) def self.id2obj(tree, id)
tpath = tree.path tpath = tree.path
return id unless TreeNodeID_TBL[tpath] TreeNodeID_TBL.mutex.synchronize{
if TreeNodeID_TBL[tpath]
if TreeNodeID_TBL[tpath][id] if TreeNodeID_TBL[tpath][id]
TreeNodeID_TBL[tpath][id] TreeNodeID_TBL[tpath][id]
else else
begin begin
self.new(tree, nil, 'node'=>Integer(id)) # self.new(tree, nil, 'node'=>Integer(id))
id = Integer(id)
if bool(tk_call(@tpath, 'exists', id))
(obj = self.allocate).instance_eval{
@parent = @tree = tree
@tpath = tpath
@path = @id = id
TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath]
TreeNodeID_TBL[@tpath][@id] = self
}
obj
else
id
end
rescue rescue
id id
end end
end end
else
id
end
}
end end
def self.new(tree, parent, keys={}) def self.new(tree, parent, keys={})
keys = _symbolkey2str(keys) keys = _symbolkey2str(keys)
tpath = tree.path tpath = tree.path
TreeNodeID_TBL.mutex.synchronize{
TreeNodeID_TBL[tpath] ||= {}
if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id]) if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id])
keys.delete('node') keys.delete('node')
tk_call(tree.path, 'move', id, parent, keys) if parent tk_call(tree.path, 'move', id, parent, keys) if parent
return obj return obj
end end
super(tree, parent, keys) (obj = self.allocate).instance_eval{
initialize(tree, parent, keys)
TreeNodeID_TBL[tpath][@id] = self
}
obj
}
end end
def initialize(tree, parent, keys={}) def initialize(tree, parent, keys={})
@parent = @tree = tree @parent = @tree = tree
@tpath = @parent.path @tpath = @parent.path
parent = tk_call(@tpath, 'root') unless parent
if (id = keys['node']) && bool(tk_call(@tpath, 'exists', id)) if (id = keys['node']) && bool(tk_call(@tpath, 'exists', id))
@path = @id = id @path = @id = id
keys.delete('node') keys.delete('node')
tk_call(@tpath, 'move', @id, parent, keys) if parent tk_call(@tpath, 'move', @id, parent, keys) if parent
else else
parent = tk_call(@tpath, 'root') unless parent
@path = @id = tk_call(@tpath, 'insert', parent, keys) @path = @id = tk_call(@tpath, 'insert', parent, keys)
end end
TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath]
TreeNodeID_TBL[@tpath][@id] = self
end end
def id def id
@ -243,18 +267,43 @@ module Tk::BLT
class Tag < TkObject class Tag < TkObject
TreeTagID_TBL = TkCore::INTERP.create_table TreeTagID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ TreeTagID_TBL.clear }
TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint].freeze TkCore::INTERP.init_ip_env{
TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }
}
(TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
def self.id2obj(tree, id) def self.id2obj(tree, id)
tpath = tree.path tpath = tree.path
return id unless TreeTagID_TBL[tpath] TreeTagID_TBL.mutex.synchronize{
if TreeTagID_TBL[tpath]
if TreeTagID_TBL[tpath][id] if TreeTagID_TBL[tpath][id]
TreeTagID_TBL[tpath][id] TreeTagID_TBL[tpath][id]
else else
self.new(tree, id) begin
# self.new(tree, id)
(obj = self.allocate).instance_eval{
@parent = @tree = tree
@tpath = @parent.path
@path = @id = id.dup.freeze if id
TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
TreeTagID_TBL[@tpath][@id] = self
}
obj
rescue
id
end end
end end
else
id
end
}
end
def initialize(tree, tag_str = nil) def initialize(tree, tag_str = nil)
@parent = @tree = tree @parent = @tree = tree
@ -263,12 +312,15 @@ module Tk::BLT
if tag_str if tag_str
@path = @id = tag_str.dup.freeze @path = @id = tag_str.dup.freeze
else else
TreeTag_ID.mutex.synchronize{
@path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_) @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_)
TreeTagID_TBL[@id] = self
TreeTag_ID[1].succ! TreeTag_ID[1].succ!
}
end end
TreeTagID_TBL.mutex.synchronize{
TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
TreeTagID_TBL[@tpath][@id] = self TreeTagID_TBL[@tpath][@id] = self
}
end end
def id def id
@ -287,7 +339,9 @@ module Tk::BLT
def forget() def forget()
tk_call(@tpath, 'tag', 'forget', @id) tk_call(@tpath, 'tag', 'forget', @id)
TreeTagID_TBL.mutex.synchronize{
TreeTagID_TBL[@tpath].delete(@id) TreeTagID_TBL[@tpath].delete(@id)
}
self self
end end
@ -312,44 +366,63 @@ module Tk::BLT
class Notify < TkObject class Notify < TkObject
NotifyID_TBL = TkCore::INTERP.create_table NotifyID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ NotifyID_TBL.clear }
TkCore::INTERP.init_ip_env{
NotifyID_TBL.mutex.synchronize{ NotifyID_TBL.clear }
}
def self.id2obj(tree, id) def self.id2obj(tree, id)
tpath = tree.path tpath = tree.path
return id unless NotifyID_TBL[tpath] NotifyID_TBL.mutex.synchronize{
if NotifyID_TBL[tpath]
if NotifyID_TBL[tpath][id] if NotifyID_TBL[tpath][id]
NotifyID_TBL[tpath][id] NotifyID_TBL[tpath][id]
else else
begin (obj = self.allocate).instance_eval{
self.new([tree, id]) @parent = @tree = tree
rescue @tpath = @parent.path
id @path = @id = id
NotifyID_TBL[@tpath] ||= {}
NotifyID_TBL[@tpath][@id] = self
}
obj
end end
else
return id
end end
}
end end
def self.new(tree, *args, &b) def self.new(tree, *args, &b)
NotifyID_TBL.mutex.synchronize{
if tree.kind_of?(Array) if tree.kind_of?(Array)
# not create # not create
if obj = NotifyID_TBL[tree[0].path][tree[1]] tpath = tree[0].path
NotifyID_TBL[tpath] ||= {}
unless (obj = NotifyID_TBL[tpath][tree[1]])
(NotifyID_TBL[tpath][tree[1]] =
obj = self.allocate).instance_eval{
@parent = @tree = tree[0]
@tpath = @parent.path
@path = @id = tree[1]
}
end
return obj return obj
else
return super(false, tree[0], tree[1])
end
end end
super(true, tree, *args, &b) (obj = self.allocate).instance_eval{
initialize(tree, *args, &b)
NotifyID_TBL[@tpath] ||= {}
NotifyID_TBL[@tpath][@id] = self
}
return obj
}
end end
def initialize(create, tree, *args, &b) def initialize(tree, *args, &b)
@parent = @tree = tree @parent = @tree = tree
@tpath = @parent.path @tpath = @parent.path
unless create
@path = @id = args[0]
return
end
# if args[0].kind_of?(Proc) || args[0].kind_of?(Method) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)
if TkComm._callback_entry?(args[0]) if TkComm._callback_entry?(args[0])
cmd = args.shift cmd = args.shift
@ -378,7 +451,9 @@ module Tk::BLT
def delete() def delete()
tk_call(@tpath, 'notify', 'delete', @id) tk_call(@tpath, 'notify', 'delete', @id)
NotifyID_TBL[tpath].delete(@id) NotifyID_TBL.mutex.synchronize{
NotifyID_TBL[@tpath].delete(@id)
}
self self
end end
@ -395,43 +470,68 @@ module Tk::BLT
class Trace < TkObject class Trace < TkObject
TraceID_TBL = TkCore::INTERP.create_table TraceID_TBL = TkCore::INTERP.create_table
TkCore::INTERP.init_ip_env{ TraceID_TBL.clear }
TkCore::INTERP.init_ip_env{
TraceID_TBL.mutex.synchronize{ TraceID_TBL.clear }
}
def self.id2obj(tree, id) def self.id2obj(tree, id)
tpath = tree.path tpath = tree.path
return id unless TraceID_TBL[tpath] TraceID_TBL.mutex.synchronize{
if TraceID_TBL[tpath]
if TraceID_TBL[tpath][id] if TraceID_TBL[tpath][id]
TraceID_TBL[tpath][id] TraceID_TBL[tpath][id]
else else
begin begin
self.new([tree, id]) # self.new([tree, id])
(obj = self.allocate).instance_eval{
@parent = @tree = tree
@tpath = @parent.path
@path = @id = node # == traceID
TraceID_TBL[@tpath] ||= {}
TraceID_TBL[@tpath][@id] = self
}
obj
rescue rescue
id id
end end
end end
else
id
end
}
end end
def self.new(tree, *args, &b) def self.new(tree, *args, &b)
TraceID_TBL.mutex.synchronize{
if tree.kind_of?(Array) if tree.kind_of?(Array)
# not create # not create
if obj = TraceID_TBL[tree[0].path][tree[1]] tpath = tree[0].path
return obj TraceID_TBL[tpath] ||= {}
else unless (obj = TraceID_TBL[tpath][tree[1]])
return super(false, tree[0], tree[1]) (TraceID_TBL[tpath][tree[1]] =
end obj = self.allocate).instance_eval{
end
super(true, tree, *args, &b)
end
def initialize(create, tree, node, key, opts, cmd=nil, &b)
@parent = @tree = tree @parent = @tree = tree
@tpath = @parent.path @tpath = @parent.path
@path = @id = tree[1] # == traceID
unless create }
@path = @id = node # == traceID
return
end end
return obj
end
# super(true, tree, *args, &b)
(obj = self.allocate).instance_eval{
initialize(tree, *args, &b)
TraceID_TBL[@tpath] ||= {}
TraceID_TBL[@tpath][@id] = self
}
return obj
}
end
def initialize(tree, node, key, opts, cmd=nil, &b)
@parent = @tree = tree
@tpath = @parent.path
if !cmd if !cmd
if b if b
@ -459,7 +559,9 @@ module Tk::BLT
def delete() def delete()
tk_call(@tpath, 'trace', 'delete', @id) tk_call(@tpath, 'trace', 'delete', @id)
TraceID_TBL.mutex.synchronize{
TraceID_TBL[tpath].delete(@id) TraceID_TBL[tpath].delete(@id)
}
self self
end end
@ -475,7 +577,12 @@ module Tk::BLT
################################### ###################################
TreeID_TBL = TkCore::INTERP.create_table TreeID_TBL = TkCore::INTERP.create_table
Tree_ID = ['blt_tree'.freeze, '00000'.taint].freeze
(Tree_ID = ['blt_tree'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
def __keyonly_optkeys def __keyonly_optkeys
{ {
@ -498,7 +605,9 @@ module Tk::BLT
end end
def self.id2obj(id) def self.id2obj(id)
TreeID_TBL.mutex.synchronize{
TreeID_TBL[id]? TreeID_TBL[id]: id TreeID_TBL[id]? TreeID_TBL[id]: id
}
end end
def self.names(pat = None) def self.names(pat = None)
@ -513,27 +622,45 @@ module Tk::BLT
end end
def self.new(name = nil) def self.new(name = nil)
return TreeID_TBL[name] if name && TreeID_TBL[name] TreeID_TBL.mutex.synchronize{
super(name) if name && TreeID_TBL[name]
TreeID_TBL[name]
else
(obj = self.allocate).instance_eval{
initialize(name)
TreeID_TBL[@id] = self
}
obj
end
}
end end
def initialzie(name = nil) def initialzie(name = nil)
if name if name
@path = @id = name @path = @id = name
else else
Tree_ID.mutex.synchronize{
@path = @id = Tree_ID.join(TkCore::INTERP._ip_id_) @path = @id = Tree_ID.join(TkCore::INTERP._ip_id_)
TreeID_TBL[@id] = self
Tree_ID[1].succ! Tree_ID[1].succ!
}
end end
TreeID_TBL[@id] = self
tk_call('::blt::tree', 'create', @id) tk_call('::blt::tree', 'create', @id)
end end
def __destroy_hook__ def __destroy_hook__
Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{
Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path) Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path)
}
Tk::BLT::Tree::Tag::TreeTagID_TBL.mutex.synchronize{
Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path) Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path)
}
Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{
Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path) Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path)
}
Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{
Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path) Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path)
}
end end
def tagid(tag) def tagid(tag)
@ -592,6 +719,7 @@ module Tk::BLT
def delete(*nodes) def delete(*nodes)
tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)})) tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)}))
Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{
nodes.each{|node| nodes.each{|node|
if node.kind_of?(Tk::BLT::Tree::Node) if node.kind_of?(Tk::BLT::Tree::Node)
Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id) Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id)
@ -599,6 +727,7 @@ module Tk::BLT
Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s) Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s)
end end
} }
}
self self
end end
@ -728,7 +857,9 @@ module Tk::BLT
id.delete id.delete
else else
tk_call(@path, 'notify', 'delete', id) tk_call(@path, 'notify', 'delete', id)
Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{
Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s) Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s)
}
end end
self self
end end
@ -835,7 +966,9 @@ module Tk::BLT
def tag_forget(tag) def tag_forget(tag)
tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag) tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag)
tk_call(@path, 'tag', 'forget', tag) tk_call(@path, 'tag', 'forget', tag)
TreeTagID_TBL.mutex.synchronize{
TreeTagID_TBL[@path].delete(tag) TreeTagID_TBL[@path].delete(tag)
}
self self
end end
@ -889,7 +1022,9 @@ module Tk::BLT
def trace_delete(*args) def trace_delete(*args)
args = args.collect{|id| tagid(id)} args = args.collect{|id| tagid(id)}
tk_call(@path, 'trace', 'delete', *args) tk_call(@path, 'trace', 'delete', *args)
Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{
args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)} args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)}
}
self self
end end

View file

@ -239,6 +239,22 @@ class Tk::BLT::Treeview
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL); _setup_subst_table(KEY_TBL, PROC_TBL);
def self.ret_val(val) def self.ret_val(val)
@ -273,8 +289,12 @@ class Tk::BLT::Treeview
######################## ########################
def __destroy_hook__ def __destroy_hook__
Tk::BLT::Treeview::Node::TreeNodeID_TBL.mutex.synchronize{
Tk::BLT::Treeview::Node::TreeNodeID_TBL.delete(@path) Tk::BLT::Treeview::Node::TreeNodeID_TBL.delete(@path)
}
Tk::BLT::Treeview::Tag::TreeTagID_TBL.mutex.synchronize{
Tk::BLT::Treeview::Tag::TreeTagID_TBL.delete(@path) Tk::BLT::Treeview::Tag::TreeTagID_TBL.delete(@path)
}
end end
def tagid(tag) def tagid(tag)
@ -472,6 +492,22 @@ class Tk::BLT::Treeview
nil nil
] ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL); _setup_subst_table(KEY_TBL, PROC_TBL);
def self.ret_val(val) def self.ret_val(val)
@ -967,22 +1003,47 @@ class Tk::BLT::Treeview::Node < TkObject
include Tk::BLT::Treeview::TagOrID_Methods include Tk::BLT::Treeview::TagOrID_Methods
TreeNodeID_TBL = TkCore::INTERP.create_table TreeNodeID_TBL = TkCore::INTERP.create_table
TreeNode_ID = ['blt_treeview_node'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TreeNodeID_TBL.clear } (TreeNode_ID = ['blt_treeview_node'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear }
}
def self.id2obj(tree, id) def self.id2obj(tree, id)
tpath = tree.path tpath = tree.path
return id unless TreeNodeID_TBL[tpath] TreeNodeID_TBL.mutex.synchronize{
if TreeNodeID_TBL[tpath]
if TreeNodeID_TBL[tpath][id] if TreeNodeID_TBL[tpath][id]
TreeNodeID_TBL[tpath][id] TreeNodeID_TBL[tpath][id]
else else
begin begin
self.new(tree, nil, nil, 'node'=>Integer(id)) # self.new(tree, nil, nil, 'node'=>Integer(id))
unless (tk_call(@tpath, 'get', id)).empty?
id = Integer(id)
(obj = self.allocate).instance_eval{
@parent = @tree = tree
@tpath = @parent.path
@path = @id = id
TreeNodeID_TBL[@tpath] ||= {}
TreeNodeID_TBL[@tpath][@id] = self
}
obj
else
id
end
rescue rescue
id id
end end
end end
else
id
end
}
end end
def self.new(tree, pos, parent=nil, keys={}) def self.new(tree, pos, parent=nil, keys={})
@ -994,13 +1055,21 @@ class Tk::BLT::Treeview::Node < TkObject
keys = _symbolkey2str(keys) keys = _symbolkey2str(keys)
tpath = tree.path tpath = tree.path
TreeNodeID_TBL.mutex.synchronize{
TreeNodeID_TBL[tpath] ||= {}
if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id]) if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id])
keys.delete('node') keys.delete('node')
tk_call(tree.path, 'move', id, pos, parent) if parent tk_call(tree.path, 'move', id, pos, parent) if parent
return obj return obj
end end
super(tree, pos, parent, keys) #super(tree, pos, parent, keys)
(obj = self.allocate).instance_eval{
initialize(tree, pos, parent, keys)
TreeNodeID_TBL[tpath][@id] = self
}
obj
}
end end
def initialize(tree, pos, parent, keys) def initialize(tree, pos, parent, keys)
@ -1008,11 +1077,18 @@ class Tk::BLT::Treeview::Node < TkObject
@tpath = @parent.path @tpath = @parent.path
if (id = keys['node']) if (id = keys['node'])
# if tk_call(@tpath, 'get', id).empty?
# fail RuntimeError, "not exist the node '#{id}'"
# end
@path = @id = id @path = @id = id
tk_call(@tpath, 'move', @id, pos, tagid(parent)) if parent tk_call(@tpath, 'move', @id, pos, tagid(parent)) if parent
configure(keys) if keys && ! keys.empty?
else else
name = nil
TreeNode_ID.mutex.synchronize{
name = TreeNode_ID.join(TkCore::INTERP._ip_id_).freeze name = TreeNode_ID.join(TkCore::INTERP._ip_id_).freeze
TreeNode_ID[1].succ! TreeNode_ID[1].succ!
}
at = keys.delete['at'] at = keys.delete['at']
@ -1035,9 +1111,6 @@ class Tk::BLT::Treeview::Node < TkObject
end end
@path = @id @path = @id
end end
TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath]
TreeNodeID_TBL[@tpath][@id] = self
end end
def id def id
@ -1051,37 +1124,66 @@ class Tk::BLT::Treeview::Tag < TkObject
include Tk::BLT::Treeview::TagOrID_Methods include Tk::BLT::Treeview::TagOrID_Methods
TreeTagID_TBL = TkCore::INTERP.create_table TreeTagID_TBL = TkCore::INTERP.create_table
TreeTag_ID = ['blt_treeview_tag'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TreeTagID_TBL.clear } (TreeTag_ID = ['blt_treeview_tag'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
def self.id2obj(tree, id) TkCore::INTERP.init_ip_env{
TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }
}
def self.id2obj(tree, name)
tpath = tree.path tpath = tree.path
return id unless TreeTagID_TBL[tpath] TreeTagID_TBL.mutex.synchronize{
if TreeTagID_TBL[tpath][id] if TreeTagID_TBL[tpath]
TreeTagID_TBL[tpath][id] if TreeTagID_TBL[tpath][name]
TreeTagID_TBL[tpath][name]
else
#self.new(tree, name)
(obj = self.allocate).instance_eval{
@parent = @tree = tree
@tpath = @parent.path
@path = @id = name
TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
TreeTagID_TBL[@tpath][@id] = self
}
obj
end
else else
begin
self.new(tree, nil, nil, 'name'=>Integer(id))
rescue
id id
end end
end }
end end
def self.new_by_name(tree, name, *ids) def self.new_by_name(tree, name, *ids)
if (obj = TreeTagID_TBL[tree.path][name]) TreeTagID_TBL.mutex.synchronize{
return obj unless (obj = TreeTagID_TBL[tree.path][name])
(obj = self.allocate).instance_eval{
initialize(tree, name, ids)
TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
TreeTagID_TBL[@tpath][@id] = self
}
end end
new([tree, name], ids) obj
}
end end
def self.new(tree, *ids) def self.new(tree, *ids)
TreeTagID_TBL.mutex.synchronize{
(obj = self.allocate).instance_eval{
if tree.kind_of?(Array) if tree.kind_of?(Array)
super(tree[0], tree[1], ids) initialize(tree[0], tree[1], ids)
else else
super(tree, nil, ids) initialize(tree, nil, ids)
end end
TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
TreeTagID_TBL[@tpath][@id] = self
}
obj
}
end end
def initialize(tree, name, ids) def initialize(tree, name, ids)
@ -1091,13 +1193,12 @@ class Tk::BLT::Treeview::Tag < TkObject
if name if name
@path = @id = name @path = @id = name
else else
TreeTag_ID.mutex.synchronize{
@path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_).freeze @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_).freeze
TreeTag_ID[1].succ! TreeTag_ID[1].succ!
}
end end
TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]
TreeTagID_TBL[@tpath][@id] = self
unless ids.empty? unless ids.empty?
tk_call(@tpath, 'tag', 'add', @id, *(ids.collect{|id| tagid(id)})) tk_call(@tpath, 'tag', 'add', @id, *(ids.collect{|id| tagid(id)}))
end end

View file

@ -23,7 +23,9 @@ module Tk::BLT
end end
def self.names(pat=None) def self.names(pat=None)
simplelist(tk_call('::blt::vector', 'names', pat)).collect{|name| list = simplelist(tk_call('::blt::vector', 'names', pat))
TkVar_ID_TBL.mutex.synchronize{
list.collect{|name|
if TkVar_ID_TBL[name] if TkVar_ID_TBL[name]
TkVar_ID_TBL[name] TkVar_ID_TBL[name]
elsif name[0..1] == '::' && TkVar_ID_TBL[name[2..-1]] elsif name[0..1] == '::' && TkVar_ID_TBL[name[2..-1]]
@ -32,6 +34,7 @@ module Tk::BLT
name name
end end
} }
}
end end
#################################### ####################################
@ -53,7 +56,9 @@ module Tk::BLT
"#auto", *hash_kv(keys)) "#auto", *hash_kv(keys))
end end
TkVar_ID_TBL.mutex.synchronize{
TkVar_ID_TBL[@id] = self TkVar_ID_TBL[@id] = self
}
@def_default = false @def_default = false
@default_val = nil @default_val = nil
@ -221,13 +226,21 @@ module Tk::BLT
class VectorAccess < Vector class VectorAccess < Vector
def self.new(name) def self.new(name)
return TkVar_ID_TBL[name] if TkVar_ID_TBL[name] TkVar_ID_TBL.mutex.synchronize{
super(name, size=nil, keys={}) if TkVar_ID_TBL[name]
TkVar_ID_TBL[name]
else
(obj = self.allocate).instance_eval{
initialize(name)
TkVar_ID_TBL[@id] = self
}
obj
end
}
end end
def initialize(vec_name) def initialize(vec_name)
@id = vec_name @id = vec_name
TkVar_ID_TBL[@id] = self
@def_default = false @def_default = false
@default_val = nil @default_val = nil

View file

@ -13,12 +13,24 @@ module Tk::BLT
TkCommandNames = ['::blt::watch'.freeze].freeze TkCommandNames = ['::blt::watch'.freeze].freeze
WATCH_ID_TBL = TkCore::INTERP.create_table WATCH_ID_TBL = TkCore::INTERP.create_table
BLT_WATCH_ID = ['blt_watch_id'.freeze, '00000'.taint].freeze
(BLT_WATCH_ID = ['blt_watch_id'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
WATCH_ID_TBL.mutex.synchronize{ WATCH_ID_TBL.clear }
}
def self.names(state = None) def self.names(state = None)
tk_split_list(tk_call('::blt::watch', 'names', state)).collect{|name| lst = tk_split_list(tk_call('::blt::watch', 'names', state))
WATCH_ID_TBL.mutex.synchronize{
lst.collect{|name|
WATCH_ID_TBL[name] || name WATCH_ID_TBL[name] || name
} }
}
end end
def __numval_optkeys def __numval_optkeys
@ -45,13 +57,17 @@ module Tk::BLT
if name if name
@id = name.to_s @id = name.to_s
else else
BLT_WATCH_ID.mutex.synchronize{
@id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_) @id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_)
BLT_WATCH_ID[1].succ! BLT_WATCH_ID[1].succ!
}
end end
@path = @id @path = @id
WATCH_ID_TBL.mutex.synchronize{
WATCH_ID_TBL[@id] = self WATCH_ID_TBL[@id] = self
}
tk_call('::blt::watch', 'create', @id, *hash_kv(keys)) tk_call('::blt::watch', 'create', @id, *hash_kv(keys))
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/bwidget.rb'
module Tk module Tk
module BWidget module BWidget
class Button < TkButton class Button < Tk::Button
end end
end end
end end

View file

@ -31,7 +31,7 @@ class Tk::BWidget::ButtonBox
name = tagOrId[:name] name = tagOrId[:name]
return index(name) unless name.empty? return index(name) unless name.empty?
end end
if tagOrId.kind_of?(TkButton) if tagOrId.kind_of?(Tk::Button)
return index(tagOrId[:text]) return index(tagOrId[:text])
end end
# index(tagOrId.to_s) # index(tagOrId.to_s)
@ -40,7 +40,13 @@ class Tk::BWidget::ButtonBox
def add(keys={}, &b) def add(keys={}, &b)
win = window(tk_send('add', *hash_kv(keys))) win = window(tk_send('add', *hash_kv(keys)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
@ -54,7 +60,7 @@ class Tk::BWidget::ButtonBox
name = idx[:name] name = idx[:name]
idx = name unless name.empty? idx = name unless name.empty?
end end
if idx.kind_of?(TkButton) if idx.kind_of?(Tk::Button)
idx = idx[:text] idx = idx[:text]
end end
number(tk_send('index', idx.to_s)) number(tk_send('index', idx.to_s))
@ -62,7 +68,13 @@ class Tk::BWidget::ButtonBox
def insert(idx, keys={}, &b) def insert(idx, keys={}, &b)
win = window(tk_send('insert', tagid(idx), *hash_kv(keys))) win = window(tk_send('insert', tagid(idx), *hash_kv(keys)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -25,7 +25,13 @@ class Tk::BWidget::ComboBox
def get_listbox(&b) def get_listbox(&b)
win = window(tk_send_without_enc('getlistbox')) win = window(tk_send_without_enc('getlistbox'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -103,7 +103,7 @@ class Tk::BWidget::Dialog
name = tagOrId[:name] name = tagOrId[:name]
return index(name) unless name.empty? return index(name) unless name.empty?
end end
if tagOrId.kind_of?(TkButton) if tagOrId.kind_of?(Tk::Button)
return index(tagOrId[:text]) return index(tagOrId[:text])
end end
# index(tagOrId.to_s) # index(tagOrId.to_s)
@ -112,19 +112,37 @@ class Tk::BWidget::Dialog
def add(keys={}, &b) def add(keys={}, &b)
win = window(tk_send('add', *hash_kv(keys))) win = window(tk_send('add', *hash_kv(keys)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def get_frame(&b) def get_frame(&b)
win = window(tk_send('getframe')) win = window(tk_send('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def get_buttonbox(&b) def get_buttonbox(&b)
win = window(@path + '.bbox') win = window(@path + '.bbox')
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/bwidget.rb'
module Tk module Tk
module BWidget module BWidget
class Entry < TkEntry class Entry < Tk::Entry
end end
end end
end end

View file

@ -9,7 +9,7 @@ require 'tkextlib/bwidget.rb'
module Tk module Tk
module BWidget module BWidget
class Label < TkLabel class Label < Tk::Label
end end
end end
end end

View file

@ -11,7 +11,7 @@ require 'tkextlib/bwidget/entry'
module Tk module Tk
module BWidget module BWidget
class LabelEntry < TkEntry class LabelEntry < Tk::Entry
end end
end end
end end

View file

@ -40,7 +40,13 @@ class Tk::BWidget::LabelFrame
end end
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
end end

View file

@ -211,14 +211,26 @@ class Tk::BWidget::ListBox::Item
include TkTreatTagFont include TkTreatTagFont
ListItem_TBL = TkCore::INTERP.create_table ListItem_TBL = TkCore::INTERP.create_table
ListItem_ID = ['bw:item'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ ListItem_TBL.clear } (ListItem_ID = ['bw:item'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
ListItem_TBL.mutex.synchronize{ ListItem_TBL.clear }
}
def self.id2obj(lbox, id) def self.id2obj(lbox, id)
lpath = lbox.path lpath = lbox.path
return id unless ListItem_TBL[lpath] ListItem_TBL.mutex.synchronize{
if ListItem_TBL[lpath]
ListItem_TBL[lpath][id]? ListItem_TBL[lpath][id]: id ListItem_TBL[lpath][id]? ListItem_TBL[lpath][id]: id
else
id
end
}
end end
def initialize(lbox, *args) def initialize(lbox, *args)
@ -250,13 +262,17 @@ class Tk::BWidget::ListBox::Item
if keys.key?('itemname') if keys.key?('itemname')
@path = @id = keys.delete('itemname') @path = @id = keys.delete('itemname')
else else
ListItem_ID.mutex.synchronize{
@path = @id = ListItem_ID.join(TkCore::INTERP._ip_id_) @path = @id = ListItem_ID.join(TkCore::INTERP._ip_id_)
ListItem_ID[1].succ! ListItem_ID[1].succ!
}
end end
ListItem_TBL.mutex.synchronize{
ListItem_TBL[@id] = self ListItem_TBL[@id] = self
ListItem_TBL[@lpath] = {} unless ListItem_TBL[@lpath] ListItem_TBL[@lpath] = {} unless ListItem_TBL[@lpath]
ListItem_TBL[@lpath][@id] = self ListItem_TBL[@lpath][@id] = self
}
@listbox.insert(index, @id, keys) @listbox.insert(index, @id, keys)
end end

View file

@ -41,37 +41,73 @@ class Tk::BWidget::MainFrame
def add_indicator(keys={}, &b) def add_indicator(keys={}, &b)
win = window(tk_send('addindicator', *hash_kv(keys))) win = window(tk_send('addindicator', *hash_kv(keys)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def add_toolbar(&b) def add_toolbar(&b)
win = window(tk_send('addtoolbar')) win = window(tk_send('addtoolbar'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def get_frame(&b) def get_frame(&b)
win = window(tk_send('getframe')) win = window(tk_send('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def get_indicator(idx, &b) def get_indicator(idx, &b)
win = window(tk_send('getindicator', idx)) win = window(tk_send('getindicator', idx))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def get_menu(menu_id, &b) def get_menu(menu_id, &b)
win = window(tk_send('getmenu', menu_id)) win = window(tk_send('getmenu', menu_id))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
def get_toolbar(idx, &b) def get_toolbar(idx, &b)
win = window(tk_send('gettoolbar', idx)) win = window(tk_send('gettoolbar', idx))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -173,6 +173,9 @@ class Tk::BWidget::MessageDlg
end end
def create def create
num_or_str(tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys))) # return the index of the pressed button, or nil if it is destroyed
ret = num_or_str(tk_call(self.class::TkCommandNames[0],
@path, *hash_kv(@keys)))
(ret < 0)? nil: ret
end end
end end

View file

@ -89,7 +89,13 @@ class Tk::BWidget::NoteBook
def add(page, &b) def add(page, &b)
win = window(tk_send('add', tagid(page))) win = window(tk_send('add', tagid(page)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
@ -105,7 +111,13 @@ class Tk::BWidget::NoteBook
def get_frame(page, &b) def get_frame(page, &b)
win = window(tk_send('getframe', tagid(page))) win = window(tk_send('getframe', tagid(page)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
@ -115,7 +127,13 @@ class Tk::BWidget::NoteBook
def insert(index, page, keys={}, &b) def insert(index, page, keys={}, &b)
win = window(tk_send('insert', index, tagid(page), *hash_kv(keys))) win = window(tk_send('insert', index, tagid(page), *hash_kv(keys)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -26,7 +26,13 @@ class Tk::BWidget::PagesManager
def add(page, &b) def add(page, &b)
win = window(tk_send('add', tagid(page))) win = window(tk_send('add', tagid(page)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
@ -42,7 +48,13 @@ class Tk::BWidget::PagesManager
def get_frame(page, &b) def get_frame(page, &b)
win = window(tk_send('getframe', tagid(page))) win = window(tk_send('getframe', tagid(page)))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -25,7 +25,13 @@ class Tk::BWidget::PanedWindow
def get_frame(idx, &b) def get_frame(idx, &b)
win = window(tk_send_without_enc('getframe', idx)) win = window(tk_send_without_enc('getframe', idx))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
end end

View file

@ -36,7 +36,13 @@ class Tk::BWidget::PanelFrame
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -51,4 +51,8 @@ class Tk::BWidget::ProgressDlg
def value= (val) def value= (val)
@keys['variable'].value = val @keys['variable'].value = val
end end
def create
window(tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys)))
end
end end

View file

@ -23,7 +23,13 @@ class Tk::BWidget::ScrollableFrame
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -21,7 +21,13 @@ class Tk::BWidget::ScrolledWindow
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -10,6 +10,11 @@ require 'tkextlib/bwidget/messagedlg'
module Tk module Tk
module BWidget module BWidget
class SelectColor < Tk::BWidget::MessageDlg class SelectColor < Tk::BWidget::MessageDlg
class Dialog < Tk::BWidget::SelectColor
end
class Menubutton < Tk::Menubutton
end
MenuButton = Menubutton
end end
end end
end end
@ -43,3 +48,26 @@ class Tk::BWidget::SelectColor
tk_call('SelectColor::setcolor', idx, color) tk_call('SelectColor::setcolor', idx, color)
end end
end end
class Tk::BWidget::SelectColor::Dialog
def create_self(keys)
super(keys)
@keys['type'] = 'dialog'
end
def create
@keys['type'] = 'dialog' # 'dialog' type returns color
tk_call(Tk::BWidget::SelectColor::TkCommandNames[0],
@path, *hash_kv(@keys))
end
end
class Tk::BWidget::SelectColor::Menubutton
def create_self(keys)
keys = {} unless keys
keys = _symbolkey2str(keys)
keys['type'] = 'menubutton' # 'toolbar' type returns widget path
window(tk_call(Tk::BWidget::SelectColor::TkCommandNames[0],
@path, *hash_kv(keys)))
end
end

View file

@ -66,7 +66,7 @@ class Tk::BWidget::SelectFont::Dialog
end end
def create def create
@keys['type'] = 'dialog' @keys['type'] = 'dialog' # 'dialog' type returns font name
tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], @path, *hash_kv(@keys)) tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], @path, *hash_kv(@keys))
end end
end end
@ -79,7 +79,8 @@ class Tk::BWidget::SelectFont::Toolbar
def create_self(keys) def create_self(keys)
keys = {} unless keys keys = {} unless keys
keys = _symbolkey2str(keys) keys = _symbolkey2str(keys)
keys['type'] = 'toolbar' keys['type'] = 'toolbar' # 'toolbar' type returns widget path
tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], @path, *hash_kv(keys)) window(tk_call(Tk::BWidget::SelectFont::TkCommandNames[0],
@path, *hash_kv(keys)))
end end
end end

View file

@ -10,7 +10,7 @@ require 'tkextlib/bwidget/entry'
module Tk module Tk
module BWidget module BWidget
class SpinBox < TkEntry class SpinBox < Tk::Entry
end end
end end
end end

View file

@ -36,7 +36,13 @@ class Tk::BWidget::StatusBar
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -21,7 +21,13 @@ class Tk::BWidget::TitleFrame
def get_frame(&b) def get_frame(&b)
win = window(tk_send_without_enc('getframe')) win = window(tk_send_without_enc('getframe'))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end
end end

View file

@ -263,14 +263,26 @@ class Tk::BWidget::Tree::Node
include TkTreatTagFont include TkTreatTagFont
TreeNode_TBL = TkCore::INTERP.create_table TreeNode_TBL = TkCore::INTERP.create_table
TreeNode_ID = ['bw:node'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TreeNode_TBL.clear } (TreeNode_ID = ['bw:node'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
TreeNode_TBL.mutex.synchronize{ TreeNode_TBL.clear }
}
def self.id2obj(tree, id) def self.id2obj(tree, id)
tpath = tree.path tpath = tree.path
return id unless TreeNode_TBL[tpath] TreeNode_TBL.mutex.synchronize{
if TreeNode_TBL[tpath]
TreeNode_TBL[tpath][id]? TreeNode_TBL[tpath][id]: id TreeNode_TBL[tpath][id]? TreeNode_TBL[tpath][id]: id
else
id
end
}
end end
def initialize(tree, *args) def initialize(tree, *args)
@ -311,13 +323,17 @@ class Tk::BWidget::Tree::Node
if keys.key?('nodename') if keys.key?('nodename')
@path = @id = keys.delete('nodename') @path = @id = keys.delete('nodename')
else else
TreeNode_ID.mutex.synchronize{
@path = @id = TreeNode_ID.join(TkCore::INTERP._ip_id_) @path = @id = TreeNode_ID.join(TkCore::INTERP._ip_id_)
TreeNode_ID[1].succ! TreeNode_ID[1].succ!
}
end end
TreeNode_TBL.mutex.synchronize{
TreeNode_TBL[@id] = self TreeNode_TBL[@id] = self
TreeNode_TBL[@tpath] = {} unless TreeNode_TBL[@tpath] TreeNode_TBL[@tpath] = {} unless TreeNode_TBL[@tpath]
TreeNode_TBL[@tpath][@id] = self TreeNode_TBL[@tpath][@id] = self
}
@tree.insert(index, parent, @id, keys) @tree.insert(index, parent, @id, keys)
end end

View file

@ -43,7 +43,13 @@ module Tk::BWidget::Widget
def self.create(klass, path, rename=None, &b) def self.create(klass, path, rename=None, &b)
win = window(tk_call('Widget::create', klass, path, rename)) win = window(tk_call('Widget::create', klass, path, rename))
win.instance_eval(&b) if b if b
if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!!
win.instance_exec(self, &b)
else
win.instance_eval(&b)
end
end
win win
end end

View file

@ -40,16 +40,22 @@ module Tk
class ItclObject < TkObject class ItclObject < TkObject
ITCL_CLASSNAME = ''.freeze ITCL_CLASSNAME = ''.freeze
ITCL_OBJ_ID = ['itclobj'.freeze, '00000'.taint].freeze (ITCL_OBJ_ID = ['itclobj'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
ITCL_OBJ_TBL = {}.taint ITCL_OBJ_TBL = {}.taint
def initialize(*args) def initialize(*args)
if (@klass = self.class::ITCL_CLASSNAME).empty? if (@klass = self.class::ITCL_CLASSNAME).empty?
fail RuntimeError, 'unknown itcl class (abstract class?)' fail RuntimeError, 'unknown itcl class (abstract class?)'
end end
Tk::Itcl::ItclObject::ITCL_OBJ_ID.mutex.synchronize{
@id = Tk::Itcl::ItclObject::TCL_OBJ_ID.join(TkCore::INTERP._ip_id_) @id = Tk::Itcl::ItclObject::TCL_OBJ_ID.join(TkCore::INTERP._ip_id_)
@path = @id
Tk::Itcl::ItclObject::ITCL_OBJ_ID[1].succ! Tk::Itcl::ItclObject::ITCL_OBJ_ID[1].succ!
}
@path = @id
end end
def self.call_proc(name, *args) def self.call_proc(name, *args)

View file

@ -145,9 +145,16 @@ module Tk
private :__config_cmd private :__config_cmd
ComponentID_TBL = TkCore::INTERP.create_table ComponentID_TBL = TkCore::INTERP.create_table
Itk_Component_ID = ['itk:component'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ ComponentID_TBL.clear } (Itk_Component_ID = ['itk:component'.freeze, '00000'.taint]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
TkCore::INTERP.init_ip_env{
ComponentID_TBL.mutex.synchronize{ ComponentID_TBL.clear }
}
def self.id2obj(master, id) def self.id2obj(master, id)
if master.kind_of?(TkObject) if master.kind_of?(TkObject)
@ -155,8 +162,13 @@ module Tk
else else
master = master.to_s master = master.to_s
end end
return id unless ComponentID_TBL.key?(master) ComponentID_TBL.mutex.synchronize{
(ComponentID_TBL.key?(id))? ComponentID_TBL[master][id]: id if ComponentID_TBL.key?(master)
(ComponentID_TBL[master].key?(id))? ComponentID_TBL[master][id]: id
else
id
end
}
end end
def self.new(master, component=nil) def self.new(master, component=nil)
@ -171,10 +183,13 @@ module Tk
elsif component elsif component
component = component.to_s component = component.to_s
else else
Itk_Component_ID.mutex.synchronize{
component = Itk_Component_ID.join(TkCore::INTERP._ip_id_) component = Itk_Component_ID.join(TkCore::INTERP._ip_id_)
Itk_Component_ID[1].succ! Itk_Component_ID[1].succ!
}
end end
ComponentID_TBL.mutex.synchronize{
if ComponentID_TBL.key?(master) if ComponentID_TBL.key?(master)
if ComponentID_TBL[master].key?(component) if ComponentID_TBL[master].key?(component)
return ComponentID_TBL[master][component] return ComponentID_TBL[master][component]
@ -182,6 +197,7 @@ module Tk
else else
ComponentID_TBL[master] = {} ComponentID_TBL[master] = {}
end end
}
super(master, component) super(master, component)
end end
@ -190,7 +206,9 @@ module Tk
@master = master @master = master
@component = component @component = component
ComponentID_TBL.mutex.synchronize{
ComponentID_TBL[@master][@component] = self ComponentID_TBL[@master][@component] = self
}
begin begin
@widget = window(tk_call(@master, 'component', @component)) @widget = window(tk_call(@master, 'component', @component))

View file

@ -45,6 +45,23 @@ class Tk::Iwidgets::Calendar
class ValidateArgs < TkUtil::CallbackSubst class ValidateArgs < TkUtil::CallbackSubst
KEY_TBL = [ [?d, ?s, :date], nil ] KEY_TBL = [ [?d, ?s, :date], nil ]
PROC_TBL = [ [?s, TkComm.method(:string) ], nil ] PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
KEY_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
end
inf
}
PROC_TBL.map!{|inf|
if inf.kind_of?(Array)
inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
end
inf
}
_setup_subst_table(KEY_TBL, PROC_TBL); _setup_subst_table(KEY_TBL, PROC_TBL);
def self.ret_val(val) def self.ret_val(val)

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