summaryrefslogtreecommitdiff
path: root/ext/tk/lib/tk
diff options
context:
space:
mode:
Diffstat (limited to 'ext/tk/lib/tk')
-rw-r--r--ext/tk/lib/tk/autoload.rb398
-rw-r--r--ext/tk/lib/tk/bindtag.rb2
-rw-r--r--ext/tk/lib/tk/busy.rb118
-rw-r--r--ext/tk/lib/tk/button.rb5
-rw-r--r--ext/tk/lib/tk/canvas.rb31
-rw-r--r--ext/tk/lib/tk/canvastag.rb29
-rw-r--r--ext/tk/lib/tk/checkbutton.rb8
-rw-r--r--ext/tk/lib/tk/composite.rb42
-rw-r--r--ext/tk/lib/tk/entry.rb5
-rw-r--r--ext/tk/lib/tk/event.rb22
-rw-r--r--ext/tk/lib/tk/font.rb15
-rw-r--r--ext/tk/lib/tk/fontchooser.rb166
-rw-r--r--ext/tk/lib/tk/frame.rb5
-rw-r--r--ext/tk/lib/tk/image.rb2
-rw-r--r--ext/tk/lib/tk/itemconfig.rb7
-rw-r--r--ext/tk/lib/tk/label.rb5
-rw-r--r--ext/tk/lib/tk/labelframe.rb6
-rw-r--r--ext/tk/lib/tk/listbox.rb6
-rw-r--r--ext/tk/lib/tk/macpkg.rb4
-rw-r--r--ext/tk/lib/tk/menu.rb59
-rw-r--r--ext/tk/lib/tk/menubar.rb24
-rw-r--r--ext/tk/lib/tk/menuspec.rb207
-rw-r--r--ext/tk/lib/tk/message.rb6
-rw-r--r--ext/tk/lib/tk/msgcat.rb2
-rw-r--r--ext/tk/lib/tk/namespace.rb2
-rw-r--r--ext/tk/lib/tk/optiondb.rb2
-rw-r--r--ext/tk/lib/tk/panedwindow.rb8
-rw-r--r--ext/tk/lib/tk/radiobutton.rb8
-rw-r--r--ext/tk/lib/tk/root.rb2
-rw-r--r--ext/tk/lib/tk/scale.rb5
-rw-r--r--ext/tk/lib/tk/scrollbar.rb14
-rw-r--r--ext/tk/lib/tk/spinbox.rb33
-rw-r--r--ext/tk/lib/tk/text.rb16
-rw-r--r--ext/tk/lib/tk/textmark.rb2
-rw-r--r--ext/tk/lib/tk/texttag.rb5
-rw-r--r--ext/tk/lib/tk/timer.rb4
-rw-r--r--ext/tk/lib/tk/toplevel.rb6
-rw-r--r--ext/tk/lib/tk/ttk_selector.rb34
-rw-r--r--ext/tk/lib/tk/variable.rb10
-rw-r--r--ext/tk/lib/tk/virtevent.rb2
-rw-r--r--ext/tk/lib/tk/winpkg.rb7
41 files changed, 1196 insertions, 138 deletions
diff --git a/ext/tk/lib/tk/autoload.rb b/ext/tk/lib/tk/autoload.rb
index df888eb927..2ebee9ea24 100644
--- a/ext/tk/lib/tk/autoload.rb
+++ b/ext/tk/lib/tk/autoload.rb
@@ -27,6 +27,8 @@ def TkPlace(*args); TkPlace.configure(*args); end
############################################
# classes on Tk module
module Tk
+ autoload :Busy, 'tk/busy'
+
autoload :Button, 'tk/button'
autoload :Canvas, 'tk/canvas'
@@ -319,9 +321,16 @@ module Tk
@TOPLEVEL_ALIAS_SETUP_PROC = {}
+ @AUTOLOAD_FILE_SYM_TABLE = Hash.new{|h,k| h[k]={}} # TABLE[file][sym] -> obj
+
@current_default_widget_set = nil
+
+ module TOPLEVEL_ALIASES; end
end
+class Object
+ include Tk::TOPLEVEL_ALIASES
+end
############################################
# methods to control default widget set
@@ -343,50 +352,387 @@ class << Tk
_replace_toplevel_aliases(target)
end
- def __set_toplevel_aliases__(target, obj, *symbols)
+ def widget_set_symbols
+ @TOPLEVEL_ALIAS_TABLE.keys
+ end
+
+ def toplevel_aliases_on_widget_set(widget_set)
+ if (tbl = @TOPLEVEL_ALIAS_TABLE[widget_set.to_sym])
+ tbl.collect{|k, v| (v.nil?)? nil: k}.compact
+ else
+ fail ArgumentError, "unknown widget_set #{widget_set.to_sym.inspect}"
+ end
+ end
+
+ def __toplevel_alias_setup_proc__(*target_list, &cmd)
+ target_list.each{|target| @TOPLEVEL_ALIAS_SETUP_PROC[target.to_sym] = cmd}
+ end
+
+ def topobj_defined?(sym) #=> alias_filename or object or false
+ Object.autoload?(sym) ||
+ (Object.const_defined?(sym) && Object.const_get(sym))
+ end
+ def topalias_defined?(sym) #=> alias_filename or object or false
+ Tk::TOPLEVEL_ALIASES.autoload?(sym) ||
+ (Tk::TOPLEVEL_ALIASES.const_defined?(sym) &&
+ Tk::TOPLEVEL_ALIASES.const_get(sym))
+ end
+ def define_topobj(sym, obj)
+ if obj.kind_of? String
+ # obj is an autoload path
+ Object.autoload(sym, obj)
+ unless Object.autoload?(sym)
+ # file is autoloaded?
+ if @AUTOLOAD_FILE_SYM_TABLE.has_key?(obj) &&
+ (loaded_obj = @AUTOLOAD_FILE_SYM_TABLE[obj][sym])
+ Object.const_set(sym, loaded_obj)
+ else
+ fail ArgumentError, "cannot define autoload file (already loaded?)"
+ end
+ end
+ else
+ # object
+ Object.const_set(sym, obj)
+ end
+ end
+ def define_topalias(sym, obj)
+ if obj.kind_of? String
+ # obj is an autoload path
+ Tk::TOPLEVEL_ALIASES.autoload(sym, obj)
+ unless Tk::TOPLEVEL_ALIASES.autoload?(sym)
+ # file is autoloaded?
+ if @AUTOLOAD_FILE_SYM_TABLE.has_key?(obj) &&
+ (loaded_obj = @AUTOLOAD_FILE_SYM_TABLE[obj][sym])
+ Tk::TOPLEVEL_ALIASES.const_set(sym, loaded_obj)
+ else
+ fail ArgumentError, "cannot define autoload file (already loaded?)"
+ end
+ end
+ else
+ # object
+ Tk::TOPLEVEL_ALIASES.const_set(sym, obj)
+ end
+ end
+ def replace_topobj(sym, obj) #=> old_obj (alias_filename or object) or nil
+ if old_obj = topobj_defined?(sym)
+ Object.class_eval{remove_const sym} rescue nil # ignore err
+ end
+ define_topobj(sym, obj)
+ old_obj
+ end
+ def replace_topalias(sym, obj) #=> old_obj (alias_filename or object) or nil
+ if old_obj = topalias_defined?(sym)
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} rescue nil #ignore err
+ end
+ define_topalias(sym, obj)
+ old_obj
+ end
+ private :topobj_defined?, :topalias_defined?
+ private :define_topobj, :define_topalias
+ private :replace_topobj, :replace_topalias
+
+ def __regist_toplevel_aliases__(target, obj, *symbols)
+ # initial regist
@TOPLEVEL_ALIAS_TABLE[target = target.to_sym] ||= {}
symbols.each{|sym|
@TOPLEVEL_ALIAS_TABLE[target][sym = sym.to_sym] = obj
- # if @current_default_widget_set == target
- if @TOPLEVEL_ALIAS_OWNER[sym] == target
- Object.class_eval{remove_const sym} if Object.const_defined?(sym)
- Object.const_set(sym, obj)
+ if !topalias_defined?(sym) || target == @current_default_widget_set
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj) unless obj.kind_of?(String) # NOT autoload
end
}
end
- ###################################
- private
- def _replace_toplevel_aliases(target)
- # check already autoloaded
- if (table = @TOPLEVEL_ALIAS_TABLE[current = @current_default_widget_set])
- table.each{|sym, file|
- if !Object.autoload?(sym) && Object.const_defined?(sym) &&
- @TOPLEVEL_ALIAS_TABLE[current][sym].kind_of?(String)
- # autoload -> class
- @TOPLEVEL_ALIAS_TABLE[current][sym] = Object.const_get(sym)
+ def regist_sym_for_loaded_file(auto, obj, sym)
+ @AUTOLOAD_FILE_SYM_TABLE[auto][sym] = obj
+
+ reg = /^#{Regexp.quote(auto)}(\.rb|\.so|)$/
+ @TOPLEVEL_ALIAS_TABLE.each_key{|set|
+ if @TOPLEVEL_ALIAS_TABLE[set][sym] =~ reg
+ @TOPLEVEL_ALIAS_TABLE[set][sym] = obj
+ if @TOPLEVEL_ALIAS_OWNER[sym].nil? || @TOPLEVEL_ALIAS_OWNER[sym] == set
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj) if set == @current_default_widget_set
end
- }
+ end
+ }
+ if (f = Object.autoload?(sym)) && f =~ reg
+ replace_topobj(sym, obj)
end
+ if (f = Tk::TOPLEVEL_ALIASES.autoload?(sym)) && f =~ reg
+ replace_topalias(sym, obj)
+ end
+ end
+ private :regist_sym_for_loaded_file
+
+ def set_topalias(target, obj, sym)
+ # obj is a kind of String : define autoload path
+ # Class : use the class object
+ if target == @current_default_widget_set
+ case @TOPLEVEL_ALIAS_OWNER[sym]
+ when false
+ # Object::sym is out of control. --> not change
+ # Make ALIAS::sym under control, because target widget set is current.
+ # Keep OWNER[sym]
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+
+ when target
+ if current_obj = topobj_defined?(sym)
+ if current_obj == obj
+ # Make current_obj under control.
+ # Keep Object::sym.
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+
+ else # current_obj != obj
+ if current_obj == topalias_defined?(sym)
+ # Change controlled object
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+
+ else # current_obj != topalias_defined?(sym)
+ # Maybe current_obj is defined by user. --> OWNER[sym] = faise
+ # Keep Object::sym.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ end
+ end
+
+ else # NOT topobj_defined?(sym)
+ # New definition for sym at target.
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ define_topobj(sym, obj)
+ end
+
+ when nil
+ # New definition for sym at target.
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+
+ else # others
+ # Maybe planning to make sym under control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+ end
+
+ else # target != @current_default_widget_set
+ case @TOPLEVEL_ALIAS_OWNER[sym]
+ when false
+ # Object::sym is out of control. --> not change
+ if topalias_defined?(sym)
+ # ALIAS[sym] may be defined by other widget set.
+ # Keep Object::sym (even if it is not defined)
+ # Keep ALIAS[sym].
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+
+ else # NOT topalias_defined?(sym)
+ # Nobody controls ALIAS[sym].
+ # At leaset, current widget set doesn't control ALIAS[sym].
+ # Keep Object::sym (even if it is not defined)
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ define_topalias(sym, obj)
+ end
+
+ when target
+ # Maybe change controlled object, because Object::sym is under control.
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+
+ when nil
+ # New definition for sym
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+
+ else # others
+ # An other widget set controls sym.
+ # Keep Object::sym (even if it is not defined)
+ # Keep ALIAS[sym].
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+
+ end
+ end
+
+ sym
+ end
+ private :set_topalias
- # 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)
+ def __set_toplevel_aliases__(target, obj, *symbols)
+ # obj is a kind of String : define autoload path
+ # Class : use the class object
+ target = target.to_sym
+ symbols.each{|sym| set_topalias(target, obj, sym.to_sym)}
+ end
+
+ def __set_loaded_toplevel_aliases__(autopath, target, obj, *symbols)
+ # autopath is an autoload file
+ # Currently, this method doesn't support that autoload loads
+ # different toplevels between <basename>.rb and <basename>.so extension.
+ shortpath = (autopath =~ /^(.*)(.rb|.so)$/)? $1: autopath
+ target = target.to_sym
+ symbols.map!{|sym| sym.to_sym}
+
+ symbols.each{|sym| regist_sym_for_loaded_file(shortpath, obj, sym) }
+ symbols.each{|sym| set_topalias(target, obj, sym)}
+ end
+
+ def backup_current_topdef(sym)
+ return if (current = @current_default_widget_set).nil?
+
+ case @TOPLEVEL_ALIAS_OWNER[sym]
+ when false
+ # Object::sym is out of control.
+ if (cur_alias = topalias_defined?(sym)) && ! cur_alias.kind_of?(String)
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
+ end
+
+ when current
+ if cur_obj = topobj_defined?(sym)
+ if ! cur_obj.kind_of?(String) && (cur_alias = topalias_defined?(sym))
+ if cur_alias.kind_of?(String)
+ # Mayby, user replaced Object::sym.
+ # Make Object::sym out of control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ elsif cur_obj == cur_alias
+ # Possibley, defined normally. Backup it
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
+ else
+ # Mayby, user replaced Object::sym.
+ # Make Object::sym out of control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ end
+ end
+ else
+ # Mayby, user replaced Object::sym.
+ # Make Object::sym out of control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ end
+
+ when nil
+ # Object::sym is out of control.
+ if (cur_alias = topalias_defined?(sym)) && ! cur_alias.kind_of?(String)
+ # Possibley, defined normally. Backup it.
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
+ end
+ else
+ # No authority to control Object::sym and ALIASES::sym.
+ # Do nothing.
+ end
+ end
+ private :backup_current_topdef
+
+ def _replace_toplevel_aliases(target)
+ # backup
+ @TOPLEVEL_ALIAS_TABLE[target].each_key{|sym|
+ backup_current_topdef(sym)
+ }
+
+ # replace
+ @TOPLEVEL_ALIAS_TABLE[target].each_key{|sym|
+ next if (obj = @TOPLEVEL_ALIAS_TABLE[target][sym]).nil?
+ if @TOPLEVEL_ALIAS_OWNER[sym] == false
+ # Object::sym is out of control. --> not change
+ # Keep OWNER[sym].
+ replace_topalias(sym, obj)
else
- # file => loaded class object
- Object.const_set(sym, file)
+ # New definition
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
end
- @TOPLEVEL_ALIAS_OWNER[sym] = target
}
- # update current alias
+ # change default_widget_set
@current_default_widget_set = target
end
+ private :_replace_toplevel_aliases
+
+ def __import_toplevel_aliases__(target, *symbols)
+ current = @current_default_widget_set
+ symbols.each{|sym|
+ sym = sym.to_sym
+ if (obj = @TOPLEVEL_ALIAS_TABLE[target][sym]).nil?
+ # remove
+ @TOPLEVEL_ALIAS_TABLE[current].delete(sym)
+ @TOPLEVEL_ALIAS_OWNER.delete(sym)
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
+ Object.class_eval{remove_const sym} if topobj_defined?(sym)
+
+ elsif obj == false
+ # remove, but OWNER[sym] <- false and not treat Object::sym
+ @TOPLEVEL_ALIAS_TABLE[current].delete(sym)
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
+
+ elsif @TOPLEVEL_ALIAS_OWNER[sym] == false
+ # Object::sym is out of control. --> not change
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = obj
+ replace_topalias(sym, obj)
+
+ else
+ # new definition under control
+ @TOPLEVEL_ALIAS_OWNER[sym] = current
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+ end
+ }
+ end
+
+ def __remove_toplevel_aliases__(*symbols)
+ # remove toplevel aliases of current widget set
+ current = @current_default_widget_set
+ symbols.each{|sym|
+ sym = sym.to_sym
+ @TOPLEVEL_ALIAS_TABLE[current].delete(sym)
+ @TOPLEVEL_ALIAS_OWNER.delete(sym)
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
+ Object.class_eval{remove_const sym} if topobj_defined?(sym)
+ }
+ end
+
+ def __reset_toplevel_owner__(*symbols)
+ symbols.each{|sym| @TOPLEVEL_ALIAS_OWNER.delete(sym.to_sym)}
+ end
+
+ def __disable_toplevel_control__(*symbols)
+ symbols.each{|sym| @TOPLEVEL_ALIAS_OWNER[sym.to_sym] = false}
+ end
+
+ def __create_widget_set__(new_set, src_set={})
+ new_set = new_set.to_sym
+ if @TOPLEVEL_ALIAS_TABLE[new_set]
+ fail RuntimeError, "A widget-set #{new_set.inspect} is already exist."
+ end
+ if src_set.kind_of?(Symbol)
+ # new_set is an alias name of existed widget set.
+ @TOPLEVEL_ALIAS_TABLE[new_set] = @TOPLEVEL_ALIAS_TABLE[src_set]
+ else
+ @TOPLEVEL_ALIAS_TABLE[new_set] = {}
+ src_set.each{|sym, obj| set_topalias(new_set, obj, sym.to_sym) }
+ end
+ end
end
+
############################################
# setup default widget set => :Tk
Tk.default_widget_set = :Tk
diff --git a/ext/tk/lib/tk/bindtag.rb b/ext/tk/lib/tk/bindtag.rb
index 88c8367a88..23b4e0b7c3 100644
--- a/ext/tk/lib/tk/bindtag.rb
+++ b/ext/tk/lib/tk/bindtag.rb
@@ -9,7 +9,7 @@ class TkBindTag
#BTagID_TBL = {}
BTagID_TBL = TkCore::INTERP.create_table
- (Tk_BINDTAG_ID = ["btag".freeze, "00000".taint]).instance_eval{
+ (Tk_BINDTAG_ID = ["btag".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/busy.rb b/ext/tk/lib/tk/busy.rb
new file mode 100644
index 0000000000..7f4f89f524
--- /dev/null
+++ b/ext/tk/lib/tk/busy.rb
@@ -0,0 +1,118 @@
+#
+# tk/busy.rb: support 'tk busy' command (Tcl/Tk8.6 or later)
+#
+require 'tk'
+
+module Tk::Busy
+ include TkCore
+ extend TkCore
+ extend TkItemConfigMethod
+end
+
+class << Tk::Busy
+ def __item_cget_cmd(win)
+ # maybe need to override
+ ['tk', 'busy', 'cget', win.path]
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(win)
+ # maybe need to override
+ ['tk', 'busy', 'configure', win.path]
+ end
+ private :__item_config_cmd
+
+ def __item_confinfo_cmd(win)
+ # maybe need to override
+ __item_config_cmd(win)
+ end
+ private :__item_confinfo_cmd
+
+ alias cget_tkstring itemcget_tkstring
+ alias cget itemcget
+ alias cget_strict itemcget_strict
+ alias configure itemconfigure
+ alias configinfo itemconfiginfo
+ alias current_configinfo current_itemconfiginfo
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ def method_missing(id, *args)
+ name = id.id2name
+ case args.length
+ when 1
+ if name[-1] == ?=
+ configure name[0..-2], args[0]
+ args[0]
+ else
+ configure name, args[0]
+ self
+ end
+ when 0
+ begin
+ cget(name)
+ rescue
+ super(id, *args)
+ end
+ else
+ super(id, *args)
+ end
+ end
+
+ def hold(win, keys={})
+ tk_call_without_enc('tk', 'busy', 'hold', win, *hash_kv(keys))
+ win
+ end
+
+ def forget(*wins)
+ tk_call_without_enc('tk', 'busy', 'forget', *wins)
+ self
+ end
+
+ def current(pat=None)
+ list(tk_call('tk', 'busy', 'current', pat))
+ end
+
+ def status(win)
+ bool(tk_call_without_enc('tk', 'busy', 'status', win))
+ end
+end
+
+module Tk::Busy
+ def busy_configinfo(option=nil)
+ Tk::Busy.configinfo(self, option)
+ end
+
+ def busy_current_configinfo(option=nil)
+ Tk::Busy.current_configinfo(self, option)
+ end
+
+ def busy_configure(option, value=None)
+ Tk::Busy.configure(self, option, value)
+ self
+ end
+
+ def busy_cget(option)
+ Tk::Busy.configure(self, option)
+ end
+
+ def busy(keys={})
+ Tk::Busy.hold(self, keys)
+ self
+ end
+ alias busy_hold busy
+
+ def busy_forget
+ Tk::Busy.forget(self)
+ self
+ end
+
+ def busy_current?
+ ! Tk::Busy.current(self.path).empty?
+ end
+
+ def busy_status
+ Tk::Busy.status(self)
+ end
+end
diff --git a/ext/tk/lib/tk/button.rb b/ext/tk/lib/tk/button.rb
index 770a5785bb..65233c91b6 100644
--- a/ext/tk/lib/tk/button.rb
+++ b/ext/tk/lib/tk/button.rb
@@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Button<Tk::Label
TkCommandNames = ['button'.freeze].freeze
WidgetClassName = 'Button'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('button', @path, *hash_kv(keys, true))
@@ -27,4 +27,5 @@ class Tk::Button<Tk::Label
end
#TkButton = Tk::Button unless Object.const_defined? :TkButton
-Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)
+Tk.__set_loaded_toplevel_aliases__('tk/button.rb', :Tk, Tk::Button, :TkButton)
diff --git a/ext/tk/lib/tk/canvas.rb b/ext/tk/lib/tk/canvas.rb
index b05a619939..1e24c0be97 100644
--- a/ext/tk/lib/tk/canvas.rb
+++ b/ext/tk/lib/tk/canvas.rb
@@ -45,7 +45,7 @@ class Tk::Canvas<TkWindow
TkCommandNames = ['canvas'.freeze].freeze
WidgetClassName = 'Canvas'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
TkcItem::CItemID_TBL.delete(@path)
@@ -265,6 +265,12 @@ class Tk::Canvas<TkWindow
self
end
+ def imove(tagOrId, idx, x, y)
+ tk_send_without_enc('imove', tagid(tagOrId), idx, x, y)
+ self
+ end
+ alias i_move imove
+
def index(tagOrId, idx)
number(tk_send_without_enc('index', tagid(tagOrId), idx))
end
@@ -523,11 +529,18 @@ class Tk::Canvas<TkWindow
self
end
- def move(tag, x, y)
- tk_send_without_enc('move', tagid(tag), x, y)
+ def move(tag, dx, dy)
+ tk_send_without_enc('move', tagid(tag), dx, dy)
self
end
+ def moveto(tag, x, y)
+ # Tcl/Tk 8.6 or later
+ tk_send_without_enc('moveto', tagid(tag), x, y)
+ self
+ end
+ alias move_to moveto
+
def postscript(keys)
tk_send("postscript", *hash_kv(keys))
end
@@ -541,6 +554,15 @@ class Tk::Canvas<TkWindow
self
end
+ def rchars(tag, first, last, str_or_coords)
+ # Tcl/Tk 8.6 or later
+ str_or_coords = str_or_coords.flatten if str_or_coords.kinad_of? Array
+ tk_send_without_enc('rchars', tagid(tag), first, last, str_or_coords)
+ self
+ end
+ alias replace_chars rchars
+ alias replace_coords rchars
+
def scale(tag, x, y, xs, ys)
tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)
self
@@ -581,7 +603,8 @@ class Tk::Canvas<TkWindow
end
#TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas
-Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
+Tk.__set_loaded_toplevel_aliases__('tk/canvas.rb', :Tk, Tk::Canvas, :TkCanvas)
class TkcItem<TkObject
diff --git a/ext/tk/lib/tk/canvastag.rb b/ext/tk/lib/tk/canvastag.rb
index 4e57a159bf..495d92a9a8 100644
--- a/ext/tk/lib/tk/canvastag.rb
+++ b/ext/tk/lib/tk/canvastag.rb
@@ -60,6 +60,9 @@ module TkcTagAccess
@c.itembindinfo(@id, seq)
end
+ def cget_tkstring(option)
+ @c.itemcget_tkstring(@id, option)
+ end
def cget(option)
@c.itemcget(@id, option)
end
@@ -116,6 +119,13 @@ module TkcTagAccess
self
end
+ def imove(idx, x, y)
+ # Tcl/Tk 8.6 or later
+ @c.imove(@id, idx, x, y)
+ self
+ end
+ alias i_move imove
+
def index(idx)
@c.index(@id, idx)
end
@@ -135,6 +145,13 @@ module TkcTagAccess
self
end
+ def moveto(x, y)
+ # Tcl/Tk 8.6 or later
+ @c.moveto(@id, x, y)
+ self
+ end
+ alias move_to moveto
+
def raise(abovethis=None)
@c.raise(@id, abovethis)
self
@@ -145,6 +162,14 @@ module TkcTagAccess
self
end
+ def rchars(first, last, str_or_coords)
+ # Tcl/Tk 8.6 or later
+ @c.rchars(@id, first, last, str_or_coords)
+ self
+ end
+ alias replace_chars rchars
+ alias replace_coords rchars
+
def select_adjust(index)
@c.select('adjust', @id, index)
self
@@ -203,7 +228,7 @@ class TkcTag<TkObject
CTagID_TBL = TkCore::INTERP.create_table
- (Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint]).instance_eval{
+ (Tk_CanvasTag_ID = ['ctag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -389,7 +414,7 @@ class TkcTagCurrent<TkcTagString
end
class TkcGroup<TkcTag
- (Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint]).instance_eval{
+ (Tk_cGroup_ID = ['tkcg'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/checkbutton.rb b/ext/tk/lib/tk/checkbutton.rb
index c1c4905c5e..b7449541c5 100644
--- a/ext/tk/lib/tk/checkbutton.rb
+++ b/ext/tk/lib/tk/checkbutton.rb
@@ -7,7 +7,7 @@ require 'tk/radiobutton'
class Tk::CheckButton<Tk::RadioButton
TkCommandNames = ['checkbutton'.freeze].freeze
WidgetClassName = 'Checkbutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true))
@@ -26,5 +26,7 @@ end
Tk::Checkbutton = Tk::CheckButton
#TkCheckButton = Tk::CheckButton unless Object.const_defined? :TkCheckButton
#TkCheckbutton = Tk::Checkbutton unless Object.const_defined? :TkCheckbutton
-Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton,
- :TkCheckButton, :TkCheckbutton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton,
+# :TkCheckButton, :TkCheckbutton)
+Tk.__set_loaded_toplevel_aliases__('tk/checkbutton.rb', :Tk, Tk::CheckButton,
+ :TkCheckButton, :TkCheckbutton)
diff --git a/ext/tk/lib/tk/composite.rb b/ext/tk/lib/tk/composite.rb
index 9a4aafda18..e267c7a22b 100644
--- a/ext/tk/lib/tk/composite.rb
+++ b/ext/tk/lib/tk/composite.rb
@@ -145,16 +145,34 @@ module TkComposite
str.chop << ' @epath=' << @epath.inspect << '>'
end
+ def _get_opt_method_list(arg)
+ m_set, m_cget, m_info = arg
+ m_set = m_set.to_s
+ m_cget = m_set if !m_cget && self.method(m_set).arity == -1
+ m_cget = m_cget.to_s if m_cget
+ m_info = m_info.to_s if m_info
+ [m_set, m_cget, m_info]
+ end
+ private :_get_opt_method_list
+
def option_methods(*opts)
- opts.each{|m_set, m_cget, m_info|
- m_set = m_set.to_s
- m_cget = m_set if !m_cget && self.method(m_set).arity == -1
- m_cget = m_cget.to_s if m_cget
- m_info = m_info.to_s if m_info
- @option_methods[m_set] = {
- :set => m_set, :cget => m_cget, :info => m_info
+ if opts.size == 1 && opts[0].kind_of?(Hash)
+ # {name => [m_set, m_cget, m_info], name => method} style
+ opts[0].each{|name, arg|
+ m_set, m_cget, m_info = _get_opt_method_list(arg)
+ @option_methods[name.to_s] = {
+ :set => m_set, :cget => m_cget, :info => m_info
+ }
}
- }
+ else
+ # [m_set, m_cget, m_info] or method style
+ opts.each{|arg|
+ m_set, m_cget, m_info = _get_opt_method_list(arg)
+ @option_methods[m_set] = {
+ :set => m_set, :cget => m_cget, :info => m_info
+ }
+ }
+ end
end
def delegate_alias(alias_opt, option, *wins)
@@ -215,6 +233,14 @@ module TkComposite
end
private :__cget_delegates
+ def cget_tkstring(slot)
+ if (ret = __cget_delegates(slot)) == None
+ super(slot)
+ else
+ _get_eval_string(ret)
+ end
+ end
+
def cget(slot)
if (ret = __cget_delegates(slot)) == None
super(slot)
diff --git a/ext/tk/lib/tk/entry.rb b/ext/tk/lib/tk/entry.rb
index 8ce8def1e7..d4aa03f2b6 100644
--- a/ext/tk/lib/tk/entry.rb
+++ b/ext/tk/lib/tk/entry.rb
@@ -13,7 +13,7 @@ class Tk::Entry<Tk::Label
TkCommandNames = ['entry'.freeze].freeze
WidgetClassName = 'Entry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# super(__conv_vcmd_on_hash_kv(keys))
@@ -116,4 +116,5 @@ class Tk::Entry<Tk::Label
end
#TkEntry = Tk::Entry unless Object.const_defined? :TkEntry
-Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)
+Tk.__set_loaded_toplevel_aliases__('tk/entry.rb', :Tk, Tk::Entry, :TkEntry)
diff --git a/ext/tk/lib/tk/event.rb b/ext/tk/lib/tk/event.rb
index d07b3b5a85..bf4e122322 100644
--- a/ext/tk/lib/tk/event.rb
+++ b/ext/tk/lib/tk/event.rb
@@ -8,7 +8,7 @@ end
########################
require 'tkutil'
-require 'tk'
+require 'tk' unless Object.const_defined? :TkComm
########################
@@ -482,6 +482,26 @@ module TkEvent
end
})
end
+ elsif cmd.respond_to?(:arity) && cmd.arity == 0 # args.size == 0
+ args = ''
+ if cmd.kind_of?(String)
+ id = cmd
+ elsif cmd.kind_of?(TkCallbackEntry)
+ id = install_cmd(cmd)
+ else
+ id = install_cmd(proc{
+ begin
+ TkUtil.eval_cmd(cmd)
+ rescue Exception=>e
+ if TkCore::INTERP.kind_of?(TclTkIp)
+ fail e
+ else
+ # MultiTkIp
+ fail Exception, "#{e.class}: #{e.message.dup}"
+ end
+ end
+ })
+ end
else
keys, args = klass._get_all_subst_keys
diff --git a/ext/tk/lib/tk/font.rb b/ext/tk/lib/tk/font.rb
index da6482c122..03db850f96 100644
--- a/ext/tk/lib/tk/font.rb
+++ b/ext/tk/lib/tk/font.rb
@@ -11,7 +11,7 @@ class TkFont
TkCommandNames = ['font'.freeze].freeze
- (Tk_FontID = ["@font".freeze, "00000".taint]).instance_eval{
+ (Tk_FontID = ["@font".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -211,7 +211,7 @@ class TkFont
end
end
def TkFont.actual_hash(fnt, option=nil)
- Hash[TkFont.actual_hash(fnt, option)]
+ Hash[TkFont.actual(fnt, option)]
end
def TkFont.actual_displayof(fnt, win, option=nil)
@@ -224,7 +224,7 @@ class TkFont
end
end
def TkFont.actual_hash_displayof(fnt, option=nil)
- Hash[TkFont.actual_hash_displayof(fnt, option)]
+ Hash[TkFont.actual_displayof(fnt, option)]
end
def TkFont.configure(fnt, slot, value=None)
@@ -2199,7 +2199,7 @@ module TkFont::CoreMethods
alias measure_core measure_core_tk4x
alias metrics_core metrics_core_tk4x
- when /^8\.[0-5]/
+ when /^8\.[0-9]/
alias actual_core actual_core_tk8x
alias configure_core configure_core_tk8x
alias configinfo_core configinfo_core_tk8x
@@ -2342,3 +2342,10 @@ if Tk::TCL_MAJOR_VERSION > 8 ||
'systemDetailSystemFont', 'systemDetailEmphasizedSystemFont'
]
end
+
+#######################################
+# autoload
+#######################################
+class TkFont
+ autoload :Chooser, 'tk/fontchooser'
+end
diff --git a/ext/tk/lib/tk/fontchooser.rb b/ext/tk/lib/tk/fontchooser.rb
new file mode 100644
index 0000000000..f9f816be59
--- /dev/null
+++ b/ext/tk/lib/tk/fontchooser.rb
@@ -0,0 +1,166 @@
+#
+# tk/fontchooser.rb -- "tk fontchooser" support (Tcl/Tk8.6 or later)
+#
+require 'tk'
+require 'tk/font'
+
+module TkFont::Chooser
+ extend TkCore
+end
+
+class << TkFont::Chooser
+ def method_missing(id, *args)
+ name = id.id2name
+ case args.length
+ when 1
+ if name[-1] == ?=
+ configure name[0..-2], args[0]
+ args[0]
+ else
+ configure name, args[0]
+ self
+ end
+ when 0
+ begin
+ cget(name)
+ rescue
+ super(id, *args)
+ end
+ else
+ super(id, *args)
+ end
+ end
+
+ def __conviginfo_value(key, val)
+ case key
+ when 'parent'
+ window(val)
+ when 'title'
+ val
+ when 'font'
+ if (lst = tk_split_simplelist(val)).size == 1
+ lst[0]
+ else
+ lst.map{|elem| num_or_str(elem)}
+ end
+ when 'command'
+ tk_tcl2ruby(val)
+ when 'visible'
+ bool(val)
+ else # unkown
+ val
+ end
+ end
+ private :__conviginfo_value
+
+ def configinfo(option=nil)
+ if !option && TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
+ lst = tk_split_simplelist(tk_call('tk', 'fontchooser', 'configure'))
+ ret = []
+ TkComm.slice_ary(lst, 2){|k, v|
+ k = k[1..-1]
+ ret << [k, __conviginfo_value(k, v)]
+ }
+ ret
+ else
+ current_configinfo(option)
+ end
+ end
+
+ def current_configinfo(option=nil)
+ if option
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.empty?
+ __conviginfo_value(option.to_s, tk_call('tk','fontchooser',
+ 'configure',"-#{opt}"))
+ else
+ lst = tk_split_simplelist(tk_call('tk', 'fontchooser', 'configure'))
+ ret = {}
+ TkComm.slice_ary(lst, 2){|k, v|
+ k = k[1..-1]
+ ret[k] = __conviginfo_value(k, v)
+ }
+ ret
+ end
+ end
+
+ def configure(option, value=None)
+ if option.kind_of? Hash
+ tk_call('tk', 'fontchooser', 'configure',
+ *hash_kv(_symbolkey2str(option)))
+ else
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.empty?
+ tk_call('tk', 'fontchooser', 'configure', "-#{opt}", value)
+ end
+ self
+ end
+
+ def configure_cmd(slot, value)
+ configure(slot, install_cmd(value))
+ end
+
+ def command(cmd=nil, &b)
+ if cmd
+ configure_cmd('command', cmd)
+ elsif b
+ configure_cmd('command', Proc.new(&b))
+ else
+ cget('command')
+ end
+ end
+
+ def cget(slot)
+ configinfo slot
+ end
+
+ def [](slot)
+ cget slot
+ end
+
+ def []=(slot, val)
+ configure slot, val
+ val
+ end
+
+ def show
+ tk_call('tk', 'fontchooser', 'show')
+ self
+ end
+
+ def hide
+ tk_call('tk', 'fontchooser', 'hide')
+ self
+ end
+
+ def toggle
+ cget(:visible) ? hide: show
+ self
+ end
+
+ def set_for(target, title="Font")
+ if target.kind_of? TkFont
+ configs = {
+ :font=>target.actual_hash,
+ :command=>proc{|fnt, *args|
+ target.configure(TkFont.actual_hash(fnt))
+ }
+ }
+ else
+ configs = {
+ :font=>target.cget_tkstring(:font),
+ :command=>proc{|fnt, *args|
+ target.font = TkFont.actual_hash_displayof(fnt, target)
+ }
+ }
+ end
+
+ configs[:title] = title if title
+ configure(configs)
+ target
+ end
+
+ def unset
+ configure(:command, nil)
+ end
+end
diff --git a/ext/tk/lib/tk/frame.rb b/ext/tk/lib/tk/frame.rb
index 263b160f29..5118939732 100644
--- a/ext/tk/lib/tk/frame.rb
+++ b/ext/tk/lib/tk/frame.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Frame<TkWindow
TkCommandNames = ['frame'.freeze].freeze
WidgetClassName = 'Frame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
################# old version
# def initialize(parent=nil, keys=nil)
@@ -128,4 +128,5 @@ class Tk::Frame<TkWindow
end
#TkFrame = Tk::Frame unless Object.const_defined? :TkFrame
-Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)
+Tk.__set_loaded_toplevel_aliases__('tk/frame.rb', :Tk, Tk::Frame, :TkFrame)
diff --git a/ext/tk/lib/tk/image.rb b/ext/tk/lib/tk/image.rb
index 09f173909d..79d9ce8d00 100644
--- a/ext/tk/lib/tk/image.rb
+++ b/ext/tk/lib/tk/image.rb
@@ -11,7 +11,7 @@ class TkImage<TkObject
Tk_IMGTBL = TkCore::INTERP.create_table
- (Tk_Image_ID = ['i'.freeze, '00000'.taint]).instance_eval{
+ (Tk_Image_ID = ['i'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/itemconfig.rb b/ext/tk/lib/tk/itemconfig.rb
index cd05d7ea53..14396048ba 100644
--- a/ext/tk/lib/tk/itemconfig.rb
+++ b/ext/tk/lib/tk/itemconfig.rb
@@ -162,6 +162,13 @@ module TkItemConfigMethod
################################################
+
+ def itemcget_tkstring(tagOrId, option)
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
+ tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{opt}"))
+ end
+
def __itemcget_core(tagOrId, option)
orig_opt = option
option = option.to_s
diff --git a/ext/tk/lib/tk/label.rb b/ext/tk/lib/tk/label.rb
index 80b3d778f1..05e430e49b 100644
--- a/ext/tk/lib/tk/label.rb
+++ b/ext/tk/lib/tk/label.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Label<TkWindow
TkCommandNames = ['label'.freeze].freeze
WidgetClassName = 'Label'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('label', @path, *hash_kv(keys, true))
@@ -18,4 +18,5 @@ class Tk::Label<TkWindow
end
#TkLabel = Tk::Label unless Object.const_defined? :TkLabel
-Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)
+Tk.__set_loaded_toplevel_aliases__('tk/label.rb', :Tk, Tk::Label, :TkLabel)
diff --git a/ext/tk/lib/tk/labelframe.rb b/ext/tk/lib/tk/labelframe.rb
index 995b5b7e72..6f679e55b5 100644
--- a/ext/tk/lib/tk/labelframe.rb
+++ b/ext/tk/lib/tk/labelframe.rb
@@ -7,7 +7,7 @@ require 'tk/frame'
class Tk::LabelFrame<Tk::Frame
TkCommandNames = ['labelframe'.freeze].freeze
WidgetClassName = 'Labelframe'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('labelframe', @path, *hash_kv(keys, true))
@@ -26,4 +26,6 @@ end
Tk::Labelframe = Tk::LabelFrame
#TkLabelFrame = Tk::LabelFrame unless Object.const_defined? :TkLabelFrame
#TkLabelframe = Tk::Labelframe unless Object.const_defined? :TkLabelframe
-Tk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe)
+Tk.__set_loaded_toplevel_aliases__('tk/labelframe.rb', :Tk, Tk::LabelFrame,
+ :TkLabelFrame, :TkLabelframe)
diff --git a/ext/tk/lib/tk/listbox.rb b/ext/tk/lib/tk/listbox.rb
index 4357fafc27..6742b2132c 100644
--- a/ext/tk/lib/tk/listbox.rb
+++ b/ext/tk/lib/tk/listbox.rb
@@ -21,7 +21,7 @@ class Tk::Listbox<TkTextWin
TkCommandNames = ['listbox'.freeze].freeze
WidgetClassName = 'Listbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
@@ -279,4 +279,6 @@ class Tk::Listbox<TkTextWin
end
#TkListbox = Tk::Listbox unless Object.const_defined? :TkListbox
-Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)
+Tk.__set_loaded_toplevel_aliases__('tk/listbox.rb', :Tk, Tk::Listbox,
+ :TkListbox)
diff --git a/ext/tk/lib/tk/macpkg.rb b/ext/tk/lib/tk/macpkg.rb
index 67b0a4bb60..3ca7953c13 100644
--- a/ext/tk/lib/tk/macpkg.rb
+++ b/ext/tk/lib/tk/macpkg.rb
@@ -23,7 +23,9 @@ end
module Tk::MacResource
end
#TkMacResource = Tk::MacResource
-Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)
+Tk.__set_loaded_toplevel_aliases__('tk/macpkg.rb', :Tk, Tk::MacResource,
+ :TkMacResource)
module Tk::MacResource
extend Tk
diff --git a/ext/tk/lib/tk/menu.rb b/ext/tk/lib/tk/menu.rb
index 3e122e6987..bcd250026d 100644
--- a/ext/tk/lib/tk/menu.rb
+++ b/ext/tk/lib/tk/menu.rb
@@ -33,13 +33,14 @@ module TkMenuEntryConfig
end
private :__item_val2ruby_optkeys
+ alias entrycget_tkstring itemcget_tkstring
alias entrycget itemcget
alias entrycget_strict itemcget_strict
alias entryconfigure itemconfigure
alias entryconfiginfo itemconfiginfo
alias current_entryconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -50,7 +51,7 @@ class Tk::Menu<TkWindow
TkCommandNames = ['menu'.freeze].freeze
WidgetClassName = 'Menu'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
@@ -386,8 +387,32 @@ class Tk::Menu<TkWindow
end
#TkMenu = Tk::Menu unless Object.const_defined? :TkMenu
-Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::Menu, :TkMenu)
+
+
+module Tk::Menu::TkInternalFunction; end
+class << Tk::Menu::TkInternalFunction
+ # These methods calls internal functions of Tcl/Tk.
+ # So, They may not work on your Tcl/Tk.
+ def next_menu(menu, dir='next')
+ dir = dir.to_s
+ case dir
+ when 'next', 'forward', 'down'
+ dir = 'right'
+ when 'previous', 'backward', 'up'
+ dir = 'left'
+ end
+
+ Tk.tk_call('::tk::MenuNextMenu', menu, dir)
+ end
+ def next_entry(menu, delta)
+ # delta is increment value of entry index.
+ # For example, +1 denotes 'next entry' and -1 denotes 'previous entry'.
+ Tk.tk_call('::tk::MenuNextEntry', menu, delta)
+ end
+end
class Tk::MenuClone<Tk::Menu
=begin
@@ -446,7 +471,9 @@ end
Tk::CloneMenu = Tk::MenuClone
#TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone
#TkCloneMenu = Tk::CloneMenu unless Object.const_defined? :TkCloneMenu
-Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::MenuClone,
+ :TkMenuClone, :TkCloneMenu)
module Tk::SystemMenu
def initialize(parent, keys=nil)
@@ -480,7 +507,9 @@ class Tk::SysMenu_Help<Tk::Menu
SYSMENU_NAME = 'help'
end
#TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help
-Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_Help,
+ :TkSysMenu_Help)
class Tk::SysMenu_System<Tk::Menu
@@ -489,7 +518,9 @@ class Tk::SysMenu_System<Tk::Menu
SYSMENU_NAME = 'system'
end
#TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System
-Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_System,
+ :TkSysMenu_System)
class Tk::SysMenu_Apple<Tk::Menu
@@ -498,13 +529,15 @@ class Tk::SysMenu_Apple<Tk::Menu
SYSMENU_NAME = 'apple'
end
#TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple
-Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_Apple,
+ :TkSysMenu_Apple)
class Tk::Menubutton<Tk::Label
TkCommandNames = ['menubutton'.freeze].freeze
WidgetClassName = 'Menubutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
@@ -541,7 +574,9 @@ end
Tk::MenuButton = Tk::Menubutton
#TkMenubutton = Tk::Menubutton unless Object.const_defined? :TkMenubutton
#TkMenuButton = Tk::MenuButton unless Object.const_defined? :TkMenuButton
-Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::Menubutton,
+ :TkMenubutton, :TkMenuButton)
class Tk::OptionMenubutton<Tk::Menubutton
@@ -677,5 +712,7 @@ end
Tk::OptionMenuButton = Tk::OptionMenubutton
#TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton
#TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton
-Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
- :TkOptionMenubutton, :TkOptionMenuButton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
+# :TkOptionMenubutton, :TkOptionMenuButton)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::OptionMenubutton,
+ :TkOptionMenubutton, :TkOptionMenuButton)
diff --git a/ext/tk/lib/tk/menubar.rb b/ext/tk/lib/tk/menubar.rb
index ac537cb4ec..9d5571c470 100644
--- a/ext/tk/lib/tk/menubar.rb
+++ b/ext/tk/lib/tk/menubar.rb
@@ -93,24 +93,30 @@ class TkMenubar<Tk::Frame
include TkComposite
include TkMenuSpec
- def initialize(parent = nil, spec = nil, options = nil)
+ def initialize(parent = nil, spec = nil, options = {})
if parent.kind_of? Hash
- options = _symbolkey2str(parent)
- spec = options.delete('spec')
- super(options)
- else
- super(parent, options)
+ options = parent
+ parent = nil
+ spec = (options.has_key?('spec'))? options.delete('spec'): nil
end
+ _symbolkey2str(options)
+ menuspec_opt = {}
+ TkMenuSpec::MENUSPEC_OPTKEYS.each{|key|
+ menuspec_opt[key] = options.delete(key) if options.has_key?(key)
+ }
+
+ super(parent, options)
+
@menus = []
- spec.each{|info| add_menu(info)} if spec
+ spec.each{|info| add_menu(info, menuspec_opt)} if spec
options.each{|key, value| configure(key, value)} if options
end
- def add_menu(menu_info)
- mbtn, menu = _create_menubutton(@frame, menu_info)
+ def add_menu(menu_info, menuspec_opt={})
+ mbtn, menu = _create_menubutton(@frame, menu_info, menuspec_opt)
submenus = _get_cascade_menus(menu).flatten
diff --git a/ext/tk/lib/tk/menuspec.rb b/ext/tk/lib/tk/menuspec.rb
index 3f38ab5140..d7521555cd 100644
--- a/ext/tk/lib/tk/menuspec.rb
+++ b/ext/tk/lib/tk/menuspec.rb
@@ -7,9 +7,12 @@
# This file can be distributed under the terms of the Ruby.
#
# The format of the menu_spec is:
-# [ menu_info, menu_info, ... ]
+# [ menubutton_info, menubutton_info, ... ]
#
-# And the format of the menu_info is:
+# The format of the menubutton_info is:
+# [ menubutton_info, entry_info, entry_info, ... ]
+#
+# And each format of *_info is:
# [
# [text, underline, configs], # menu button/entry (*1)
# [label, command, underline, accelerator, configs], # command entry
@@ -22,12 +25,24 @@
# ...
# ]
#
+# A menu_info is an array of menu entries:
+# [ entry_info, entry_info, ... ]
+#
+#
# underline, accelerator, and configs are optional pearameters.
# Hashes are OK instead of Arrays. Then the entry type ('command',
# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key
# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info
# is acceptable for 'menu' key (then, create sub-menu).
#
+# If the value of underline is true instead of an integer,
+# check whether the text/label string contains a '&' character.
+# When includes, the first '&' is removed and its following character is
+# converted the corresponding 'underline' option (first '&' is removed).
+# Else if the value of underline is a String or a Regexp,
+# use the result of label.index(underline) as the index of underline
+# (don't remove matched substring).
+#
# NOTE: (*1)
# If you want to make special menus (*.help for UNIX, *.system for Win,
# and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX,
@@ -39,6 +54,10 @@
# to the configs of the cascade entry.
module TkMenuSpec
+ extend TkMenuSpec
+
+ MENUSPEC_OPTKEYS = [ 'layout_proc' ]
+
def _create_menu(parent, menu_info, menu_name = nil,
tearoff = false, default_opts = nil)
if tearoff.kind_of?(Hash)
@@ -59,6 +78,7 @@ module TkMenuSpec
end
tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')
+ tearoff = false unless tearoff # nil --> false
if menu_name
#menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
@@ -84,6 +104,23 @@ module TkMenuSpec
tearoff, menu_opts)
options['menu'] = submenu
end
+ case options['underline']
+ when String, Regexp
+ if options['label'] &&
+ (idx = options['label'].index(options['underline']))
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ when true
+ if options['label'] && (idx = options['label'].index('&'))
+ options['label'] = options['label'].dup
+ options['label'][idx] = ''
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ end
menu.add(item_type, options)
elsif item_info.kind_of?(Array)
@@ -138,6 +175,25 @@ module TkMenuSpec
end
options.update(opts)
end
+
+ case options['underline']
+ when String, Regexp
+ if options['label'] &&
+ (idx = options['label'].index(options['underline']))
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ when true
+ if options['label'] && (idx = options['label'].index('&'))
+ options['label'] = options['label'].dup
+ options['label'][idx] = ''
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ end
+
menu.add(item_type, options)
elsif /^-+$/ =~ item_info
@@ -177,7 +233,7 @@ module TkMenuSpec
end
private :_create_menu_for_menubar
- def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil)
+ def _create_menubutton(parent, menu_info, tearoff=false, default_opts = {})
btn_info = menu_info[0]
if tearoff.kind_of?(Hash)
@@ -186,14 +242,49 @@ module TkMenuSpec
end
if default_opts.kind_of?(Hash)
- keys = _symbolkey2str(default_opts)
- else
- keys = {}
+ default_opts = _symbolkey2str(default_opts)
+
+ if default_opts.has_key?('layout_proc')
+ layout_proc = default_opts.delete('layout_proc')
+ end
+
+ _vertical_mbar_bind_proc = proc{|m, dir|
+ Tk::Menu::TkInternalFunction.next_menu(m, dir) rescue nil
+ # ignore error when the internal function doesn't exist
+ }
+
+ case layout_proc
+ when :vertical, 'vertical', :vertical_left, 'vertical_left'
+ layout_proc = proc{|_parent, _mbtn|
+ _mbtn.direction :right
+ _mbtn.pack(:side=>:top, :fill=>:x)
+
+ menu = _mbtn.menu
+ menu.bind('Tab', _vertical_mbar_bind_proc, :widget, 'forward')
+ menu.bind('Alt-Tab', _vertical_mbar_bind_proc, :widget, 'backward')
+ }
+ when :vertical_right, 'vertical_right'
+ layout_proc = proc{|_parent, _mbtn|
+ _mbtn.direction :left
+ _mbtn.pack(:side=>:top, :fill=>:x)
+
+ menu = _mbtn.menu
+ menu.bind('Tab', _vertical_mbar_bind_proc, :widget, 'forward')
+ menu.bind('Alt-Tab', _vertical_mbar_bind_proc, :widget, 'backward')
+ }
+ when :horizontal, 'horizontal'
+ layout_proc = proc{|_parent, _mbtn| _mbtn.pack(:side=>:left)}
+ else
+ # do nothing
+ end
end
+ keys = default_opts.dup
+
tearoff = keys.delete('tearoff') if keys.key?('tearoff')
+ tearoff = false unless tearoff # nil --> false
- if _use_menubar?(parent)
+ if _use_menubar?(parent) && ! layout_proc
# menubar by menu entries
mbar = _create_menu_for_menubar(parent)
@@ -202,14 +293,52 @@ module TkMenuSpec
if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name')
- keys['label'] = keys.delete('text') if keys.key?('text')
+ keys['label'] = keys.delete('text') || ''
+
+ case keys['underline']
+ when String, Regexp
+ if idx = keys['label'].index(keys['underline'])
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ when true
+ if idx = keys['label'].index('&')
+ keys['label'] = keys['label'].dup
+ keys['label'][idx] = ''
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ end
+
elsif btn_info.kind_of?(Array)
keys['label'] = btn_info[0] if btn_info[0]
- keys['underline'] = btn_info[1] if btn_info[1]
+
+ case btn_info[1]
+ when Integer
+ keys['underline'] = btn_info[1]
+ when String, Regexp
+ if idx = keys['label'].index(btn_info[1])
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ when true
+ if idx = keys['label'].index('&')
+ keys['label'] = keys['label'].dup
+ keys['label'][idx] = ''
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ end
+
if btn_info[2]&&btn_info[2].kind_of?(Hash)
keys.update(_symbolkey2str(btn_info[2]))
menu_name = keys.delete('menu_name')
end
+
else
keys = {:label=>btn_info}
end
@@ -234,9 +363,42 @@ module TkMenuSpec
if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name')
- keys['text'] = keys.delete('label') if keys.key?('label')
+ keys['text'] = keys.delete('label') || ''
+ case keys['underline']
+ when String, Regexp
+ if idx = keys['text'].index(keys['underline'])
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ when true
+ if idx = keys['text'].index('&')
+ keys['text'] = keys['text'].dup
+ keys['text'][idx] = ''
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ end
mbtn.configure(keys)
+
elsif btn_info.kind_of?(Array)
+ case btn_info[1]
+ when String, Regexp
+ if btn_info[0] && (idx = btn_info[0].index(btn_info[1]))
+ btn_info[1] = idx
+ else
+ btn_info[1] = -1
+ end
+ when true
+ if btn_info[0] && (idx = btn_info[0].index('&'))
+ btn_info[0] = btn_info[0].dup
+ btn_info[0][idx] = ''
+ btn_info[1] = idx
+ else
+ btn_info[1] = -1
+ end
+ end
mbtn.configure('text', btn_info[0]) if btn_info[0]
mbtn.configure('underline', btn_info[1]) if btn_info[1]
# mbtn.configure('accelerator', btn_info[2]) if btn_info[2]
@@ -245,22 +407,41 @@ module TkMenuSpec
menu_name = keys.delete('menu_name')
mbtn.configure(keys)
end
+
else
mbtn.configure('text', btn_info)
end
- mbtn.pack('side' => 'left')
-
menu = _create_menu(mbtn, menu_info[1..-1], menu_name,
tearoff, default_opts)
-
mbtn.menu(menu)
+ if layout_proc.kind_of?(Proc) || layout_proc.kind_of?(Method)
+ # e.g. make a vertical menubar
+ # :layout_proc => proc{|parent, btn| btn.pack(:side=>:top, :fill=>:x)}
+ layout_proc.call(parent, mbtn)
+ else
+ mbtn.pack('side' => 'left')
+ end
+
[mbtn, menu]
end
end
private :_create_menubutton
+ def _create_menubar(parent, menu_spec, tearoff = false, opts = nil)
+ if tearoff.kind_of?(Hash)
+ opts = tearoff
+ tearoff = false
+ end
+ tearoff = false unless tearoff # nil --> false
+ menu_spec.each{|menu_info|
+ _create_menubutton(parent, menu_info, tearoff, opts)
+ }
+ parent
+ end
+ private :_create_menubar
+
def _get_cascade_menus(menu)
menus = []
(0..(menu.index('last'))).each{|idx|
diff --git a/ext/tk/lib/tk/message.rb b/ext/tk/lib/tk/message.rb
index 946b68c704..5f73b3066f 100644
--- a/ext/tk/lib/tk/message.rb
+++ b/ext/tk/lib/tk/message.rb
@@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Message<Tk::Label
TkCommandNames = ['message'.freeze].freeze
WidgetClassName = 'Message'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('message', @path, *hash_kv(keys, true))
@@ -19,4 +19,6 @@ class Tk::Message<Tk::Label
end
#TkMessage = Tk::Message unless Object.const_defined? :TkMessage
-Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)
+Tk.__set_loaded_toplevel_aliases__('tk/message.rb', :Tk, Tk::Message,
+ :TkMessage)
diff --git a/ext/tk/lib/tk/msgcat.rb b/ext/tk/lib/tk/msgcat.rb
index f90dbc5efa..4abbcad85e 100644
--- a/ext/tk/lib/tk/msgcat.rb
+++ b/ext/tk/lib/tk/msgcat.rb
@@ -36,7 +36,7 @@ class TkMsgCatalog < TkObject
MSGCAT_EXT = '.msg'
- UNKNOWN_CBTBL = Hash.new{|hash,key| hash[key] = {}}.taint
+ UNKNOWN_CBTBL = TkUtil.untrust(Hash.new{|hash,key| hash[key] = {}})
TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL')
if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} {
diff --git a/ext/tk/lib/tk/namespace.rb b/ext/tk/lib/tk/namespace.rb
index dfb162cda8..4af891995e 100644
--- a/ext/tk/lib/tk/namespace.rb
+++ b/ext/tk/lib/tk/namespace.rb
@@ -13,7 +13,7 @@ class TkNamespace < TkObject
Tk_Namespace_ID_TBL = TkCore::INTERP.create_table
- (Tk_Namespace_ID = ["ns".freeze, "00000".taint]).instance_eval{
+ (Tk_Namespace_ID = ["ns".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/optiondb.rb b/ext/tk/lib/tk/optiondb.rb
index 9d366c13ea..0f3be30ff7 100644
--- a/ext/tk/lib/tk/optiondb.rb
+++ b/ext/tk/lib/tk/optiondb.rb
@@ -8,7 +8,7 @@ module TkOptionDB
extend Tk
TkCommandNames = ['option'.freeze].freeze
- (CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint]).instance_eval{
+ (CmdClassID = ['CMD_CLASS'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/panedwindow.rb b/ext/tk/lib/tk/panedwindow.rb
index 4e70ede9bf..04407802ea 100644
--- a/ext/tk/lib/tk/panedwindow.rb
+++ b/ext/tk/lib/tk/panedwindow.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::PanedWindow<TkWindow
TkCommandNames = ['panedwindow'.freeze].freeze
WidgetClassName = 'Panedwindow'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true))
@@ -254,5 +254,7 @@ end
Tk::Panedwindow = Tk::PanedWindow
#TkPanedWindow = Tk::PanedWindow unless Object.const_defined? :TkPanedWindow
#TkPanedwindow = Tk::Panedwindow unless Object.const_defined? :TkPanedwindow
-Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow,
- :TkPanedWindow, :TkPanedwindow)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow,
+# :TkPanedWindow, :TkPanedwindow)
+Tk.__set_loaded_toplevel_aliases__('tk/panedwindow.rb', :Tk, Tk::PanedWindow,
+ :TkPanedWindow, :TkPanedwindow)
diff --git a/ext/tk/lib/tk/radiobutton.rb b/ext/tk/lib/tk/radiobutton.rb
index 1d75dc220d..627df6d9cf 100644
--- a/ext/tk/lib/tk/radiobutton.rb
+++ b/ext/tk/lib/tk/radiobutton.rb
@@ -7,7 +7,7 @@ require 'tk/button'
class Tk::RadioButton<Tk::Button
TkCommandNames = ['radiobutton'.freeze].freeze
WidgetClassName = 'Radiobutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true))
@@ -67,5 +67,7 @@ end
Tk::Radiobutton = Tk::RadioButton
#TkRadioButton = Tk::RadioButton unless Object.const_defined? :TkRadioButton
#TkRadiobutton = Tk::Radiobutton unless Object.const_defined? :TkRadiobutton
-Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton,
- :TkRadioButton, :TkRadiobutton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton,
+# :TkRadioButton, :TkRadiobutton)
+Tk.__set_loaded_toplevel_aliases__('tk/radiobutton.rb', :Tk, Tk::RadioButton,
+ :TkRadioButton, :TkRadiobutton)
diff --git a/ext/tk/lib/tk/root.rb b/ext/tk/lib/tk/root.rb
index ca6260927a..b4f0bd107f 100644
--- a/ext/tk/lib/tk/root.rb
+++ b/ext/tk/lib/tk/root.rb
@@ -52,7 +52,7 @@ class Tk::Root<TkWindow
end
WidgetClassName = 'Tk'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.to_eval
# self::WidgetClassName
diff --git a/ext/tk/lib/tk/scale.rb b/ext/tk/lib/tk/scale.rb
index 58283216b8..0bdcead7f2 100644
--- a/ext/tk/lib/tk/scale.rb
+++ b/ext/tk/lib/tk/scale.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Scale<TkWindow
TkCommandNames = ['scale'.freeze].freeze
WidgetClassName = 'Scale'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
@@ -108,4 +108,5 @@ class Tk::Scale<TkWindow
end
#TkScale = Tk::Scale unless Object.const_defined? :TkScale
-Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)
+Tk.__set_loaded_toplevel_aliases__('tk/scale.rb', :Tk, Tk::Scale, :TkScale)
diff --git a/ext/tk/lib/tk/scrollbar.rb b/ext/tk/lib/tk/scrollbar.rb
index decc4205c4..c0ac201acb 100644
--- a/ext/tk/lib/tk/scrollbar.rb
+++ b/ext/tk/lib/tk/scrollbar.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Scrollbar<TkWindow
TkCommandNames = ['scrollbar'.freeze].freeze
WidgetClassName = 'Scrollbar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
@assigned = []
@@ -148,7 +148,9 @@ class Tk::Scrollbar<TkWindow
end
#TkScrollbar = Tk::Scrollbar unless Object.const_defined? :TkScrollbar
-Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::Scrollbar,
+ :TkScrollbar)
class Tk::XScrollbar<Tk::Scrollbar
@@ -161,7 +163,9 @@ class Tk::XScrollbar<Tk::Scrollbar
end
#TkXScrollbar = Tk::XScrollbar unless Object.const_defined? :TkXScrollbar
-Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::XScrollbar,
+ :TkXScrollbar)
class Tk::YScrollbar<Tk::Scrollbar
@@ -174,4 +178,6 @@ class Tk::YScrollbar<Tk::Scrollbar
end
#TkYScrollbar = Tk::YScrollbar unless Object.const_defined? :TkYScrollbar
-Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::YScrollbar,
+ :TkYScrollbar)
diff --git a/ext/tk/lib/tk/spinbox.rb b/ext/tk/lib/tk/spinbox.rb
index 2fcc916237..f2917d60ca 100644
--- a/ext/tk/lib/tk/spinbox.rb
+++ b/ext/tk/lib/tk/spinbox.rb
@@ -8,7 +8,7 @@ require 'tk/entry'
class Tk::Spinbox<Tk::Entry
TkCommandNames = ['spinbox'.freeze].freeze
WidgetClassName = 'Spinbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
class SpinCommand < TkValidateCommand
class ValidateArgs < TkUtil::CallbackSubst
@@ -100,13 +100,36 @@ class Tk::Spinbox<Tk::Entry
tk_send_without_enc('identify', x, y)
end
+ def invoke(elem)
+ tk_send_without_enc('invoke', elem)
+ self
+ end
+
def spinup
- tk_send_without_enc('invoke', 'spinup')
+ begin
+ tk_send_without_enc('invoke', 'buttonup')
+ rescue RuntimeError => e
+ # old version of element?
+ begin
+ tk_send_without_enc('invoke', 'spinup')
+ rescue
+ fail e
+ end
+ end
self
end
def spindown
- tk_send_without_enc('invoke', 'spindown')
+ begin
+ tk_send_without_enc('invoke', 'buttondown')
+ rescue RuntimeError => e
+ # old version of element?
+ begin
+ tk_send_without_enc('invoke', 'spinup')
+ rescue
+ fail e
+ end
+ end
self
end
@@ -116,4 +139,6 @@ class Tk::Spinbox<Tk::Entry
end
#TkSpinbox = Tk::Spinbox unless Object.const_defined? :TkSpinbox
-Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)
+Tk.__set_loaded_toplevel_aliases__('tk/spinbox.rb', :Tk, Tk::Spinbox,
+ :TkSpinbox)
diff --git a/ext/tk/lib/tk/text.rb b/ext/tk/lib/tk/text.rb
index 42b8be475e..bc2aa0a293 100644
--- a/ext/tk/lib/tk/text.rb
+++ b/ext/tk/lib/tk/text.rb
@@ -29,6 +29,9 @@ module TkTextTagConfig
end
private :__item_pathname
+ def tag_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['tag', tagOrId], option)
+ end
def tag_cget(tagOrId, option)
itemcget(['tag', tagOrId], option)
end
@@ -45,6 +48,9 @@ module TkTextTagConfig
current_itemconfiginfo(['tag', tagOrId], slot)
end
+ def window_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['window', tagOrId], option)
+ end
def window_cget(tagOrId, option)
itemcget(['window', tagOrId], option)
end
@@ -61,7 +67,7 @@ module TkTextTagConfig
current_itemconfiginfo(['window', tagOrId], slot)
end
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -251,7 +257,7 @@ class Tk::Text<TkTextWin
TkCommandNames = ['text'.freeze].freeze
WidgetClassName = 'Text'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.new(*args, &block)
obj = super(*args){}
@@ -1570,7 +1576,8 @@ class Tk::Text<TkTextWin
end
#TkText = Tk::Text unless Object.const_defined? :TkText
-Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)
+Tk.__set_loaded_toplevel_aliases__('tk/text.rb', :Tk, Tk::Text, :TkText)
#######################################
@@ -1587,7 +1594,8 @@ class Tk::Text::Peer < Tk::Text
def create_self(keys)
if keys and keys != None
- tk_call_without_enc(@src_text.path, 'peer', 'create', @path)
+ tk_call_without_enc(@src_text.path, 'peer', 'create',
+ @path, *hash_kv(keys, true))
else
tk_call_without_enc(@src_text.path, 'peer', 'create', @path)
end
diff --git a/ext/tk/lib/tk/textmark.rb b/ext/tk/lib/tk/textmark.rb
index e9743475e0..d1888c5e54 100644
--- a/ext/tk/lib/tk/textmark.rb
+++ b/ext/tk/lib/tk/textmark.rb
@@ -9,7 +9,7 @@ class TkTextMark<TkObject
TMarkID_TBL = TkCore::INTERP.create_table
- (Tk_TextMark_ID = ['mark'.freeze, '00000'.taint]).instance_eval{
+ (Tk_TextMark_ID = ['mark'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/texttag.rb b/ext/tk/lib/tk/texttag.rb
index 7bd59bf8ee..96692014e4 100644
--- a/ext/tk/lib/tk/texttag.rb
+++ b/ext/tk/lib/tk/texttag.rb
@@ -11,7 +11,7 @@ class TkTextTag<TkObject
TTagID_TBL = TkCore::INTERP.create_table
- (Tk_TextTag_ID = ['tag'.freeze, '00000'.taint]).instance_eval{
+ (Tk_TextTag_ID = ['tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -129,6 +129,9 @@ class TkTextTag<TkObject
val
end
+ def cget_tkstring(key)
+ @t.tag_cget_tkstring @id, key
+ end
def cget(key)
@t.tag_cget @id, key
end
diff --git a/ext/tk/lib/tk/timer.rb b/ext/tk/lib/tk/timer.rb
index 686d4bd483..be2a8919e4 100644
--- a/ext/tk/lib/tk/timer.rb
+++ b/ext/tk/lib/tk/timer.rb
@@ -11,13 +11,13 @@ class TkTimer
TkCommandNames = ['after'.freeze].freeze
- (Tk_CBID = ['a'.freeze, '00000'.taint]).instance_eval{
+ (Tk_CBID = ['a'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
- Tk_CBTBL = {}.taint
+ Tk_CBTBL = TkUtil.untrust({})
TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')
if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} {
diff --git a/ext/tk/lib/tk/toplevel.rb b/ext/tk/lib/tk/toplevel.rb
index 917264aef7..30ef009517 100644
--- a/ext/tk/lib/tk/toplevel.rb
+++ b/ext/tk/lib/tk/toplevel.rb
@@ -11,7 +11,7 @@ class Tk::Toplevel<TkWindow
TkCommandNames = ['toplevel'.freeze].freeze
WidgetClassName = 'Toplevel'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
################# old version
# def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
@@ -259,4 +259,6 @@ class Tk::Toplevel<TkWindow
end
#TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel
-Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)
+Tk.__set_loaded_toplevel_aliases__('tk/toplevel.rb', :Tk, Tk::Toplevel,
+ :TkToplevel)
diff --git a/ext/tk/lib/tk/ttk_selector.rb b/ext/tk/lib/tk/ttk_selector.rb
index 7a0dd34038..522249e6a9 100644
--- a/ext/tk/lib/tk/ttk_selector.rb
+++ b/ext/tk/lib/tk/ttk_selector.rb
@@ -53,21 +53,43 @@ module Tk
:TkTreeview => 'tkextlib/tile/treeview',
}
- @TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]
+
+ # @TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]
+ Tk.__create_widget_set__(:Tile, :Ttk)
+
+ ############################################
+ # depend on the version of Tcl/Tk
+ major, minor, type, patchlevel = TclTkLib.get_version
+
+ # ttk::spinbox is supported on Tcl/Tk8.6b1 or later
+ if ([major,minor,type,patchlevel] <=>
+ [8,6,TclTkLib::RELEASE_TYPE::BETA,1]) >= 0
+ @TOPLEVEL_ALIAS_TABLE[:Ttk].update(
+ :TkSpinbox => 'tkextlib/tile/tspinbox'
+ )
+ end
################################################
# register some Ttk widgets as default
# (Ttk is a standard library on Tcl/Tk8.5+)
@TOPLEVEL_ALIAS_TABLE[:Ttk].each{|sym, file|
- unless Object.autoload?(sym) || Object.const_defined?(sym)
- Object.autoload(sym, file)
- end
+ #unless Tk::TOPLEVEL_ALIASES.autoload?(sym) || Tk::TOPLEVEL_ALIASES.const_defined?(sym)
+ # @TOPLEVEL_ALIAS_OWNER[sym] = :Ttk
+ # Tk::TOPLEVEL_ALIASES.autoload(sym, file)
+ #end
+ Tk.__regist_toplevel_aliases__(:Ttk, file, sym)
}
################################################
- @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
- @TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|
+ # @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
+ # @TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|
+ # unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile)
+ # Object.autoload :Ttk, 'tkextlib/tile'
+ # Tk.autoload :Tile, 'tkextlib/tile'
+ # end
+ # }
+ Tk.__toplevel_alias_setup_proc__(:Ttk, :Tile){|mod|
unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile)
Object.autoload :Ttk, 'tkextlib/tile'
Tk.autoload :Tile, 'tkextlib/tile'
diff --git a/ext/tk/lib/tk/variable.rb b/ext/tk/lib/tk/variable.rb
index bdd441705b..6fc2ffdf2f 100644
--- a/ext/tk/lib/tk/variable.rb
+++ b/ext/tk/lib/tk/variable.rb
@@ -16,7 +16,7 @@ class TkVariable
#TkVar_ID_TBL = {}
TkVar_CB_TBL = TkCore::INTERP.create_table
TkVar_ID_TBL = TkCore::INTERP.create_table
- (Tk_VARIABLE_ID = ["v".freeze, "00000".taint]).instance_eval{
+ (Tk_VARIABLE_ID = ["v".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1239,6 +1239,14 @@ end
end
end
+ def ===(other)
+ if other.kind_of?(TkVariable)
+ self.id == other.id
+ else
+ super
+ end
+ end
+
def zero?
numeric.zero?
end
diff --git a/ext/tk/lib/tk/virtevent.rb b/ext/tk/lib/tk/virtevent.rb
index ba771da647..19c0dac380 100644
--- a/ext/tk/lib/tk/virtevent.rb
+++ b/ext/tk/lib/tk/virtevent.rb
@@ -9,7 +9,7 @@ class TkVirtualEvent<TkObject
TkCommandNames = ['event'.freeze].freeze
- (TkVirtualEventID = ["VirtEvent".freeze, "00000".taint]).instance_eval{
+ (TkVirtualEventID = ["VirtEvent".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/winpkg.rb b/ext/tk/lib/tk/winpkg.rb
index a131731560..80e0439ace 100644
--- a/ext/tk/lib/tk/winpkg.rb
+++ b/ext/tk/lib/tk/winpkg.rb
@@ -10,7 +10,8 @@ require 'tk'
module Tk::WinDDE
end
#TkWinDDE = Tk::WinDDE
-Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)
+Tk.__set_loaded_toplevel_aliases__('tk/winpkg.rb', :Tk, Tk::WinDDE, :TkWinDDE)
module Tk::WinDDE
extend Tk
@@ -93,7 +94,9 @@ end
module Tk::WinRegistry
end
#TkWinRegistry = Tk::WinRegistry
-Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)
+Tk.__set_loaded_toplevel_aliases__('tk/winpkg.rb', :Tk, Tk::WinRegistry,
+ :TkWinRegistry)
module Tk::WinRegistry
extend Tk