diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-01-25 05:09:22 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-01-25 05:09:22 +0000 |
commit | 10484e5c95d649554fc353012626c3696edd2eac (patch) | |
tree | 7497f0a182dae28c37d518d56551a8231092fc5c /ext | |
parent | 586d308ecf23a88d18413bd2ce9d1373e556c34f (diff) |
* ext/tcltklib/tcltklib.c: fix SEGV bug; trouble on canceling remained
after scripts [ruby-dev:25479]: NULL current namespce when deleting
Tk interpreter [ruby-talk:126225]
* ext/tcltklib/extconf.rb: bug fix; TCL_ENABLE_THREAD flag is inverted
[ruby-talk:126360]
* ext/tcltklib/extconf.rb: add yet another native-thread check
* ext/tk/tkutil.c: fix SEGV bug; NULL string pointer when finalize
Ruby interpreter
* ext/tk/lib/multi-tk.rb: avoid warning for deleted safeTk ip frame
* ext/tk/lib/tk/bindtag.rb: bug fix; new method of named bindtag
doesn't return the created object [ruby-dev:25479]
* ext/tk/lib/tk/menu.rb: bug on treating arguments [ruby-dev:25479]
* ext/tk/lib/tk.rb: bug fix; cannot accept a callback ID string for
a command argument [ruby-dev:25479]
* ext/tk/lib/multi-tk.rb: ditto
* ext/tk/lib/tk/*.rb: ditto
* ext/tk/lib/tkextlib/*.rb: ditto
* ext/tk/sample/demos-jp/anilabel.rb: new demo script
* ext/tk/sample/demos-en/anilabel.rb: ditto
* ext/tk/sample/tkHTML/ss.rb: local variable scope bug fix
[ruby-dev:25479]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7821 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
30 files changed, 602 insertions, 105 deletions
diff --git a/ext/tcltklib/extconf.rb b/ext/tcltklib/extconf.rb index 201768cb0d..00aa2ca620 100644 --- a/ext/tcltklib/extconf.rb +++ b/ext/tcltklib/extconf.rb @@ -166,6 +166,15 @@ def pthread_check() # tcl-thread is unknown if try_run(<<EOF) #include <tcl.h> +int main() { + Tcl_Interp *ip; + ip = Tcl_CreateInterp(); + exit((Tcl_Eval(ip, "set tcl_platform(threaded)") == TCL_OK)? 0: 1); +} +EOF + tcl_enable_thread = true + elsif try_run(<<EOF) +#include <tcl.h> static Tcl_ThreadDataKey dataKey; int main() { exit((Tcl_GetThreadData(&dataKey, 1) == dataKey)? 1: 0); } EOF @@ -230,11 +239,11 @@ EOF ** ***************************************************************************** ') - $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0' + $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1' return false else # ruby -> disable && tcl -> disable - $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1' + $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0' return true end end diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index a52994dd00..c9a72ed4bd 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -4,7 +4,7 @@ * Oct. 24, 1997 Y. Matsumoto */ -#define TCLTKLIB_RELEASE_DATE "2004-12-27" +#define TCLTKLIB_RELEASE_DATE "2005-01-25" #include "ruby.h" #include "rubysig.h" @@ -74,8 +74,8 @@ const char tcltklib_release_date[] = TCLTKLIB_RELEASE_DATE; static char *finalize_hook_name = "INTERP_FINALIZE_HOOK"; /* to cancel remained after-scripts when deleting IP */ -#define REMAINED_AFTER_IDS_VAR "__ruby_tcltklib_remained_after_script_list__" -#define CANCEL_REMAINED_AFTER_IDS "foreach id $__ruby_tcltklib_remained_after_script_list__ {after cancel $id}" +#define CANCEL_AFTER_SCRIPTS "__ruby_tcltklib_cancel_after_scripts__" +#define DEF_CANCEL_AFTER_SCRIPTS_PROC "proc __ruby_tcltklib_cancel_after_scripts__ {} {foreach id [after info] {after cancel $id}}" /* for callback break & continue */ static VALUE eTkCallbackReturn; @@ -204,6 +204,14 @@ static int ip_ruby_eval _((ClientData, Tcl_Interp *, int, char **)); static int ip_ruby_cmd _((ClientData, Tcl_Interp *, int, char **)); #endif +static int ip_null_namespace _((Tcl_Interp *)); +#if TCL_MAJOR_VERSION >= 8 +#ifndef Tcl_GetCurrentNamespace +EXTERN Tcl_Namespace * Tcl_GetCurrentNamespace _((Tcl_Interp *)); +#endif +#endif + + /*---- class TclTkIp ----*/ struct tcltkip { Tcl_Interp *ip; /* the interpreter */ @@ -1881,7 +1889,7 @@ ip_InterpExitCommand(clientData, interp, argc, argv) char *argv[]; #endif { - if (!Tcl_InterpDeleted(interp)) { + if (!Tcl_InterpDeleted(interp) && !ip_null_namespace(interp)) { Tcl_Preserve(interp); Tcl_Eval(interp, "interp eval {} {destroy .}; interp delete {}"); Tcl_Release(interp); @@ -3261,10 +3269,13 @@ VALUE del_root(ip) if (!Tcl_InterpDeleted(ip)) { Tcl_Preserve(ip); - while((main_win = Tk_MainWindow(ip)) != (Tk_Window)NULL) { + + if ( (main_win = Tk_MainWindow(ip)) != (Tk_Window)NULL + && !(((Tk_FakeWin*)main_win)->flags & TK_ALREADY_DEAD) ) { DUMP1("wait main_win is destroyed"); Tk_DestroyWindow(main_win); } + Tcl_Release(ip); } return Qnil; @@ -3277,9 +3288,15 @@ delete_slaves(ip) { Tcl_Interp *slave; Tcl_Obj *slave_list, *elem; + Tcl_CmdInfo info; char *slave_name; int i, len; + if (Tcl_InterpDeleted(ip) || ip_null_namespace(ip)) { + DUMP2("call delete_slaves() for deleted ip(%lx)", ip); + return; + } + DUMP2("delete slaves of ip(%lx)", ip); Tcl_Preserve(ip); @@ -3316,14 +3333,18 @@ delete_slaves(ip) Tcl_Preserve(slave); - if (!Tcl_InterpDeleted(slave)) { - if (Tcl_Eval(slave, "after info") == TCL_OK - && Tcl_SetVar(slave, - REMAINED_AFTER_IDS_VAR, - Tcl_GetStringResult(slave), - TCL_GLOBAL_ONLY) != (char *)NULL) { - DUMP1("cancel after scripts"); - Tcl_Eval(slave, CANCEL_REMAINED_AFTER_IDS); + if (!Tcl_InterpDeleted(slave) && !ip_null_namespace(slave)) { + if (Tcl_Eval(slave, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { + if (Tcl_GetCommandInfo(slave, CANCEL_AFTER_SCRIPTS, &info)) { + DUMP2("call cancel after scripts proc '%s'", + CANCEL_AFTER_SCRIPTS); + Tcl_Eval(slave, CANCEL_AFTER_SCRIPTS); + } + } + + if (Tcl_GetCommandInfo(slave, finalize_hook_name, &info)) { + DUMP2("call finalize hook proc '%s'", finalize_hook_name); + Tcl_Eval(slave, finalize_hook_name); } } @@ -3332,12 +3353,16 @@ delete_slaves(ip) /* delete slave */ del_root(slave); - while(!Tcl_InterpDeleted(slave)) { + /* while(!rbtk_InterpDeleted(slave)) { */ + if (!Tcl_InterpDeleted(slave)) { DUMP1("wait ip is deleted"); Tcl_DeleteInterp(slave); } Tcl_Release(slave); + + /* delete slave_name command */ + Tcl_DeleteCommand(ip, slave_name); } Tcl_DecrRefCount(slave_list); @@ -3359,7 +3384,7 @@ ip_free(ptr) DUMP2("IP ref_count = %d", ptr->ref_count); - if (!Tcl_InterpDeleted(ptr->ip)) { + if (!Tcl_InterpDeleted(ptr->ip) && !ip_null_namespace(ptr->ip)) { DUMP2("IP(%lx) is not deleted", ptr->ip); /* Tcl_Preserve(ptr->ip); */ rbtk_preserve_ip(ptr); @@ -3368,13 +3393,12 @@ ip_free(ptr) Tcl_ResetResult(ptr->ip); - if (Tcl_Eval(ptr->ip, "after info") == TCL_OK - && Tcl_SetVar(ptr->ip, - REMAINED_AFTER_IDS_VAR, - Tcl_GetStringResult(ptr->ip), - TCL_GLOBAL_ONLY) != (char *)NULL) { - DUMP1("cancel after scripts"); - Tcl_Eval(ptr->ip, CANCEL_REMAINED_AFTER_IDS); + if (Tcl_Eval(ptr->ip, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { + if (Tcl_GetCommandInfo(ptr->ip, CANCEL_AFTER_SCRIPTS, &info)) { + DUMP2("call cancel after scripts proc '%s'", + CANCEL_AFTER_SCRIPTS); + Tcl_Eval(ptr->ip, CANCEL_AFTER_SCRIPTS); + } } if (Tcl_GetCommandInfo(ptr->ip, finalize_hook_name, &info)) { @@ -3382,10 +3406,11 @@ ip_free(ptr) Tcl_Eval(ptr->ip, finalize_hook_name); } - del_root(ptr->ip); + /* del_root(ptr->ip); */ DUMP1("delete interp"); - while(!Tcl_InterpDeleted(ptr->ip)) { + /* while(!rbtk_InterpDeleted(ptr->ip)) { */ + if (!Tcl_InterpDeleted(ptr->ip)) { DUMP1("wait ip is deleted"); Tcl_DeleteInterp(ptr->ip); } @@ -3843,24 +3868,34 @@ static VALUE ip_delete(self) VALUE self; { + Tcl_CmdInfo info; struct tcltkip *ptr = get_ip(self); /* Tcl_Preserve(ptr->ip); */ rbtk_preserve_ip(ptr); - if (Tcl_Eval(ptr->ip, "after info") == TCL_OK - && Tcl_SetVar(ptr->ip, - REMAINED_AFTER_IDS_VAR, - Tcl_GetStringResult(ptr->ip), - TCL_GLOBAL_ONLY) != (char *)NULL) { - DUMP1("cancel after scripts"); - Tcl_Eval(ptr->ip, CANCEL_REMAINED_AFTER_IDS); + DUMP1("delete slaves"); + delete_slaves(ptr->ip); + + DUMP1("finalize operation"); + if (Tcl_Eval(ptr->ip, DEF_CANCEL_AFTER_SCRIPTS_PROC) == TCL_OK) { + if (Tcl_GetCommandInfo(ptr->ip, CANCEL_AFTER_SCRIPTS, &info)) { + DUMP2("call cancel after scripts proc '%s'", + CANCEL_AFTER_SCRIPTS); + Tcl_Eval(ptr->ip, CANCEL_AFTER_SCRIPTS); + } + } + + if (Tcl_GetCommandInfo(ptr->ip, finalize_hook_name, &info)) { + DUMP2("call finalize hook proc '%s'", finalize_hook_name); + Tcl_Eval(ptr->ip, finalize_hook_name); } del_root(ptr->ip); DUMP1("delete interp"); - while(!Tcl_InterpDeleted(ptr->ip)) { + /* while(!rbtk_InterpDeleted(ptr->ip)) { */ + if (!Tcl_InterpDeleted(ptr->ip)) { DUMP1("wait ip is deleted"); Tcl_DeleteInterp(ptr->ip); } @@ -3872,6 +3907,30 @@ ip_delete(self) } /* is deleted? */ +static int +ip_null_namespace(interp) + Tcl_Interp *interp; +{ +#if TCL_MAJOR_VERSION < 8 + return 0; +#else /* support Namespace */ + return ( Tcl_GetCurrentNamespace(interp) == (Tcl_Namespace *)NULL ); +#endif +} + +static VALUE +ip_has_null_namespace_p(self) + VALUE self; +{ + struct tcltkip *ptr = get_ip(self); + + if (ip_null_namespace(ptr->ip)) { + return Qtrue; + } else { + return Qfalse; + } +} + static VALUE ip_is_deleted_p(self) VALUE self; @@ -3922,7 +3981,11 @@ ip_get_result_string_obj(interp) # if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 s = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &len); - return(rb_tainted_str_new(s, len)); + if (s == (char*)NULL) { + return rb_tainted_str_new2(""); + } else { + return(rb_tainted_str_new(s, len)); + } # else /* TCL_VERSION >= 8.1 */ volatile VALUE strval; @@ -3937,12 +4000,20 @@ ip_get_result_string_obj(interp) if (Tcl_GetCharLength(retobj) != Tcl_UniCharLen(Tcl_GetUnicode(retobj))) { /* possibly binary string */ s = Tcl_GetByteArrayFromObj(retobj, &len); - strval = rb_tainted_str_new(s, len); + if (s == (char*)NULL) { + strval = rb_tainted_str_new2(""); + } else { + strval = rb_tainted_str_new(s, len); + } rb_ivar_set(strval, ID_at_enc, rb_str_new2("binary")); } else { /* possibly text string */ s = Tcl_GetStringFromObj(retobj, &len); - strval = rb_tainted_str_new(s, len); + if (s == (char*)NULL) { + strval = rb_tainted_str_new2(""); + } else { + strval = rb_tainted_str_new(s, len); + } } rb_thread_critical = thr_crit_bup; @@ -3982,7 +4053,7 @@ ip_eval_real(self, cmd_str, cmd_len) Tcl_IncrRefCount(cmd); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(cmd); rb_thread_critical = thr_crit_bup; @@ -4023,7 +4094,7 @@ ip_eval_real(self, cmd_str, cmd_len) DUMP2("Tcl_Eval(%s)", cmd_str); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); ptr->return_value = TCL_OK; return rb_tainted_str_new2(""); @@ -4228,7 +4299,7 @@ lib_restart(self) rb_secure(4); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); rb_raise(rb_eRuntimeError, "interpreter is deleted"); } @@ -4717,7 +4788,7 @@ ip_invoke_core(interp, argc, argv) ptr = get_ip(interp); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } @@ -5199,7 +5270,7 @@ ip_get_variable(self, varname_arg, flag_arg) Tcl_IncrRefCount(nameobj); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); rb_thread_critical = thr_crit_bup; @@ -5263,7 +5334,7 @@ ip_get_variable(self, varname_arg, flag_arg) char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5335,7 +5406,7 @@ ip_get_variable2(self, varname_arg, index_arg, flag_arg) Tcl_IncrRefCount(idxobj); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); Tcl_DecrRefCount(idxobj); @@ -5400,7 +5471,7 @@ ip_get_variable2(self, varname_arg, index_arg, flag_arg) char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5447,7 +5518,7 @@ ip_set_variable(self, varname_arg, value_arg, flag_arg) varname = varname_arg; value = value_arg; flag = flag_arg; - + StringValue(varname); StringValue(value); @@ -5497,7 +5568,7 @@ ip_set_variable(self, varname_arg, value_arg, flag_arg) # endif /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); Tcl_DecrRefCount(valobj); @@ -5564,7 +5635,7 @@ ip_set_variable(self, varname_arg, value_arg, flag_arg) CONST char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5661,7 +5732,7 @@ ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg) Tcl_IncrRefCount(valobj); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); Tcl_DecrRefCount(nameobj); Tcl_DecrRefCount(idxobj); @@ -5722,7 +5793,7 @@ ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg) CONST char *ret; /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } else { @@ -5766,7 +5837,7 @@ ip_unset_variable(self, varname_arg, flag_arg) StringValue(varname); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return Qtrue; } @@ -5808,7 +5879,7 @@ ip_unset_variable2(self, varname_arg, index_arg, flag_arg) StringValue(index); /* ip is deleted? */ - if (Tcl_InterpDeleted(ptr->ip)) { + if (Tcl_InterpDeleted(ptr->ip) || ip_null_namespace(ptr->ip)) { DUMP1("ip is deleted"); return Qtrue; } @@ -6401,6 +6472,7 @@ Init_tcltklib() rb_define_method(ip, "allow_ruby_exit=", ip_allow_ruby_exit_set, 1); rb_define_method(ip, "delete", ip_delete, 0); rb_define_method(ip, "deleted?", ip_is_deleted_p, 0); + rb_define_method(ip, "null_namespace?", ip_has_null_namespace_p, 0); rb_define_method(ip, "_eval", ip_eval, 1); rb_define_method(ip, "_toUTF8", ip_toUTF8, -1); rb_define_method(ip, "_fromUTF8", ip_fromUTF8, -1); diff --git a/ext/tk/ChangeLog.tkextlib b/ext/tk/ChangeLog.tkextlib index 653c6ef7dd..0bfa0ba5f2 100644 --- a/ext/tk/ChangeLog.tkextlib +++ b/ext/tk/ChangeLog.tkextlib @@ -1,3 +1,33 @@ +2005-01-25 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> + + * ext/tk/lib/tkextlib/blt/component.rb: bug fix. cannot accept + a callback ID string for a command argument. [ruby-dev:25479] + + * ext/tk/lib/tkextlib/blt/tabset.rb: ditto + + * ext/tk/lib/tkextlib/blt/treeview.rb: ditto + + * ext/tk/lib/tkextlib/bwidget/labelentry.rb: ditto + + * ext/tk/lib/tkextlib/bwidget/listbox.rb: ditto + + * ext/tk/lib/tkextlib/bwidget/notebook.rb: ditto + + * ext/tk/lib/tkextlib/bwidget/spinbox.rb: ditto + + * ext/tk/lib/tkextlib/bwidget/tree.rb: ditto + + * ext/tk/lib/tkextlib/itk/incr_tk.rb: ditto + + * ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb: ditto + + * ext/tk/lib/tkextlib/tkDND/tkdnd.rb: ditto + + * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: ditto + + * ext/tk/sample/tkHTML/ss.rb: local variable scope bug fix + [ruby-dev:25479] + 2004-12-24 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> * add BLT extension support diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index d292b5089d..ef4868fdef 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -762,7 +762,11 @@ class MultiTkIp #slave_ip.delete slave_ip._eval_without_enc('exit') end - top.destroy if top.winfo_exist? + begin + top.destroy if top.winfo_exist? + rescue + # ignore + end } tag = TkBindTag.new.bind('Destroy', slave_delete_proc) @@ -1560,10 +1564,14 @@ class << MultiTkIp __getip.delete end - def deleteed? + def deleted? __getip.deleted? end + def null_namespace? + __getip.null_namespace? + end + def abort(msg = nil) __getip.abort(msg) end @@ -1886,6 +1894,10 @@ class MultiTkIp @interp.deleted? end + def null_namespace? + @interp.null_namespace? + end + def abort(msg = nil) if master? if msg @@ -2217,7 +2229,7 @@ class MultiTkIp def set_bgerror_handler(cmd = Proc.new, slave = nil, &b) unless TkComm._callback_entry?(cmd) - unless slave + if !slave && b slave = cmd cmd = Proc.new(&b) end diff --git a/ext/tk/lib/remote-tk.rb b/ext/tk/lib/remote-tk.rb index 1ef5310bde..a2f8a46d4e 100644 --- a/ext/tk/lib/remote-tk.rb +++ b/ext/tk/lib/remote-tk.rb @@ -282,6 +282,10 @@ class RemoteTkIp end end + def null_namespace? + false + end + def restart fail RuntimeError, 'cannot restart the remote interpreter' end diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 9dae5f0899..7f734a0820 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -913,7 +913,7 @@ module TkComm #end def bind(tagOrClass, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -928,7 +928,7 @@ module TkComm #end def bind_append(tagOrClass, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -952,7 +952,7 @@ module TkComm #end def bind_all(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -967,7 +967,7 @@ module TkComm #end def bind_append_all(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -2131,7 +2131,7 @@ module TkBindCore #end def bind(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -2144,7 +2144,7 @@ module TkBindCore #end def bind_append(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -3940,7 +3940,7 @@ end #Tk.freeze module Tk - RELEASE_DATE = '2004-12-27'.freeze + RELEASE_DATE = '2005-01-25'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' diff --git a/ext/tk/lib/tk/bindtag.rb b/ext/tk/lib/tk/bindtag.rb index 737223e3df..9023a08e06 100644 --- a/ext/tk/lib/tk/bindtag.rb +++ b/ext/tk/lib/tk/bindtag.rb @@ -23,6 +23,7 @@ class TkBindTag @id = name BTagID_TBL[@id] = self bind(*args, &b) if args != [] + self } end diff --git a/ext/tk/lib/tk/canvas.rb b/ext/tk/lib/tk/canvas.rb index a0543cc42d..e9a2caccd6 100644 --- a/ext/tk/lib/tk/canvas.rb +++ b/ext/tk/lib/tk/canvas.rb @@ -100,7 +100,7 @@ class TkCanvas<TkWindow #end def itembind(tag, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -115,7 +115,7 @@ class TkCanvas<TkWindow #end def itembind_append(tag, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tk/canvastag.rb b/ext/tk/lib/tk/canvastag.rb index 2eec6e3ca1..b1ac10ba43 100644 --- a/ext/tk/lib/tk/canvastag.rb +++ b/ext/tk/lib/tk/canvastag.rb @@ -27,7 +27,7 @@ module TkcTagAccess #end def bind(seq, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -42,7 +42,7 @@ module TkcTagAccess #end def bind_append(seq, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tk/menu.rb b/ext/tk/lib/tk/menu.rb index 8a33b482c7..e646d56246 100644 --- a/ext/tk/lib/tk/menu.rb +++ b/ext/tk/lib/tk/menu.rb @@ -438,6 +438,7 @@ class TkOptionMenubutton<TkMenubutton parent = nil if args[0].kind_of?(TkWindow) || args[0] == nil + keys.delete('parent') # ignore parent = args.shift else parent = keys.delete('parent') @@ -445,6 +446,7 @@ class TkOptionMenubutton<TkMenubutton @variable = nil if args[0].kind_of?(TkVariable) || args[0] == nil + keys.delete('variable') # ignore @variable = args.shift else @variable = keys.delete('variable') diff --git a/ext/tk/lib/tk/text.rb b/ext/tk/lib/tk/text.rb index 8069adc57a..355153ea07 100644 --- a/ext/tk/lib/tk/text.rb +++ b/ext/tk/lib/tk/text.rb @@ -589,7 +589,7 @@ class TkText<TkTextWin #end def tag_bind(tag, seq, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -604,7 +604,7 @@ class TkText<TkTextWin #end def tag_bind_append(tag, seq, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tk/texttag.rb b/ext/tk/lib/tk/texttag.rb index 1e3a2d7e41..6201c7caa8 100644 --- a/ext/tk/lib/tk/texttag.rb +++ b/ext/tk/lib/tk/texttag.rb @@ -173,7 +173,7 @@ class TkTextTag<TkObject #end def bind(seq, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -188,7 +188,7 @@ class TkTextTag<TkObject #end def bind_append(seq, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/blt/component.rb b/ext/tk/lib/tkextlib/blt/component.rb index 417c1d454b..8e36946d0b 100644 --- a/ext/tk/lib/tkextlib/blt/component.rb +++ b/ext/tk/lib/tkextlib/blt/component.rb @@ -899,7 +899,7 @@ module Tk::BLT end def _component_bind(target, tag, context, *args) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -908,7 +908,7 @@ module Tk::BLT self end def _component_bind_append(target, tag, context, *args) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/blt/tabset.rb b/ext/tk/lib/tkextlib/blt/tabset.rb index 063460f163..693cce5073 100644 --- a/ext/tk/lib/tkextlib/blt/tabset.rb +++ b/ext/tk/lib/tkextlib/blt/tabset.rb @@ -78,7 +78,7 @@ module Tk::BLT #end def bind(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -92,7 +92,7 @@ module Tk::BLT #end def bind_append(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -243,7 +243,7 @@ module Tk::BLT #end def tabbind(tag, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -257,7 +257,7 @@ module Tk::BLT #end def tabbind_append(tag, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/blt/treeview.rb b/ext/tk/lib/tkextlib/blt/treeview.rb index 8001472484..30ee528e7d 100644 --- a/ext/tk/lib/tkextlib/blt/treeview.rb +++ b/ext/tk/lib/tkextlib/blt/treeview.rb @@ -292,7 +292,7 @@ class Tk::BLT::Treeview end def tag_bind(tag, seq, *args) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -301,7 +301,7 @@ class Tk::BLT::Treeview self end def tag_bind_append(tag, seq, *args) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -323,7 +323,7 @@ class Tk::BLT::Treeview end def button_bind(tag, seq, *args) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -332,7 +332,7 @@ class Tk::BLT::Treeview self end def button_bind_append(tag, seq, *args) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/bwidget/labelentry.rb b/ext/tk/lib/tkextlib/bwidget/labelentry.rb index 19e92d7ae4..dc1db06828 100644 --- a/ext/tk/lib/tkextlib/bwidget/labelentry.rb +++ b/ext/tk/lib/tkextlib/bwidget/labelentry.rb @@ -29,7 +29,7 @@ class Tk::BWidget::LabelEntry #end def entrybind(context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -44,7 +44,7 @@ class Tk::BWidget::LabelEntry #end def entrybind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/bwidget/listbox.rb b/ext/tk/lib/tkextlib/bwidget/listbox.rb index 178866f699..3d26081e6c 100644 --- a/ext/tk/lib/tkextlib/bwidget/listbox.rb +++ b/ext/tk/lib/tkextlib/bwidget/listbox.rb @@ -50,7 +50,7 @@ class Tk::BWidget::ListBox #end def imagebind(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -66,7 +66,7 @@ class Tk::BWidget::ListBox #end def imagebind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -91,7 +91,7 @@ class Tk::BWidget::ListBox #end def textbind(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -107,7 +107,7 @@ class Tk::BWidget::ListBox #end def textbind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/bwidget/notebook.rb b/ext/tk/lib/tkextlib/bwidget/notebook.rb index 01299d2de8..2bef13dffd 100644 --- a/ext/tk/lib/tkextlib/bwidget/notebook.rb +++ b/ext/tk/lib/tkextlib/bwidget/notebook.rb @@ -47,7 +47,7 @@ class Tk::BWidget::NoteBook #end def tabbind(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -63,7 +63,7 @@ class Tk::BWidget::NoteBook #end def tabbind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/bwidget/spinbox.rb b/ext/tk/lib/tkextlib/bwidget/spinbox.rb index 52dfa30abc..a5ddfafbf4 100644 --- a/ext/tk/lib/tkextlib/bwidget/spinbox.rb +++ b/ext/tk/lib/tkextlib/bwidget/spinbox.rb @@ -28,7 +28,7 @@ class Tk::BWidget::SpinBox #end def entrybind(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -43,7 +43,7 @@ class Tk::BWidget::SpinBox #end def entrybind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/bwidget/tree.rb b/ext/tk/lib/tkextlib/bwidget/tree.rb index dadf3d5161..5af9f0dc11 100644 --- a/ext/tk/lib/tkextlib/bwidget/tree.rb +++ b/ext/tk/lib/tkextlib/bwidget/tree.rb @@ -47,7 +47,7 @@ class Tk::BWidget::Tree #end def imagebind(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -63,7 +63,7 @@ class Tk::BWidget::Tree #end def imagebind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -88,7 +88,7 @@ class Tk::BWidget::Tree #end def textbind(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -104,7 +104,7 @@ class Tk::BWidget::Tree #end def textbind_append(context, *args) #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/itk/incr_tk.rb b/ext/tk/lib/tkextlib/itk/incr_tk.rb index 1d80e1cd6b..cdc05bde94 100644 --- a/ext/tk/lib/tkextlib/itk/incr_tk.rb +++ b/ext/tk/lib/tkextlib/itk/incr_tk.rb @@ -351,7 +351,7 @@ module Tk end end # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -380,7 +380,7 @@ module Tk end end # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb index 939d97de67..d4b9b48fe0 100644 --- a/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb +++ b/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb @@ -103,7 +103,7 @@ class Tk::Iwidgets::Scrolledcanvas #end def itembind(tag, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -118,7 +118,7 @@ class Tk::Iwidgets::Scrolledcanvas #end def itembind_append(tag, context, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/tkDND/tkdnd.rb b/ext/tk/lib/tkextlib/tkDND/tkdnd.rb index 375ac89518..b75282d3c8 100644 --- a/ext/tk/lib/tkextlib/tkDND/tkdnd.rb +++ b/ext/tk/lib/tkextlib/tkDND/tkdnd.rb @@ -89,7 +89,7 @@ module Tk #end def dnd_bindtarget(type, event, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -129,7 +129,7 @@ module Tk #end def dnd_bindsource(type, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb index 9c1e977d14..e5d58ef79d 100644 --- a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb +++ b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -749,7 +749,7 @@ class Tk::TreeCtrl #end def notify_bind(obj, event, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new @@ -764,7 +764,7 @@ class Tk::TreeCtrl #end def notify_bind_append(obj, event, *args) # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) - if TkComm._callback_entry?(args[0]) + if TkComm._callback_entry?(args[0]) || !block_given? cmd = args.shift else cmd = Proc.new diff --git a/ext/tk/sample/demos-en/anilabel.rb b/ext/tk/sample/demos-en/anilabel.rb new file mode 100644 index 0000000000..36989c5c91 --- /dev/null +++ b/ext/tk/sample/demos-en/anilabel.rb @@ -0,0 +1,172 @@ +# +# animated label widget demo (called by 'widget') +# +# based on Tcl/Tk8.5a2 widget demos + +if defined?($anilabel_demo) && $anilabel_demo + $anilabel_demo.destroy + $anilabel_demo = nil +end + +# demo toplevel widget +$anilabel_demo = TkToplevel.new {|w| + title("Animated Label Demonstration") + iconname("anilabel") + positionWindow(w) +} + +# label +msg = TkLabel.new($anilabel_demo) { + font $font + wraplength '4i' + justify 'left' + text "Four animated labels are displayed below; each of the labels on the left is animated by making the text message inside it appear to scroll, and the label on the right is animated by animating the image that it displays." +} +msg.pack('side'=>'top') + +# frame +TkFrame.new($anilabel_demo) {|frame| + TkButton.new(frame) { + text 'Dismiss' + command proc{ + tmppath = $anilabel_demo + $anilabel_demo = nil + tmppath.destroy + } + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'See Code' + command proc{showCode 'label'} + }.pack('side'=>'left', 'expand'=>'yes') + +}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# create frame for label demo +f_left = TkLabelFrame.new($anilabel_demo, :text=>'Scrolling Texts') +f_right = TkLabelFrame.new($anilabel_demo, :text=>'GIF Image') +Tk.pack(f_left, f_right, 'side'=>'left', 'expand'=>'yes', 'fill'=>'both', + 'padx'=>10, 'pady'=>10) + +# animated label +class AnimatedTextLabel < TkLabel + def initialize(*args) + super(*args) + @timer = TkTimer.new{ _animation_callback } + @timer.loop_exec = -1 + # bind('Destroy'){ @timer.stop } + @btag = TkBindTag.new('Destroy'){ @timer.stop } + self.bindtags_unshift(@btag) + end + + def _animation_callback() + txt = self.text + self.text = (txt[1..-1] << txt[0]) + end + private :_animation_callback + + def start(interval) + @timer.set_interval(interval) + @timer.start + end + + def stop + @timer.stop + end +end + +# animated image +class AnimatedImageLabel < AnimatedTextLabel + def initialize(*args) + super(*args) + @destroy_image = false + @btag.bind_append('Destroy'){ + if @destroy_image + begin + self.image.delete + rescue + end + end + } + end + attr_accessor :destroy_image + + def _animation_callback() + img = self.image + + fmt = img.format + if fmt.kind_of?(Array) + if fmt[1].kind_of?(Hash) + # fmt == ['GIF', {'index'=>idx}] + idx = fmt[1]['index'] + else + # fmt == ['GIF', '-index', idx] :: Ruby1.8.2 returns this. + idx = fmt[2] + end + elsif fmt.kind_of?(String) && fmt =~ /GIF -index (\d+)/ + idx = $1.to_i + else + idx = -1 + end + + begin + img.format("GIF -index #{idx + 1}") + rescue => e + img.format("GIF -index 0") + end + end + private :_animation_callback +end + +# create labels +l1 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:ridge, + :font=>{:family=>'Courier', :size=>10}) +l2 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:groove, + :font=>{:family=>'Courier', :size=>10}) +l3 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:flat, + :font=>{:family=>'Courier', :size=>10}, :width=>18) +Tk.pack(l1, l2, l3, + :side=>:top, :expand=>true, :anchor=>:w, :padx=>10, :pady=>10) + +limg = AnimatedImageLabel.new(f_right, :borderwidth=>0) +limg.pack(:side=>:top, :expand=>true, :padx=>10, :pady=>10) + +# base64-encoded animated GIF file +tclPowerdData = <<EOD + R0lGODlhKgBAAPQAAP//////zP//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM + zMyZmcyZZsxmZsxmAMwzAJnMzJmZzJmZmZlmmZlmZplmM5kzM2aZzGZmzGZm + mWZmZmYzZmYzMzNmzDMzZgAzmSH+IE1hZGUgd2l0aCBHSU1QIGJ5IExARGVt + YWlsbHkuY29tACH5BAVkAAEALAAAAAAqAEAAAAX+YCCOZEkyTKM2jOm66yPP + dF03bx7YcuHIDkGBR7SZeIyhTID4FZ+4Es8nQyCe2EeUNJ0peY2s9mi7PhAM + ngEAMGRbUpvzSxskLh1J+Hkg134OdDIDEB+GHxtYMEQMTjMGEYeGFoomezaC + DZGSHFmLXTQKkh8eNQVpZ2afmDQGHaOYSoEyhhcklzVmMpuHnaZmDqiGJbg0 + qFqvh6UNAwB7VA+OwydEjgujkgrPNhbTI8dFvNgEYcHcHx0lB1kX2IYeA2G6 + NN0YfkXJ2BsAMuAzHB9cZMk3qoEbRzUACsRCUBK5JxsC3iMiKd8GN088SIyT + 0RAFSROyeEg38caDiB/+JEgqxsODrZJ1BkT0oHKSmI0ceQxo94HDpg0qsuDk + UmRAMgu8OgwQ+uIJgUMVeGXA+IQkzEeHGvD8cIGlDXsLiRjQ+EHroQhea7xY + 8IQBSgYYDi1IS+OFBCgaDMGVS3fGi5BPJpBaENdQ0EomKGD56IHwO39EXiSC + Ysgxor5+Xfgq0qByYUpiXmwuoredB2aYH4gWWda0B7SeNENpEJHC1ghi+pS4 + AJpIAwWvKPBi+8YEht5EriEqpFfMlhEdkBNpx0HUhwypx5T4IB1MBg/Ws2sn + wV3MSQOkzI8fUd48Aw3dOZto71x85hHtHijYv18Gf/3GqCdDCXHNoICBobSo + IqBqJLyCoH8JPrLgdh88CKCFD0CGmAiGYPgffwceZh6FC2ohIIklnkhehTNY + 4CIHHGzgwYw01ujBBhvAqKOLLq5AAk9kuSPkkKO40NB+h1gnypJIIvkBf09a + N5QIRz5p5ZJXJpmlIVhOGQA2TmIJZZhKKmmll2BqyWSXWUrZpQtpatlmk1c2 + KaWRHeTZEJF8SqLDn/hhsOeQgBbqAh6DGqronxeARUIIACH5BAUeAAAALAUA + LgAFAAUAAAUM4CeKz/OV5YmqaRkCACH5BAUeAAEALAUALgAKAAUAAAUUICCK + z/OdJVCaa7p+7aOWcDvTZwgAIfkEBR4AAQAsCwAuAAkABQAABRPgA4zP95zA + eZqoWqqpyqLkZ38hACH5BAUKAAEALAcALgANAA4AAAU7ICA+jwiUJEqeKau+ + r+vGaTmac63v/GP9HM7GQyx+jsgkkoRUHJ3Qx0cK/VQVTKtWwbVKn9suNunc + WkMAIfkEBQoAAAAsBwA3AAcABQAABRGgIHzk842j+Yjlt5KuO8JmCAAh+QQF + CgAAACwLADcABwAFAAAFEeAnfN9TjqP5oOWziq05lmUIACH5BAUKAAAALA8A + NwAHAAUAAAUPoPCJTymS3yiQj4qOcPmEACH5BAUKAAAALBMANwAHAAUAAAUR + oCB+z/MJX2o+I2miKimiawgAIfkEBQoAAAAsFwA3AAcABQAABRGgIHzfY47j + Q4qk+aHl+pZmCAAh+QQFCgAAACwbADcABwAFAAAFEaAgfs/zCV9qPiNJouo7 + ll8IACH5BAUKAAAALB8ANwADAAUAAAUIoCB8o0iWZggAOw== +EOD + +l1.text('* Slow Animation *').start(300) +l2.text('* Fast Animation *').start(80) +l3.text('This is a longer scrolling text in a widget that will not show the whole message at once. ').start(150) + +limg.destroy_image = true +limg.image(TkPhotoImage.new(:format=>'GIF', :data=>tclPowerdData)).start(100) diff --git a/ext/tk/sample/demos-en/widget b/ext/tk/sample/demos-en/widget index 9df91c467b..1a4fb0b96d 100644 --- a/ext/tk/sample/demos-en/widget +++ b/ext/tk/sample/demos-en/widget @@ -389,6 +389,11 @@ txt.insert('end', "3. Color picker.\n", tag_demo, "demo-clrpick") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") +txt.insert('end', "Animation\n", tag_title) +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "1. Animated labels (if supported)\n", tag_demo, "demo-anilabel") + +txt.insert('end', "\n") txt.insert('end', "Miscellaneous\n", tag_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. The built-in bitmaps.\n", tag_demo, "demo-bitmap") @@ -780,7 +785,7 @@ end # def aboutBox Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', - 'message'=>"Ruby/Tk widget demonstration Ver.1.4.4-en\n\n" + + 'message'=>"Ruby/Tk widget demonstration Ver.1.5.0-en\n\n" + "based on demos of Tk8.1 -- 8.5 " + "( Copyright:: " + "(c) 1996-1997 Sun Microsystems, Inc. / " + diff --git a/ext/tk/sample/demos-jp/anilabel.rb b/ext/tk/sample/demos-jp/anilabel.rb new file mode 100644 index 0000000000..8cbec50167 --- /dev/null +++ b/ext/tk/sample/demos-jp/anilabel.rb @@ -0,0 +1,174 @@ +# +# animated label widget demo (called by 'widget') +# +# based on Tcl/Tk8.5a2 widget demos + +# toplevel widget が存在すれば削除する +if defined?($anilabel_demo) && $anilabel_demo + $anilabel_demo.destroy + $anilabel_demo = nil +end + +# demo 用の toplevel widget を生成 +$anilabel_demo = TkToplevel.new {|w| + title("Animated Label Demonstration") + iconname("anilabel") + positionWindow(w) +} + +# label 生成 +msg = TkLabel.new($anilabel_demo) { + font $font + wraplength '4i' + justify 'left' + text "下には4つのアニメーションラベルが表示されています。左側にあるラベルは、内部のテキストメッセージをスクロールしたように見せることで動きを付けています。右側のラベルは、表示するイメージを変化させることで動きを与えています。" +} +msg.pack('side'=>'top') + +# frame 生成 +TkFrame.new($anilabel_demo) {|frame| + TkButton.new(frame) { + #text '了解' + text '閉じる' + command proc{ + tmppath = $anilabel_demo + $anilabel_demo = nil + tmppath.destroy + } + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'コード参照' + command proc{showCode 'label'} + }.pack('side'=>'left', 'expand'=>'yes') + +}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# label demo 用フレーム生成 +f_left = TkLabelFrame.new($anilabel_demo, :text=>'Scrolling Texts') +f_right = TkLabelFrame.new($anilabel_demo, :text=>'GIF Image') +Tk.pack(f_left, f_right, 'side'=>'left', 'expand'=>'yes', 'fill'=>'both', + 'padx'=>10, 'pady'=>10) + +# animated label +class AnimatedTextLabel < TkLabel + def initialize(*args) + super(*args) + @timer = TkTimer.new{ _animation_callback } + @timer.loop_exec = -1 + # bind('Destroy'){ @timer.stop } + @btag = TkBindTag.new('Destroy'){ @timer.stop } + self.bindtags_unshift(@btag) + end + + def _animation_callback() + txt = self.text + self.text = (txt[1..-1] << txt[0]) + end + private :_animation_callback + + def start(interval) + @timer.set_interval(interval) + @timer.start + end + + def stop + @timer.stop + end +end + +# animated image +class AnimatedImageLabel < AnimatedTextLabel + def initialize(*args) + super(*args) + @destroy_image = false + @btag.bind_append('Destroy'){ + if @destroy_image + begin + self.image.delete + rescue + end + end + } + end + attr_accessor :destroy_image + + def _animation_callback() + img = self.image + + fmt = img.format + if fmt.kind_of?(Array) + if fmt[1].kind_of?(Hash) + # fmt == ['GIF', {'index'=>idx}] + idx = fmt[1]['index'] + else + # fmt == ['GIF', '-index', idx] :: Ruby1.8.2 returns this. + idx = fmt[2] + end + elsif fmt.kind_of?(String) && fmt =~ /GIF -index (\d+)/ + idx = $1.to_i + else + idx = -1 + end + + begin + img.format("GIF -index #{idx + 1}") + rescue => e + img.format("GIF -index 0") + end + end + private :_animation_callback +end + +# label 生成 +l1 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:ridge, + :font=>{:family=>'Courier', :size=>10}) +l2 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:groove, + :font=>{:family=>'Courier', :size=>10}) +l3 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:flat, + :font=>{:family=>'Courier', :size=>10}, :width=>18) +Tk.pack(l1, l2, l3, + :side=>:top, :expand=>true, :anchor=>:w, :padx=>10, :pady=>10) + +limg = AnimatedImageLabel.new(f_right, :borderwidth=>0) +limg.pack(:side=>:top, :expand=>true, :padx=>10, :pady=>10) + +# base64-encoded animated GIF file +tclPowerdData = <<EOD + R0lGODlhKgBAAPQAAP//////zP//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM + zMyZmcyZZsxmZsxmAMwzAJnMzJmZzJmZmZlmmZlmZplmM5kzM2aZzGZmzGZm + mWZmZmYzZmYzMzNmzDMzZgAzmSH+IE1hZGUgd2l0aCBHSU1QIGJ5IExARGVt + YWlsbHkuY29tACH5BAVkAAEALAAAAAAqAEAAAAX+YCCOZEkyTKM2jOm66yPP + dF03bx7YcuHIDkGBR7SZeIyhTID4FZ+4Es8nQyCe2EeUNJ0peY2s9mi7PhAM + ngEAMGRbUpvzSxskLh1J+Hkg134OdDIDEB+GHxtYMEQMTjMGEYeGFoomezaC + DZGSHFmLXTQKkh8eNQVpZ2afmDQGHaOYSoEyhhcklzVmMpuHnaZmDqiGJbg0 + qFqvh6UNAwB7VA+OwydEjgujkgrPNhbTI8dFvNgEYcHcHx0lB1kX2IYeA2G6 + NN0YfkXJ2BsAMuAzHB9cZMk3qoEbRzUACsRCUBK5JxsC3iMiKd8GN088SIyT + 0RAFSROyeEg38caDiB/+JEgqxsODrZJ1BkT0oHKSmI0ceQxo94HDpg0qsuDk + UmRAMgu8OgwQ+uIJgUMVeGXA+IQkzEeHGvD8cIGlDXsLiRjQ+EHroQhea7xY + 8IQBSgYYDi1IS+OFBCgaDMGVS3fGi5BPJpBaENdQ0EomKGD56IHwO39EXiSC + Ysgxor5+Xfgq0qByYUpiXmwuoredB2aYH4gWWda0B7SeNENpEJHC1ghi+pS4 + AJpIAwWvKPBi+8YEht5EriEqpFfMlhEdkBNpx0HUhwypx5T4IB1MBg/Ws2sn + wV3MSQOkzI8fUd48Aw3dOZto71x85hHtHijYv18Gf/3GqCdDCXHNoICBobSo + IqBqJLyCoH8JPrLgdh88CKCFD0CGmAiGYPgffwceZh6FC2ohIIklnkhehTNY + 4CIHHGzgwYw01ujBBhvAqKOLLq5AAk9kuSPkkKO40NB+h1gnypJIIvkBf09a + N5QIRz5p5ZJXJpmlIVhOGQA2TmIJZZhKKmmll2BqyWSXWUrZpQtpatlmk1c2 + KaWRHeTZEJF8SqLDn/hhsOeQgBbqAh6DGqronxeARUIIACH5BAUeAAAALAUA + LgAFAAUAAAUM4CeKz/OV5YmqaRkCACH5BAUeAAEALAUALgAKAAUAAAUUICCK + z/OdJVCaa7p+7aOWcDvTZwgAIfkEBR4AAQAsCwAuAAkABQAABRPgA4zP95zA + eZqoWqqpyqLkZ38hACH5BAUKAAEALAcALgANAA4AAAU7ICA+jwiUJEqeKau+ + r+vGaTmac63v/GP9HM7GQyx+jsgkkoRUHJ3Qx0cK/VQVTKtWwbVKn9suNunc + WkMAIfkEBQoAAAAsBwA3AAcABQAABRGgIHzk842j+Yjlt5KuO8JmCAAh+QQF + CgAAACwLADcABwAFAAAFEeAnfN9TjqP5oOWziq05lmUIACH5BAUKAAAALA8A + NwAHAAUAAAUPoPCJTymS3yiQj4qOcPmEACH5BAUKAAAALBMANwAHAAUAAAUR + oCB+z/MJX2o+I2miKimiawgAIfkEBQoAAAAsFwA3AAcABQAABRGgIHzfY47j + Q4qk+aHl+pZmCAAh+QQFCgAAACwbADcABwAFAAAFEaAgfs/zCV9qPiNJouo7 + ll8IACH5BAUKAAAALB8ANwADAAUAAAUIoCB8o0iWZggAOw== +EOD + +l1.text('* Slow Animation *').start(300) +l2.text('* Fast Animation *').start(80) +l3.text('This is a longer scrolling text in a widget that will not show the whole message at once. ').start(150) + +limg.destroy_image = true +limg.image(TkPhotoImage.new(:format=>'GIF', :data=>tclPowerdData)).start(100) diff --git a/ext/tk/sample/demos-jp/widget b/ext/tk/sample/demos-jp/widget index 6eaaece4c4..3be05c167c 100644 --- a/ext/tk/sample/demos-jp/widget +++ b/ext/tk/sample/demos-jp/widget @@ -438,6 +438,12 @@ txt.insert('end', "3. 色選択ダイアログ\n", tag_demo, "demo-clrpick") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") +#txt.insert('end', "アニメーション\n", tag_middle) +txt.insert('end', "アニメーション\n", tag_kanji_title) +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "1. アニメーションラベル (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-anilabel") + +txt.insert('end', "\n") #txt.insert('end', "その他\n", tag_middle) txt.insert('end', "その他\n", tag_kanji_title) txt.insert('end', " \n ", tag_demospace) @@ -807,7 +813,7 @@ end # def aboutBox Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', - 'message'=>"Ruby/Tk ウィジェットデモ Ver.1.4.4-jp\n\n" + + 'message'=>"Ruby/Tk ウィジェットデモ Ver.1.5.0-jp\n\n" + "based on demos of Tk8.1 -- 8.5 " + "( Copyright:: " + "(c) 1996-1997 Sun Microsystems, Inc. / " + diff --git a/ext/tk/sample/tkextlib/tkHTML/ss.rb b/ext/tk/sample/tkextlib/tkHTML/ss.rb index 179bdc13cd..3dbb7ec716 100644 --- a/ext/tk/sample/tkextlib/tkHTML/ss.rb +++ b/ext/tk/sample/tkextlib/tkHTML/ss.rb @@ -159,6 +159,8 @@ href_binding = proc{|w, x, y| # # last_dir = Dir.pwd +load_file = nil + sel_load = proc{ filetypes = [ ['Html Files', ['.html', '.htm']], diff --git a/ext/tk/tkutil.c b/ext/tk/tkutil.c index e36f92af04..d88f7b9a72 100644 --- a/ext/tk/tkutil.c +++ b/ext/tk/tkutil.c @@ -8,7 +8,7 @@ ************************************************/ -#define TKUTIL_RELEASE_DATE "2004-12-23" +#define TKUTIL_RELEASE_DATE "2005-01-25" #include "ruby.h" #include "rubysig.h" @@ -824,6 +824,8 @@ tcl2rb_bool(self, value) value = rb_funcall(value, ID_downcase, 0); + if (RSTRING(value)->ptr == (char*)NULL) return Qnil; + if (RSTRING(value)->ptr[0] == '\0' || strcmp(RSTRING(value)->ptr, "0") == 0 || strcmp(RSTRING(value)->ptr, "no") == 0 @@ -880,6 +882,8 @@ tkstr_to_number(value) { rb_check_type(value, T_STRING); + if (RSTRING(value)->ptr == (char*)NULL) return INT2FIX(0); + return rb_rescue2(tkstr_to_int, value, tkstr_rescue_float, value, rb_eArgError, 0); @@ -916,6 +920,8 @@ tcl2rb_string(self, value) { rb_check_type(value, T_STRING); + if (RSTRING(value)->ptr == (char*)NULL) return rb_tainted_str_new2(""); + return tkstr_to_str(value); } @@ -926,6 +932,8 @@ tcl2rb_num_or_str(self, value) { rb_check_type(value, T_STRING); + if (RSTRING(value)->ptr == (char*)NULL) return rb_tainted_str_new2(""); + return rb_rescue2(tkstr_to_number, value, tkstr_to_str, value, rb_eArgError, 0); |