diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-07-31 07:59:18 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-07-31 07:59:18 +0000 |
commit | 7126624b4effe49919e35224054cc48e86716f39 (patch) | |
tree | 081a374af97921e6315428db1bf7d58cbda40955 | |
parent | 89769459ba6ab5987ac257f35e2559726437e35b (diff) |
* wrap the command-proc of TkScale : pass the numeric object to the proc
* better support for widgets created on Tk interpreter (without Ruby)
* a little more stable on Multiple Tk interpreters running
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4242 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ext/tk/lib/multi-tk.rb | 43 | ||||
-rw-r--r-- | ext/tk/lib/tk.rb | 87 | ||||
-rw-r--r-- | ext/tk/lib/tkafter.rb | 9 | ||||
-rw-r--r-- | ext/tk/sample/safe-tk.rb | 2 |
4 files changed, 117 insertions, 24 deletions
diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index 438c3c0816..99c25f2595 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -6,6 +6,13 @@ require 'tcltklib' require 'thread' ################################################ +# ignore exception on the mainloop + +# TclTkLib.mainloop_abort_on_exception = false +TclTkLib.mainloop_abort_on_exception = nil + + +################################################ # exceptiopn to treat the return value from IP class MultiTkIp_OK < Exception def self.send(thred, ret=nil) @@ -22,17 +29,11 @@ class MultiTkIp_OK < Exception end MultiTkIp_OK.freeze + ################################################ # methods for construction class MultiTkIp - - # ignore exception on the mainloop - #TclTkLib.mainloop_abort_on_exception = false - TclTkLib.mainloop_abort_on_exception = nil - - ###################################### - - SLAVE_IP_ID = ['slave'.freeze, '00000'] + SLAVE_IP_ID = ['slave'.freeze, '0'] @@IP_TABLE = {} @@ -827,6 +828,32 @@ end # depend on TclTkIp class MultiTkIp + def mainloop(check_root = true, restart_on_dead = true) + unless restart_on_dead + @interp.mainloop(check_root) + else + begin + loop do + @interp.mainloop(check_root) + if check_root + begin + break if @interp._invoke('winfo', 'exists?', '.') == "1" + rescue Exception + break + end + end + end + rescue StandardError + if TclTkLib.mainloop_abort_on_exception != nil + STDERR.print("warning: Tk mainloop on ", @interp.inspect, + " receives ", $!.class.inspect, + " exception (ignore) : ", $!.message, "\n"); + end + retry + end + end + end + def make_safe @interp.make_safe end diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 7b7b116a14..b25c5f3a1c 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -50,28 +50,27 @@ module TkComm if ruby_class = WidgetClassNames[tk_class] ruby_class_name = ruby_class.name - gen_class_name = ruby_class_name + 'GeneratedOnTk' + # gen_class_name = ruby_class_name + 'GeneratedOnTk' + gen_class_name = ruby_class_name classname_def = '' elsif Object.const_defined?('Tk' + tk_class) ruby_class_name = 'Tk' + tk_class - gen_class_name = ruby_class_name + 'GeneratedOnTk' + # gen_class_name = ruby_class_name + 'GeneratedOnTk' + gen_class_name = ruby_class_name classname_def = '' else ruby_class_name = 'TkWindow' - gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk' + # gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk' + gen_class_name = 'TkWidget_' + tk_class classname_def = "WidgetClassName = '#{tk_class}'.freeze" end unless Object.const_defined? gen_class_name Object.class_eval "class #{gen_class_name}<#{ruby_class_name} #{classname_def} - def initialize(path) - @path=path - #Tk_WINDOWS[@path] = self - TkCore::INTERP.tk_windows[@path] = self - end end" end - Object.class_eval "#{gen_class_name}.new('#{path}')" + Object.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', + 'without_creating'=>true)" end private :_genobj_for_tkwidget module_function :_genobj_for_tkwidget @@ -889,11 +888,34 @@ module TkCore tk_call('info', *args) end - def mainloop(check_root = true) - TclTkLib.mainloop(check_root) + def mainloop(check_root = true, restart_on_dead = true) + unless restart_on_dead + TclTkLib.mainloop(check_root) + else + begin + loop do + TclTkLib.mainloop(check_root) + if check_root + begin + break if TkWinfo.exist?('.') + rescue Exception + break + end + end + end + rescue StandardError + if TclTkLib.mainloop_abort_on_exception != nil + STDERR.print("warning: Tk mainloop on ", TkCore::INTERP.inspect, + " receives ", $!.class.inspect, + " exception (ignore) : ", $!.message, "\n"); + end + retry + end + end end def mainloop_watchdog(check_root = true) + # watchdog restarts mainloop when mainloop is dead TclTkLib.mainloop_watchdog(check_root) end @@ -3739,12 +3761,12 @@ class TkWindow<TkObject def destroy super _destroy_children - tk_call 'destroy', epath if defined?(@cmdtbl) for id in @cmdtbl uninstall_cmd id end end + tk_call 'destroy', epath uninstall_win end @@ -4392,12 +4414,46 @@ class TkScale<TkWindow def create_self(keys) if keys and keys != None + if keys.key?('command') + cmd = keys.delete('command') + keys['command'] = proc{|val| cmd.call(val.to_f)} + end tk_call 'scale', @path, *hash_kv(keys) else tk_call 'scale', @path end end + def _wrap_command_arg(cmd) + proc{|val| + if val.kind_of?(String) + cmd.call(number(val)) + else + cmd.call(val) + end + } + end + private :_wrap_command_arg + + def configure_cmd(slot, value) + configure(slot=>value) + end + + def configure(slot, value=None) + if (slot == 'command' || slot == :command) + configure('command'=>value) + elsif slot.kind_of?(Hash) && + (slot.key?('command') || slot.key?(:command)) + slot = _symbolkey2str(slot) + slot['command'] = __wrap_command_arg(slot.delete('command')) + end + super(slot, value) + end + + def command(cmd=Proc.new) + configure('command'=>cmd) + end + def get(x=None, y=None) number(tk_send('get', x, y)) end @@ -5098,10 +5154,11 @@ TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|widget| else w = widget.to_s end - if widget.respond_to?(:__destroy_hook__) && - TkCore::INTERP._invoke('winfo','exist',w) == '1' + if widget.respond_to?(:__destroy_hook__) begin - widget.__destroy_hook__ + if TkCore::INTERP._invoke('winfo','exist',w) == '1' + widget.__destroy_hook__ + end rescue Exception end end diff --git a/ext/tk/lib/tkafter.rb b/ext/tk/lib/tkafter.rb index eddfc16f63..529b1e6cfb 100644 --- a/ext/tk/lib/tkafter.rb +++ b/ext/tk/lib/tkafter.rb @@ -114,7 +114,14 @@ class TkTimer @id = Tk_CBID.join Tk_CBID[1].succ! - @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback)) + # @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback)) + @cb_cmd = TkCore::INTERP.get_cb_entry(proc{ + begin + self.do_callback + rescue + self.cancel + end + }) @set_next = true diff --git a/ext/tk/sample/safe-tk.rb b/ext/tk/sample/safe-tk.rb index 90eb456653..6b6de8f848 100644 --- a/ext/tk/sample/safe-tk.rb +++ b/ext/tk/sample/safe-tk.rb @@ -55,6 +55,8 @@ safe_slave1.eval_proc(cmd, 'safe1') # label -> .w00016 safe_slave2.eval_proc(cmd, 'safe2') # label -> .w00020 cmd.call('master') # label -> .w00024 +#second_master = MultiTkIp.new(&cmd) + TkTimer.new(2000, -1, proc{p ['safe1', safe_slave1.deleted?]}).start TkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start TkTimer.new(2000, -1, proc{p ['trusted', trusted_slave.deleted?]}).start |