diff --git a/ChangeLog b/ChangeLog index 0586d30c34..b1d02562cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sun May 2 01:04:38 2004 Hidetoshi NAGAI + + * ext/tcltklib, ext/tk: renewal Ruby/Tk + Fri Apr 30 20:08:41 2004 WATANABE Hirofumi * time.c (SIZEOF_TIME_T): support SIZEOF_TIME_T == SIZEOF_INT. diff --git a/ext/tcltklib/MANIFEST b/ext/tcltklib/MANIFEST index e06547a6aa..e408dc3ee8 100644 --- a/ext/tcltklib/MANIFEST +++ b/ext/tcltklib/MANIFEST @@ -11,6 +11,8 @@ lib/tcltk.rb demo/lines0.tcl demo/lines1.rb demo/lines2.rb +demo/lines3.rb +demo/lines4.rb demo/safeTk.rb sample/sample0.rb sample/sample1.rb diff --git a/ext/tcltklib/MANUAL.eng b/ext/tcltklib/MANUAL.eng index a037d18d41..20e966d223 100644 --- a/ext/tcltklib/MANUAL.eng +++ b/ext/tcltklib/MANUAL.eng @@ -1,5 +1,5 @@ (tof) - 2003/10/17 Hidetoshi NAGAI + 2004/03/28 Hidetoshi NAGAI This document discribes about the 'tcltklib' library. Although there is the 'tcltk' library (tcltk.rb) under this directory, no description @@ -41,224 +41,367 @@ module TclTklib : a target event. With this flag, doesn't wait and returns : false if there is no target event for processing. - [module methods] - mainloop(check_root = true) - : Starts the eventloop. If 'check_root' is true, this method - : doesn't return when a root widget exists. - : If 'check_root' is false, doen't return by the other - : reasons than exceptions. + module TclTkLib::VarAccessFlag + : Defines flags to give '_get_variable' and so on. When to give, + : please use bit-operator (e.g. GLOBAL_ONLY | LEAVE_ERR_MSG ). - mainloop_watchdog(check_root = true) - : On the normal eventloop, some kinds of callback operations - : cause deadlock. To avoid some of such deadlocks, this - : method starts an eventloop and a watchdog-thread. + [constants] + NONE + : Is 0. It means "set no flag". - do_one_event(flag = TclTkLib::EventFlag::ALL | - TclTkLib::EventFlag::DONT_WAIT) - : Do one event for processing. When processed an event, - : returns true. - : If NOT set DONT_WAIT flag, this method waits occurrence of - : a target event. - : If set DONT_WAIT flag and no event for processing, returns - : false immediately. - : If $SAFE >= 4, or $SAFE >= 1 and the flag is tainted, - : force to set DONT_WAIT flag. + GLOBAL_ONLY + : (site Tcl/Tk's man page) + : Under normal circumstances the procedures look up + : variables as follows: If a procedure call is active + : in interp, a variable is looked up at the current + : level of procedure call. Otherwise, a variable is + : looked up first in the current namespace, then in + : the global namespace. However, if this bit is set + : in flags then the variable is looked up only in the + : global namespace even if there is a procedure call + : active. If both GLOBAL_ONLY and NAMESPACE_ONLY are + : given, GLOBAL_ONLY is ignored. + : + : *** ATTENTION *** + : Tcl7.6 doesn't have namespaces. So NAMESPACE_ONLY + : is defined as 0, and then GLOBAL_ONLY is available + : even if flag is (GLOBAL_ONLY | NAMESPACE_ONLY). - set_eventloop_tick(timer_tick) - : Define the interval of thread-switching with an integer - : value of mili-seconds. - : Default timer_tick is 0. It means that thread-switching - : is based on the count of processed events. - : ( see 'set_eventloop_weight' method ) - : However, if the eventloop thread is the only thread, - : timer_tick cannt be set to 0. If 0, then is set to 100 ms - : automatically (see NO_THREAD_INTERRUPT_TIME on tcltklib.c). - : On $SAFE >= 4, cannot call this method. + NAMESPACE_ONLY + : (site Tcl/Tk's man page) + : Under normal circumstances the procedures look up + : variables as follows: If a procedure call is active + : in interp, a variable is looked up at the current + : level of procedure call. Otherwise, a variable is + : looked up first in the current namespace, then in + : the global namespace. However, if this bit is set + : in flags then the variable is looked up only in the + : current namespace even if there is a procedure call + : active. + : + : *** ATTENTION *** + : Tcl7.6 doesn't have namespaces. So NAMESPACE_ONLY + : is defined as 0. - get_eventloop_tick - : Get current value of 'timer_tick' + LEAVE_ERR_MSG + : (site Tcl/Tk's man page) + : If an error is returned and this bit is set in flags, + : then an error message will be left in the interpreter's + : result, where it can be retrieved with Tcl_GetObjResult + : or Tcl_GetStringResult. If this flag bit isn't set then + : no error message is left and the interpreter's result + : will not be modified. - set_no_event_wait(no_event_wait) - : Define sleeping time of the eventloop when two or more - : thread are running and there is no event for processing. - : Default value is 20 (ms). - : If the eventloop thread is the only thread, this value is - : invalid. - : On $SAFE >= 4, cannot call this method. + APPEND_VALUE + : (site Tcl/Tk's man page) + : If this bit is set then newValue is appended to the + : current value, instead of replacing it. If the variable + : is currently undefined, then this bit is ignored. - get_no_event_wait - : Get current value of 'no_event_wait'. + LIST_ELEMENT + : (site Tcl/Tk's man page) + : If this bit is set, then newValue is converted to a + : valid Tcl list element before setting (or appending + : to) the variable. A separator space is appended before + : the new list element unless the list element is going + : to be the first element in a list or sublist (i.e. the + : variable's current value is empty, or contains the + : single character ``{'', or ends in `` }''). - set_eventloop_weight(loop_max, no_event_tick) - : Define the weight parameters for the eventloop thread. - : That is invalid when the eventloop is the only thread. - : 'loop_max' is the max events for thread-switching. - : 'no_event_tick' is the increment value of the event count - : when no event for processing (And then, the eventloop thead - : sleeps 'no_event_wait' mili-seconds). - : 'loop_max == 800' and 'no_event_tick == 10' are defalut. - : On $SAFE >= 4, cannot call this method. + PARSE_VARNAME + : (site Tcl/Tk's man page) + : If this bit is set when calling _set_variable and so + : on, var_name argument may contain both an array and an + : element name: if the name contains an open parenthesis + : and ends with a close parenthesis, then the value + : between the parentheses is treated as an element name + : (which can have any string value) and the characters + : before the first open parenthesis are treated as the + : name of an array variable. If the flag PARSE_VARNAME + : is given, index_name argument should be 'nil' since the + : array and element names are taken from var_name. + : + : *** ATTENTION *** + : Tcl7.6 doesn't have this flag. So PARSE_VARNAME is + : defined as 0. - get_eventloop_weight - : Get current values of 'loop_max' and 'no_event_tick'. + [module methods] + mainloop(check_root = true) + : Starts the eventloop. If 'check_root' is true, this method + : doesn't return when a root widget exists. + : If 'check_root' is false, doen't return by the other + : reasons than exceptions. - mainloop_abort_on_exception=(bool) - : Define whether the eventloop stops on exception or not. - : If true (default value), stops on exception. - : If false, show a warinig message but ignore the exception. - : If nil, no warning message and ignore the excepsion. - : This parameter is sometimes useful when multiple Tk - : interpreters are working. Because the only one eventloop - : admins all Tk interpreters, sometimes exception on a - : interpreter kills the eventloop thread. Even if such - : situation, when abort_on_exception == false or nil, - : the eventloop ignores the exception and continue to working. - : On $SAFE >= 4, cannot call this method. + mainloop_watchdog(check_root = true) + : On the normal eventloop, some kinds of callback operations + : cause deadlock. To avoid some of such deadlocks, this + : method starts an eventloop and a watchdog-thread. - mainloop_abort_on_exception - : Get current status of that. + do_one_event(flag = TclTkLib::EventFlag::ALL | + TclTkLib::EventFlag::DONT_WAIT) + : Do one event for processing. When processed an event, + : returns true. + : If NOT set DONT_WAIT flag, this method waits occurrence of + : a target event. + : If set DONT_WAIT flag and no event for processing, returns + : false immediately. + : If $SAFE >= 4, or $SAFE >= 1 and the flag is tainted, + : force to set DONT_WAIT flag. - num_of_mainwindows - : Returns the number of main-windows (root-widget). - : Because there is only one main-window for one Tk interpreter, - : the value is same to the number of interpreters which has - : available Tk functions. + set_eventloop_tick(timer_tick) + : Define the interval of thread-switching with an integer + : value of mili-seconds. + : Default timer_tick is 0. It means that thread-switching + : is based on the count of processed events. + : ( see 'set_eventloop_weight' method ) + : However, if the eventloop thread is the only thread, + : timer_tick cannt be set to 0. If 0, then is set to 100 ms + : automatically (see NO_THREAD_INTERRUPT_TIME on tcltklib.c). + : On $SAFE >= 4, cannot call this method. + get_eventloop_tick + : Get current value of 'timer_tick' + + set_no_event_wait(no_event_wait) + : Define sleeping time of the eventloop when two or more + : thread are running and there is no event for processing. + : Default value is 20 (ms). + : If the eventloop thread is the only thread, this value is + : invalid. + : On $SAFE >= 4, cannot call this method. + + get_no_event_wait + : Get current value of 'no_event_wait'. + + set_eventloop_weight(loop_max, no_event_tick) + : Define the weight parameters for the eventloop thread. + : That is invalid when the eventloop is the only thread. + : 'loop_max' is the max events for thread-switching. + : 'no_event_tick' is the increment value of the event count + : when no event for processing (And then, the eventloop thead + : sleeps 'no_event_wait' mili-seconds). + : 'loop_max == 800' and 'no_event_tick == 10' are defalut. + : On $SAFE >= 4, cannot call this method. + + get_eventloop_weight + : Get current values of 'loop_max' and 'no_event_tick'. + + mainloop_abort_on_exception=(bool) + : Define whether the eventloop stops on exception or not. + : If true (default value), stops on exception. + : If false, show a warinig message but ignore the exception. + : If nil, no warning message and ignore the excepsion. + : This parameter is sometimes useful when multiple Tk + : interpreters are working. Because the only one eventloop + : admins all Tk interpreters, sometimes exception on a + : interpreter kills the eventloop thread. Even if such + : situation, when abort_on_exception == false or nil, + : the eventloop ignores the exception and continue to working. + : On $SAFE >= 4, cannot call this method. + + mainloop_abort_on_exception + : Get current status of that. + + num_of_mainwindows + : Returns the number of main-windows (root-widget). + : Because there is only one main-window for one Tk interpreter, + : the value is same to the number of interpreters which has + : available Tk functions. + + _merge_tklist(str, str, ... ) + : Get a Tcl's list string from arguments with a Tcl/Tk's + : library function. Each arguemnt is converted to a valid + : Tcl list element. + + _conv_listelement(str) + : Convert the argument to a valid Tcl list element with + : Tcl/Tk's library function. + + _toUTF8(str, encoding) + _fromUTF8(str, encoding) + : Call the function (which is internal function of Tcl/Tk) to + : convert to/from a UTF8 string. + + _subst_UTF_backslash(str) + _subst_Tcl_backslash(str) + : Substitute backslash sequence with Tcl's rule (include \uhhhh; + : give a sixteen-bit hexadecimal value for Unicode character). + : _subst_Tcl_backslash method parses all backslash sequence. + : _subst_UTF_backslash method parses \uhhhh only. class TclTkIp [class methods] - new(ip_name=nil, options='') - : Generate an instance of TclTkIp class. - : If 'ip_name' argument is given as a string, it is the name - : of the Tk interpreter which is shown by 'winfo interps' - : command. - : 'options' argument accepts a string which is the command - : line options of wish; such as '-geometry' or '-use'. - : The information is used to generate the root widget of the - : interpreter. - : ( e.g. TclTkIp.new('FOO', '-geometry 500x200 -use 0x2200009') ) - : If is given nil or falsr for the 'option' argument, generates - : the Tcl interpreter without Tk library. Then the interpreter - : doesn't need GUI environment. Therefore, even if a window - : system doesn't exist or cannot be used, Ruby can control the - : Tcl interpreter and the extention libraries loaded on the - : interpreter. + new(ip_name=nil, options='') + : Generate an instance of TclTkIp class. + : If 'ip_name' argument is given as a string, it is the name + : of the Tk interpreter which is shown by 'winfo interps' + : command. + : 'options' argument accepts a string which is the command + : line options of wish; such as '-geometry' or '-use'. + : The information is used to generate the root widget of the + : interpreter. + : ( e.g. TclTkIp.new('FOO', '-geometry 500x200 -use 0x2200009') ) + : If is given nil or falsr for the 'option' argument, generates + : the Tcl interpreter without Tk library. Then the interpreter + : doesn't need GUI environment. Therefore, even if a window + : system doesn't exist or cannot be used, Ruby can control the + : Tcl interpreter and the extention libraries loaded on the + : interpreter. - [instance methods] - create_slave(name, safe=false) - : Create a slave interpreter. - : The parent of the interpreter is the receiver of this method. - : The name of the slave interpreter is given by 'name' argument. - : The 'safe' argument decides whether the slave interpreter is - : created as a safe interpreter or not. If true, create a safe - : interpreter. Default is false. However, if the parent - : interpreter is a safe interpreter, the created interpreter is - : a safe interpreter (ignore 'safe' argument value). - : If $SAFE >= 4, can create a safe interpreter only. + [instance methods] + create_slave(name, safe=false) + : Create a slave interpreter. + : The parent of the interpreter is the receiver of this method. + : The name of the slave interpreter is given by 'name' argument. + : The 'safe' argument decides whether the slave interpreter is + : created as a safe interpreter or not. If true, create a safe + : interpreter. Default is false. However, if the parent + : interpreter is a safe interpreter, the created interpreter is + : a safe interpreter (ignore 'safe' argument value). + : If $SAFE >= 4, can create a safe interpreter only. - make_safe - : Make the interpreter to the safe interpreter, and returns - : self. If fail, raise RuntimeError. + make_safe + : Make the interpreter to the safe interpreter, and returns + : self. If fail, raise RuntimeError. - safe? - : Check whether the interpreter is the safe interpreter. - : If is the safe interpreter, returns true. + safe? + : Check whether the interpreter is the safe interpreter. + : If is the safe interpreter, returns true. - delete - : Delete the interpreter. - : The deleted interpreter doesn't accept command and then - : raise an exception. + delete + : Delete the interpreter. + : The deleted interpreter doesn't accept command and then + : raise an exception. - deleted? - : Check whether the interpreter is already deleted. - : If deleted, returns true. + deleted? + : Check whether the interpreter is already deleted. + : If deleted, returns true. - restart - : Restart Tk part of the interpreter. - : Use this when you need Tk functions after destroying the - : root widget. - : On $SAFE >= 4, cannot call this method. + restart + : Restart Tk part of the interpreter. + : Use this when you need Tk functions after destroying the + : root widget. + : On $SAFE >= 4, cannot call this method. - _eval(str) - _invoke(*args) - : Estimates the arguments as a command on the Tk interpreter. - : The argument of _eval is a script of Tcl/Tk. - : Each argument of _invoke is a token of one command line of - : Tcl/Tk. - : Because the operation of _invoke doesn't through the - : command line parser of Tk interpreter, the cost of - : estimation is smaller than _eval. However, auto_load - : mechanism of the Tk interpreter doesn't work on _invoke. - : So _invoke can call only the command which already - : registered on the interpreter by 'load' command and so on. - : On _eval command, auto_load mechanism words. So if succeed - : to _eval and regist the command once, after that, the - : command can be called by _invoke. + _eval(str) + _invoke(*args) + : Estimates the arguments as a command on the Tk interpreter. + : The argument of _eval is a script of Tcl/Tk. + : Each argument of _invoke is a token of one command line of + : Tcl/Tk. + : Because the operation of _invoke doesn't through the + : command line parser of Tk interpreter, the cost of + : estimation is smaller than _eval. However, auto_load + : mechanism of the Tk interpreter doesn't work on _invoke. + : So _invoke can call only the command which already + : registered on the interpreter by 'load' command and so on. + : On _eval command, auto_load mechanism words. So if succeed + : to _eval and regist the command once, after that, the + : command can be called by _invoke. - _toUTF8(str, encoding) - _fromUTF8(str, encoding) - : Call the function (which is internal function of Tcl/Tk) to - : convert to/from a UTF8 string. + _toUTF8(str, encoding) + _fromUTF8(str, encoding) + : Call the function (which is internal function of Tcl/Tk) to + : convert to/from a UTF8 string. - _thread_vwait(var_name) - _thread_tkwait(mode, target) - : 'vwait' or 'tkwait' with thread support. - : The difference from normal 'vwait' or 'tkwait' command is - : doing independent wait from the vwait stack when they are - : called on the other thread than the eventloop thread. - : In the case of Tcl/Tk's vwait / tkwait, if 2nd vwait / - : tkwait is called on waiting for 1st vwait / tkwait, - : returns the order of [2nd]->[1st] regardless of the order - : of when the wait condition was fulfilled. - : If _thread_vwait / _thread_tkwait is called on the - : eventloop thread, there is no difference from vwait / - : tkwait. But if called on the other thread than the - : eventloop, stops the thread. And when the wait condition - : is fulfilled, the thread restarts. The meaning of - : "independent from the vwait stack" is that the timing of - : restarting is independent from the waiting status of the - : other threads. That is, even if the eventloop thread is - : waiting by vwait and is not fulfilled the condition, - : _thread_vwait completes the waiting when its waiting - : condition is fulfilled and the thread which stopped by - : _thread_vwait can continue the operation. + _thread_vwait(var_name) + _thread_tkwait(mode, target) + : 'vwait' or 'tkwait' with thread support. + : The difference from normal 'vwait' or 'tkwait' command is + : doing independent wait from the vwait stack when they are + : called on the other thread than the eventloop thread. + : In the case of Tcl/Tk's vwait / tkwait, if 2nd vwait / + : tkwait is called on waiting for 1st vwait / tkwait, + : returns the order of [2nd]->[1st] regardless of the order + : of when the wait condition was fulfilled. + : If _thread_vwait / _thread_tkwait is called on the + : eventloop thread, there is no difference from vwait / + : tkwait. But if called on the other thread than the + : eventloop, stops the thread. And when the wait condition + : is fulfilled, the thread restarts. The meaning of + : "independent from the vwait stack" is that the timing of + : restarting is independent from the waiting status of the + : other threads. That is, even if the eventloop thread is + : waiting by vwait and is not fulfilled the condition, + : _thread_vwait completes the waiting when its waiting + : condition is fulfilled and the thread which stopped by + : _thread_vwait can continue the operation. - _return_value - : Get the last result value on the interpreter. + _return_value + : Get the last result value on the interpreter. - mainloop - mainloop_watchdog - : If on the slave interpreter, never start an eventloop and - : returns nil. - : With the exception that, same to the TclTkLib module method - : with the same name. + _get_variable(var_name, flag) + _get_variable2(var_name, index_name, flag) + : Get the current value of a variable. If specified a + : index_name (see also the PARSE_VARNAME flag), get the + : value of the index_name element. - do_one_event - : With the exception that the argument is forced to set - : DONT_WAIT flag on the slave interpreter, same to - : TclTkLib#do_one_event. + _set_variable(var_name, value, flag) + _set_variable2(var_name, index_name, value, flag) + : Create or modify a variable. If specified a index_name + : (see also the PARSE_VARNAME flag), create or modify the + : index_name element. - set_eventloop_tick - get_eventloop_tick - set_no_event_wait - get_no_event_wait - set_eventloop_weight - get_eventloop_weight - mainloop_abort_on_exception - mainloop_abort_on_exception= - : With the exception that it is ignored to set value on the - : slave interpreter, same to the TclTkLib module method with - : the same name. + _unset_variable(var_name) + _unset_variable2(var_name, index_name) + : Remove a variable. If specified a index_name (see also + : the PARSE_VARNAME flag), remove the index_name element. + + _get_global_var(var_name) + _get_global_var2(var_name, index_name) + _set_global_var(var_name, value) + _set_global_var2(var_name, index_name, value) + _unset_global_var(var_name) + _unset_global_var2(var_name, index_name) + : Call the associated method with the flag argument + : (GLOBAL_ONLY | LEAVE_ERR_MSG). + + _split_tklist(str) + : Split the argument with Tcl/Tk's library function and + : get an array as a list of Tcl list elements. + + _merge_tklist(str, str, ... ) + : Get a Tcl's list string from arguments with a Tcl/Tk's + : library function. Each arguemnt is converted to a valid + : Tcl list element. + + _conv_listelement(str) + : Convert the argument to a valid Tcl list element with + : Tcl/Tk's library function. + + mainloop + mainloop_watchdog + : If on the slave interpreter, never start an eventloop and + : returns nil. + : With the exception that, same to the TclTkLib module method + : with the same name. + + do_one_event + : With the exception that the argument is forced to set + : DONT_WAIT flag on the slave interpreter, same to + : TclTkLib#do_one_event. + + set_eventloop_tick + get_eventloop_tick + set_no_event_wait + get_no_event_wait + set_eventloop_weight + get_eventloop_weight + mainloop_abort_on_exception + mainloop_abort_on_exception= + : With the exception that it is ignored to set value on the + : slave interpreter, same to the TclTkLib module method with + : the same name. class TkCallbackBreak < StandardError class TkCallbackContinue < StandardError - : They are exception classes to break or continue the Tk callback - : operation. - : If raise TkCallbackBreak on the callback procedure, Ruby returns - : 'break' code to Tk interpreter (Then the Tk interpreter will - : break the operation for the current event). - : If raise TkCallbackContinue, returns 'continue' code (Then the Tk - : interpreter will break the operateion for the current bindtag and - : starts the operation for the next buindtag for the current event). + : They are exception classes to break or continue the Tk callback + : operation. + : If raise TkCallbackBreak on the callback procedure, Ruby returns + : 'break' code to Tk interpreter (Then the Tk interpreter will + : break the operation for the current event). + : If raise TkCallbackContinue, returns 'continue' code (Then the Tk + : interpreter will break the operateion for the current bindtag and + : starts the operation for the next buindtag for the current event). (eof) diff --git a/ext/tcltklib/MANUAL.euc b/ext/tcltklib/MANUAL.euc index 9f9c77da02..baddcaf54b 100644 --- a/ext/tcltklib/MANUAL.euc +++ b/ext/tcltklib/MANUAL.euc @@ -1,5 +1,5 @@ (tof) - 2003/10/17 Hidetoshi NAGAI + 2004/03/28 Hidetoshi NAGAI 本ドキュメントには古い tcltk ライブラリ,tcltklib ライブラリの説明 が含まれていますが,その記述内容は古いものとなっています. @@ -175,6 +175,52 @@ require "tcltklib" : 処理対象イベントが存在しない場合に,イベント発生を待たず : に do_one_event を終了 ( false を返す ) する + モジュール TclTkLib::VarAccessFlag + : _get_variable などでのフラグを指定するためのもの.フラグに + : は以下の定数を OR で連結して与える. + + 定数 NONE + : 値は 0 で,何もフラグを指定していないのに等しい. + + 定数 GLOBAL_ONLY + : 通常,変数の検索はまず手続き呼び出しを行ったレベルで検 + : 索し,次に現在の名前空間で検索,最後にグローバル空間で + : 検索を行う.しかし,このフラグが指定された場合には,グ + : ローバル空間でのみ検索する. + : もし GLOBAL_ONLY と NAMESPACE_ONLY とが両方指定された場 + : 合には,GLOBAL_ONLY の指定は無視される. + + 定数 NAMESPACE_ONLY + : このフラグが指定された場合には,現在の名前空間でのみ変 + : 数の検索を行う.GLOBAL_ONLY の説明も参照すること. + + 定数 LEAVE_ERR_MSG + : 変数アクセスにおいてエラーが発生した場合,このフラグが + : 指定されていれば,実行結果として Tcl インタープリタにエ + : ラーメッセージが残される.このフラグが指定されていなけ + : れば,エラーメッセージは一切残されない. + + 定数 APPEND_VALUE + : このフラグが指定されていた場合,変数の値を置き換えので + : はなく,現在の値に代入値が追加 (append; 文字列連結) さ + : れる.変数が未定義あった場合,このフラグは無視される. + + 定数 LIST_ELEMENT + : このフラグが指定されていた場合,代入値はまず Tcl のリス + : ト要素として適切となるように変換される.代入値がリスト + : (またはサブリスト) の最初の要素となるのでない限り,代入 + : 値の直前には空白文字が追加される. + + 定数 PARSE_VARNAME + : _set_variable などの呼び出しにおいてこのフラグが指定さ + : れていた場合,var_name 引数が連想配列名と要素名とを両方 + : 含む可能性がある (開き括弧を含み,閉じ括弧で終わる) こ + : とを示す.その場合,括弧の間が要素名指定,最初の開き括 + : 弧までが連想配列名として扱われる._set_variable2 などで + : このフラグを指定する場合,連想配列名と要素名は var_name + : から抽出されるはずであるから,index_name 引数は nil と + : せねばならない. + モジュールメソッド mainloop(check_root = true) : イベントループを起動する.check_root が true であれば, @@ -277,6 +323,26 @@ require "tcltklib" : ので,この値は現在 Tk の機能が有効であるインタープリタの総 : 数に等しい. + _merge_tklist(str, str, ... ) + : Tcl/Tk のライブラリ関数を使って,引数の文字列がそれぞれ + : 正しく一つのリスト要素となるように連結した文字列を返す. + + _conv_listelement(str) + : Tcl/Tk のライブラリ関数を使って,引数の文字列が Tcl の + : 一つのリスト要素として適切な表現になるように変換した文 + : 字列を返す. + + _toUTF8(str, encoding) + _fromUTF8(str, encoding) + : Tcl/Tk が内蔵している UTF8 変換処理を呼び出す. + + _subst_UTF_backslash(str) + _subst_Tcl_backslash(str) + : Tcl のルールでバックスラッシュ記法 ( \uhhhh による + : Unicode 文字表現を含む ) を解析する. + : _subst_Tcl_backslash はすべてのバックスラッシュ記法を + : 置き換えるのに対し,_subst_UTF_backslash は \uhhhh + : による Unicode 文字表現だけを置き換える. クラス TclTkIp クラスメソッド @@ -373,6 +439,52 @@ require "tcltklib" _return_value : 直前の Tcl/Tk 上での評価の実行結果としての戻り値を返す. + _get_variable(var_name, flag) + _get_variable2(var_name, index_name, flag) + : Tcl/Tk 上の var という変数名の変数の値を返す. + : もし index_name が指定 (PARSE_VARNAME フラグの説明も参照) + : された場合は連想配列 var_name の index_name の要素を返す. + : flag には変数を検索する際の条件を指定する.flag に与える + : 値はモジュール TclTkLib::VarAccessFlag を参照すること. + + _set_variable(var_name, value, flag) + _set_variable2(var_name, index_name, value, flag) + : Tcl/Tk 上の var という変数名の変数に値を設定する. + : もし index_name が指定 (PARSE_VARNAME フラグの説明も参照) + : された場合は連想配列 var_name の index_name の要素を設定 + : する. + : flag には変数を検索する際の条件を指定する.flag に与える + : 値はモジュール TclTkLib::VarAccessFlag を参照すること. + + _unset_variable(var_name) + _unset_variable2(var_name, index_name) + : Tcl/Tk 上の var_name という変数名の変数を消去する. + : もし index_name が指定 (PARSE_VARNAME フラグの説明も参照) + : された場合は連想配列 var_name から index_name の要素だけ + : を消去する. + + _get_global_var(var_name) + _get_global_var2(var_name, index_name) + _set_global_var(var_name, value) + _set_global_var2(var_name, index_name, value) + _unset_global_var(var_name) + _unset_global_var2(var_name, index_name) + : それぞれ,対応する変数アクセスメソッドの flag に対して + : (GLOBAL_ONLY | LEAVE_ERR_MSG) を与えたもの. + + _split_tklist(str) + : Tcl/Tk のライブラリ関数を使って,文字列 str をリストに + : 分割する (文字列の配列として返す). + + _merge_tklist(str, str, ... ) + : Tcl/Tk のライブラリ関数を使って,引数の文字列がそれぞれ + : 正しく一つのリスト要素となるように連結した文字列を返す. + + _conv_listelement(str) + : Tcl/Tk のライブラリ関数を使って,引数の文字列が Tcl の + : 一つのリスト要素として適切な表現になるように変換した文 + : 字列を返す. + mainloop mainloop_watchdog : スレーブ IP の場合にはイベントループを起動せずに nil を返す. diff --git a/ext/tcltklib/README.1st b/ext/tcltklib/README.1st index 510dd1c2cd..48e3a2b668 100644 --- a/ext/tcltklib/README.1st +++ b/ext/tcltklib/README.1st @@ -8,7 +8,7 @@ some or all of the following options. --with-tcllib= (e.g. libtcl8.3.so ==> --with-tcllib=tcl8.3) --with-tklib= (e.g. libtk8.3.so ==> --with-tklib=tk8.3) - --enable_tcltk_stubs (if you force to enable stubs) + --enable-tcltk_stubs (if you force to enable stubs) --with-tcl-dir= equal to "--with-tcl-include=/include --with-tcl-lib=/lib" diff --git a/ext/tcltklib/demo/lines3.rb b/ext/tcltklib/demo/lines3.rb new file mode 100644 index 0000000000..caa50f92e7 --- /dev/null +++ b/ext/tcltklib/demo/lines3.rb @@ -0,0 +1,54 @@ +#! /usr/local/bin/ruby + +require "tk" + +def drawlines() + print Time.now, "\n" + + for j in 0 .. 99 + print "*" + $stdout.flush + if (j & 1) != 0 + col = "blue" + else + col = "red" + end + for i in 0 .. 99 +# $a.create(TkcLine, i, 0, 0, 500 - i, "fill"=>col) + end + end + + print Time.now, "\n" + + for j in 0 .. 99 + print "*" + $stdout.flush + if (j & 1) != 0 + col = "blue" + else + col = "red" + end + for i in 0 .. 99 + $a.create(TkcLine, i, 0, 0, 500 - i, "fill"=>col) + end + end + + print Time.now, "\n" +# Tk.root.destroy +end + +$a = TkCanvas.new{ + height(500) + width(500) +} + +$b = TkButton.new{ + text("draw") + command(proc{drawlines()}) +} + +TkPack.configure($a, $b, {"side"=>"left"}) + +Tk.mainloop + +# eof diff --git a/ext/tcltklib/demo/lines4.rb b/ext/tcltklib/demo/lines4.rb new file mode 100644 index 0000000000..7a1175bce0 --- /dev/null +++ b/ext/tcltklib/demo/lines4.rb @@ -0,0 +1,54 @@ +#! /usr/local/bin/ruby + +require "tk" + +def drawlines() + print Time.now, "\n" + + for j in 0 .. 99 + print "*" + $stdout.flush + if (j & 1) != 0 + col = "blue" + else + col = "red" + end + for i in 0 .. 99 +# TkCore::INTERP.__invoke($a.path, "create", "line", i.to_s, '0', '0', (500 - i).to_s, "-fill", col) + end + end + + print Time.now, "\n" + + for j in 0 .. 99 + print "*" + $stdout.flush + if (j & 1) != 0 + col = "blue" + else + col = "red" + end + for i in 0 .. 99 + TkCore::INTERP.__invoke($a.path, "create", "line", i.to_s, '0', '0', (500 - i).to_s, "-fill", col) + end + end + + print Time.now, "\n" +# Tk.root.destroy +end + +$a = TkCanvas.new{ + height(500) + width(500) +} + +$b = TkButton.new{ + text("draw") + command(proc{drawlines()}) +} + +TkPack.configure($a, $b, {"side"=>"left"}) + +Tk.mainloop + +# eof diff --git a/ext/tcltklib/extconf.rb b/ext/tcltklib/extconf.rb index 575bf78034..6b2fcdd4ac 100644 --- a/ext/tcltklib/extconf.rb +++ b/ext/tcltklib/extconf.rb @@ -2,7 +2,9 @@ require 'mkmf' -if RUBY_PLATFORM !~ /mswin32|mingw|cygwin|bccwin32/ +is_win32 = (/mswin32|mingw|cygwin|bccwin32/ =~ RUBY_PLATFORM) + +unless is_win32 have_library("nsl", "t_open") have_library("socket", "socket") have_library("dl", "dlopen") @@ -25,7 +27,7 @@ def find_tcl(tcllib, stubs) elsif find_library("tcl", func, *paths) true else - %w[8.4 8.3 8.2 8.0 7.6].find { |ver| + %w[8.5 8.4 8.3 8.2 8.1 8.0 7.6].find { |ver| find_library("tcl#{ver}", func, *paths) or find_library("tcl#{ver.delete('.')}", func, *paths) } @@ -40,7 +42,7 @@ def find_tk(tklib, stubs) elsif find_library("tk", func, *paths) true else - %w[8.4 8.3 8.2 8.0 4.2].find { |ver| + %w[8.5 8.4 8.3 8.2 8.1 8.0 4.2].find { |ver| find_library("tk#{ver}", func, *paths) or find_library("tk#{ver.delete('.')}", func, *paths) } @@ -48,11 +50,73 @@ def find_tk(tklib, stubs) end if have_header("tcl.h") && have_header("tk.h") && - (/mswin32|mingw|cygwin|bccwin32/ =~ RUBY_PLATFORM || find_library("X11", "XOpenDisplay", - "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib")) && + (is_win32 || find_library("X11", "XOpenDisplay", + "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib")) && find_tcl(tcllib, stubs) && find_tk(tklib, stubs) $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM - create_makefile("tcltklib") + + pthread_enabled = macro_defined?('HAVE_LIBPTHREAD', '#include "ruby.h"') + + if try_run(< +static Tcl_ThreadDataKey dataKey; +int main() { exit((Tcl_GetThreadData(&dataKey, 1) == dataKey)? 1: 0); } +EOF + tcl_enable_thread = true + else + tcl_enable_thread = false + end + + unless pthread_enabled + if tcl_enable_thread + # ruby -> disable && tcl -> enable + puts(%Q'\ +***************************************************************************** +** +** PTHREAD SUPPORT MODE ERRROR: +** +** Ruby is not compiled with --enable-pthread, but your Tcl/Tk +** libararies seems to be compiled with "pthread support". This +** combination possibly cause "Hang-up" or "Segmentation Fault" +** frequently when Ruby/Tk is working. We NEVER recommend you to +** create the library under such combination of pthread support. +** +** Please recompile Ruby with "--enable-pthread" configure option +** or recompile Tcl/Tk with "--disable-threads" configure option. +** +***************************************************************************** +') + else + # ruby -> disable && tcl -> disable + create_makefile("tcltklib") + end + else + unless tcl_enable_thread + # ruby -> enable && tcl -> disable + puts(%Q'\ +***************************************************************************** +** +** PTHREAD SUPPORT MODE WARNING: +** +** Ruby is compiled with --enable-pthread, but your Tcl/Tk libraries +** seems to be compiled without "pthread support". Although You can +** create tcltklib library, this combination may cause memory trouble +** (e.g. "Hang-up" or "Segmentation Fault"). If you have no reason you +** must have to keep current pthread support status, we recommend you +** to make both or neither libraries to support pthread. +** +** If you want change the status of pthread support, please recompile +** Ruby without "--enable-pthread" configure option or recompile Tcl/Tk +** with "--enable-threads" configure option (if your Tcl/Tk is later +** than Tcl/Tk8.1). +** +***************************************************************************** +') + end + # ruby -> enable && tcl -> enable/disable + + create_makefile("tcltklib") + end end diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index 63dd593605..eea7ace7fa 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -36,28 +36,62 @@ # endif # endif # endif -#else /* TCL_MAJOR_VERSION == 7 */ +#else /* TCL_MAJOR_VERSION < 8 */ # ifdef CONST # define CONST84 CONST # else +# define CONST # define CONST84 # endif #endif -/* for ruby_debug */ +/* copied from eval.c */ +#define TAG_RETURN 0x1 +#define TAG_BREAK 0x2 +#define TAG_NEXT 0x3 +#define TAG_RETRY 0x4 +#define TAG_REDO 0x5 +#define TAG_RAISE 0x6 +#define TAG_FATAL 0x8 -#define DUMP1(ARG1) if (ruby_debug) { fprintf(stderr, "tcltklib: %s\n", ARG1);} +/* for ruby_debug */ +#define DUMP1(ARG1) if (ruby_debug) { fprintf(stderr, "tcltklib: %s\n", ARG1); fflush(stderr); } #define DUMP2(ARG1, ARG2) if (ruby_debug) { fprintf(stderr, "tcltklib: ");\ -fprintf(stderr, ARG1, ARG2); fprintf(stderr, "\n"); } +fprintf(stderr, ARG1, ARG2); fprintf(stderr, "\n"); fflush(stderr); } /* #define DUMP1(ARG1) #define DUMP2(ARG1, ARG2) */ +/* finalize_proc_name */ +static char *finalize_hook_name = "INTERP_FINALIZE_HOOK"; + /* for callback break & continue */ +static VALUE eTkCallbackReturn; static VALUE eTkCallbackBreak; static VALUE eTkCallbackContinue; +static VALUE eLocalJumpError; + +static ID ID_at_enc; +static ID ID_at_interp; + +static ID ID_stop_p; +static ID ID_kill; +static ID ID_join; + +static ID ID_call; +static ID ID_backtrace; +static ID ID_message; + +static ID ID_at_reason; +static ID ID_return; +static ID ID_break; +static ID ID_next; + +static ID ID_to_s; +static ID ID_inspect; + static VALUE ip_invoke_real _((int, VALUE*, VALUE)); static VALUE ip_invoke _((int, VALUE*, VALUE)); @@ -78,23 +112,45 @@ int *tclDummyMathPtr = (int *) matherr; struct invoke_queue { Tcl_Event ev; int argc; - VALUE *argv; - VALUE obj; - int done; +#if TCL_MAJOR_VERSION >= 8 + Tcl_Obj **argv; +#else /* TCL_MAJOR_VERSION < 8 */ + char **argv; +#endif + VALUE interp; + int *done; int safe_level; - VALUE *result; + VALUE result; VALUE thread; }; struct eval_queue { Tcl_Event ev; - VALUE str; - VALUE obj; - int done; + char *str; + int len; + VALUE interp; + int *done; int safe_level; - VALUE *result; + VALUE result; VALUE thread; }; + +void +invoke_queue_mark(struct invoke_queue *q) +{ + rb_gc_mark(q->interp); + rb_gc_mark(q->result); + rb_gc_mark(q->thread); +} + +void +eval_queue_mark(struct eval_queue *q) +{ + rb_gc_mark(q->interp); + rb_gc_mark(q->result); + rb_gc_mark(q->thread); +} + static VALUE eventloop_thread; static VALUE watchdog_thread; @@ -128,9 +184,11 @@ static int loop_counter = 0; static int check_rootwidget_flag = 0; #if TCL_MAJOR_VERSION >= 8 -static int ip_ruby _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*)); -#else -static int ip_ruby _((ClientData, Tcl_Interp *, int, char **)); +static int ip_ruby_eval _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*)); +static int ip_ruby_cmd _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*)); +#else /* TCL_MAJOR_VERSION < 8 */ +static int ip_ruby_eval _((ClientData, Tcl_Interp *, int, char **)); +static int ip_ruby_cmd _((ClientData, Tcl_Interp *, int, char **)); #endif /*---- class TclTkIp ----*/ @@ -161,10 +219,16 @@ static void _timer_for_tcl(clientData) ClientData clientData; { + int thr_crit_bup; + /* struct invoke_queue *q, *tmp; */ /* VALUE thread; */ DUMP1("called timer_for_tcl"); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tk_DeleteTimerHandler(timer_token); run_timer_flag = 1; @@ -176,6 +240,8 @@ _timer_for_tcl(clientData) timer_token = (Tcl_TimerToken)NULL; } + rb_thread_critical = thr_crit_bup; + /* rb_thread_schedule(); */ /* tick_counter += event_loop_max; */ } @@ -186,6 +252,7 @@ set_eventloop_tick(self, tick) VALUE tick; { int ttick = NUM2INT(tick); + int thr_crit_bup; rb_secure(4); @@ -194,6 +261,9 @@ set_eventloop_tick(self, tick) "timer-tick parameter must be 0 or positive number"); } + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + /* delete old timer callback */ Tk_DeleteTimerHandler(timer_token); @@ -206,6 +276,8 @@ set_eventloop_tick(self, tick) timer_token = (Tcl_TimerToken)NULL; } + rb_thread_critical = thr_crit_bup; + return tick; } @@ -334,6 +406,39 @@ ip_get_eventloop_weight(self) return get_eventloop_weight(self); } +static VALUE +set_max_block_time(self, time) + VALUE self; + VALUE time; +{ + struct Tcl_Time tcl_time; + VALUE divmod; + + switch(TYPE(time)) { + case T_FIXNUM: + case T_BIGNUM: + /* time is micro-second value */ + divmod = rb_funcall(time, rb_intern("divmod"), 1, LONG2NUM(1000000)); + tcl_time.sec = NUM2LONG(RARRAY(divmod)->ptr[0]); + tcl_time.usec = NUM2LONG(RARRAY(divmod)->ptr[1]); + break; + + case T_FLOAT: + /* time is second value */ + divmod = rb_funcall(time, rb_intern("divmod"), 1, INT2FIX(1)); + tcl_time.sec = NUM2LONG(RARRAY(divmod)->ptr[0]); + tcl_time.usec = (long)(NUM2DBL(RARRAY(divmod)->ptr[1]) * 1000000); + + default: + rb_raise(rb_eArgError, "invalid value for time: '%s'", + RSTRING(rb_funcall(time, ID_inspect, 0, 0))->ptr); + } + + Tcl_SetMaxBlockTime(&tcl_time); + + return Qnil; +} + static VALUE lib_evloop_abort_on_exc(self) VALUE self; @@ -361,7 +466,7 @@ lib_evloop_abort_on_exc_set(self, val) rb_secure(4); if (RTEST(val)) { event_loop_abort_on_exc = 1; - } else if (val == Qnil) { + } else if (NIL_P(val)) { event_loop_abort_on_exc = -1; } else { event_loop_abort_on_exc = 0; @@ -391,13 +496,19 @@ lib_num_of_mainwindows(self) } static int -lib_eventloop_core(check_root, check_var) +lib_eventloop_core(check_root, update_flag, check_var) int check_root; + int update_flag; int *check_var; { VALUE current = eventloop_thread; int found_event = 1; + int event_flag; struct timeval t; + int thr_crit_bup; + + + if (update_flag) DUMP1("update loop start!!"); t.tv_sec = (time_t)0; t.tv_usec = (time_t)(no_event_wait*1000.0); @@ -405,8 +516,11 @@ lib_eventloop_core(check_root, check_var) Tk_DeleteTimerHandler(timer_token); run_timer_flag = 0; if (timer_tick > 0) { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; timer_token = Tk_CreateTimerHandler(timer_tick, _timer_for_tcl, (ClientData)0); + rb_thread_critical = thr_crit_bup; } else { timer_token = (Tcl_TimerToken)NULL; } @@ -416,7 +530,13 @@ lib_eventloop_core(check_root, check_var) DUMP1("no other thread"); event_loop_wait_event = 0; - if (timer_tick == 0) { + if (update_flag) { + event_flag = update_flag | TCL_DONT_WAIT; /* for safety */ + } else { + event_flag = TCL_ALL_EVENTS; + } + + if (timer_tick == 0 && update_flag == 0) { timer_tick = NO_THREAD_INTERRUPT_TIME; timer_token = Tk_CreateTimerHandler(timer_tick, _timer_for_tcl, @@ -429,25 +549,30 @@ lib_eventloop_core(check_root, check_var) } } - found_event = Tcl_DoOneEvent(TCL_ALL_EVENTS); + found_event = Tcl_DoOneEvent(event_flag); - if (loop_counter++ > 30000) { - loop_counter = 0; + if (update_flag != 0) { + if (found_event) { + DUMP1("next update loop"); + continue; + } else { + DUMP1("update complete"); + return 0; + } } - if (run_timer_flag) { - /* - DUMP1("timer interrupt"); + DUMP1("check Root Widget"); + if (check_root && Tk_GetNumMainWindows() == 0) { run_timer_flag = 0; - DUMP1("call rb_trap_exec()"); - rb_trap_exec(); - */ - DUMP1("check Root Widget"); - if (check_root && Tk_GetNumMainWindows() == 0) { - run_timer_flag = 0; - rb_trap_exec(); - return 1; + if (!rb_prohibit_interrupt) { + if (rb_trap_pending) rb_trap_exec(); } + return 1; + } + + if (loop_counter++ > 30000) { + /* fprintf(stderr, "loop_counter > 30000\n"); */ + loop_counter = 0; } } else { @@ -458,6 +583,12 @@ lib_eventloop_core(check_root, check_var) found_event = 1; + if (update_flag) { + event_flag = update_flag | TCL_DONT_WAIT; /* for safety */ + } else { + event_flag = TCL_ALL_EVENTS | TCL_DONT_WAIT; + } + timer_tick = req_timer_tick; tick_counter = 0; while(tick_counter < event_loop_max) { @@ -467,27 +598,40 @@ lib_eventloop_core(check_root, check_var) } } - if (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) { + if (Tcl_DoOneEvent(event_flag)) { tick_counter++; } else { - tick_counter += no_event_tick; - - DUMP1("check Root Widget"); - if (check_root && Tk_GetNumMainWindows() == 0) { - return 1; + if (update_flag != 0) { + DUMP1("update complete"); + return 0; } - + tick_counter += no_event_tick; rb_thread_wait_for(t); } - if (loop_counter++ > 30000) { - loop_counter = 0; - } - if (watchdog_thread != 0 && eventloop_thread != current) { return 1; } + DUMP1("check Root Widget"); + if (check_root && Tk_GetNumMainWindows() == 0) { + run_timer_flag = 0; + if (!rb_prohibit_interrupt) { + if (rb_trap_pending) rb_trap_exec(); + } + return 1; + } + + DUMP1("trap check"); + if (!rb_prohibit_interrupt) { + if (rb_trap_pending) rb_trap_exec(); + } + + if (loop_counter++ > 30000) { + /* fprintf(stderr, "loop_counter > 30000\n"); */ + loop_counter = 0; + } + if (run_timer_flag) { /* DUMP1("timer interrupt"); @@ -496,23 +640,11 @@ lib_eventloop_core(check_root, check_var) break; /* switch to other thread */ } } - - DUMP1("check Root Widget"); - if (check_root && Tk_GetNumMainWindows() == 0) { - return 1; - } } - /* rb_thread_schedule(); */ - if (run_timer_flag) { - run_timer_flag = 0; - rb_trap_exec(); - } else { - DUMP1("thread scheduling"); - if (is_ruby_native_thread()) { - rb_thread_schedule(); - } - } + DUMP1("trap check & thread scheduling"); + if (update_flag == 0) CHECK_INTS; + } return 1; } @@ -523,7 +655,7 @@ lib_eventloop_main(check_rootwidget) { check_rootwidget_flag = RTEST(check_rootwidget); - if (lib_eventloop_core(check_rootwidget_flag, (int *)NULL)) { + if (lib_eventloop_core(check_rootwidget_flag, 0, (int *)NULL)) { return Qtrue; } else { return Qfalse; @@ -614,8 +746,8 @@ lib_watchdog_core(check_rootwidget) /* check other watchdog thread */ if (watchdog_thread != 0) { - if (RTEST(rb_funcall(watchdog_thread, rb_intern("stop?"), 0))) { - rb_funcall(watchdog_thread, rb_intern("kill"), 0); + if (RTEST(rb_funcall(watchdog_thread, ID_stop_p, 0))) { + rb_funcall(watchdog_thread, ID_kill, 0); } else { return Qnil; } @@ -626,7 +758,7 @@ lib_watchdog_core(check_rootwidget) do { if (eventloop_thread == 0 || (loop_counter == prev_val - && RTEST(rb_funcall(eventloop_thread, rb_intern("stop?"), 0)) + && RTEST(rb_funcall(eventloop_thread, ID_stop_p, 0)) && ++chance >= 3 ) ) { /* start new eventloop thread */ @@ -703,7 +835,7 @@ lib_do_one_event_core(argc, argv, self, is_ip) VALUE self; int is_ip; { - VALUE vflags; + volatile VALUE vflags; int flags; int found_event; @@ -727,7 +859,8 @@ lib_do_one_event_core(argc, argv, self, is_ip) } } - found_event = Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); + /* found_event = Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); */ + found_event = Tcl_DoOneEvent(flags); if (found_event) { return Qtrue; @@ -755,13 +888,97 @@ ip_do_one_event(argc, argv, self) } -/* Tcl command `ruby' */ +static void +ip_set_exc_message(interp, exc) + Tcl_Interp *interp; + VALUE exc; +{ + char *buf; + Tcl_DString dstr; + volatile VALUE msg; + int thr_crit_bup; + +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + volatile VALUE enc; + Tcl_Encoding encoding; +#endif + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + msg = rb_funcall(exc, ID_message, 0, 0); + +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + enc = rb_ivar_get(exc, ID_at_enc); + if (NIL_P(enc)) { + enc = rb_ivar_get(msg, ID_at_enc); + } + if (NIL_P(enc)) { + encoding = (Tcl_Encoding)NULL; + } else if (TYPE(enc) == T_STRING) { + encoding = Tcl_GetEncoding(interp, RSTRING(enc)->ptr); + } else { + enc = rb_funcall(enc, ID_to_s, 0, 0); + encoding = Tcl_GetEncoding(interp, RSTRING(enc)->ptr); + } + + /* to avoid a garbled error message dialog */ + buf = ALLOC_N(char, (RSTRING(msg)->len)+1); + strncpy(buf, RSTRING(msg)->ptr, RSTRING(msg)->len); + buf[RSTRING(msg)->len] = 0; + + Tcl_DStringInit(&dstr); + Tcl_DStringFree(&dstr); + Tcl_ExternalToUtfDString(encoding, buf, RSTRING(msg)->len, &dstr); + + Tcl_AppendResult(interp, Tcl_DStringValue(&dstr), (char*)NULL); + DUMP2("error message:%s", Tcl_DStringValue(&dstr)); + free(buf); + +#else /* TCL_VERSION <= 8.0 */ + Tcl_AppendResult(interp, RSTRING(msg)->ptr, (char*)NULL); +#endif + + rb_thread_critical = thr_crit_bup; +} + +static VALUE +TkStringValue(obj) + VALUE obj; +{ + switch(TYPE(obj)) { + case T_STRING: + return obj; + + case T_NIL: + return rb_str_new2(""); + + case T_TRUE: + return rb_str_new2("1"); + + case T_FALSE: + return rb_str_new2("0"); + + case T_ARRAY: + return rb_funcall(obj, ID_join, 1, rb_str_new2(" ")); + + default: + if (rb_respond_to(obj, ID_to_s)) { + return rb_funcall(obj, ID_to_s, 0, 0); + } + } + + return rb_funcall(obj, ID_inspect, 0, 0); +} + +/* Tcl command `ruby'|`ruby_eval' */ static VALUE ip_ruby_eval_rescue(failed, einfo) - VALUE *failed; + VALUE failed; VALUE einfo; { - *failed = einfo; + DUMP1("call ip_ruby_eval_rescue"); + RARRAY(failed)->ptr[0] = einfo; return Qnil; } @@ -772,76 +989,265 @@ struct eval_body_arg { static VALUE ip_ruby_eval_body(arg) - struct eval_body_arg *arg; + struct eval_body_arg *arg; { + VALUE ret; + int status = 0; + int thr_crit_bup; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + DUMP1("call ip_ruby_eval_body"); rb_trap_immediate = 0; - return rb_rescue2(rb_eval_string, (VALUE)arg->string, - ip_ruby_eval_rescue, (VALUE)&(arg->failed), + +#if 0 + ret = rb_rescue2(rb_eval_string, (VALUE)arg->string, + ip_ruby_eval_rescue, arg->failed, rb_eStandardError, rb_eScriptError, rb_eSystemExit, (VALUE)0); +#else + + ret = rb_eval_string_protect(arg->string, &status); + if (status) { + char *errtype, *buf; + int errtype_len, len; + VALUE old_gc; + + old_gc = rb_gc_disable(); + + switch(status) { + case TAG_RETURN: + errtype = "LocalJumpError: "; + errtype_len = strlen(errtype); + len = errtype_len + RSTRING(rb_obj_as_string(ruby_errinfo))->len; + buf = ALLOC_N(char, len + 1); + strncpy(buf, errtype, errtype_len); + strncpy(buf + errtype_len, + RSTRING(rb_obj_as_string(ruby_errinfo))->ptr, + RSTRING(rb_obj_as_string(ruby_errinfo))->len); + *(buf + len) = 0; + + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(eTkCallbackReturn, buf); + free(buf); + break; + + case TAG_BREAK: + errtype = "LocalJumpError: "; + errtype_len = strlen(errtype); + len = errtype_len + RSTRING(rb_obj_as_string(ruby_errinfo))->len; + buf = ALLOC_N(char, len + 1); + strncpy(buf, errtype, errtype_len); + strncpy(buf + errtype_len, + RSTRING(rb_obj_as_string(ruby_errinfo))->ptr, + RSTRING(rb_obj_as_string(ruby_errinfo))->len); + *(buf + len) = 0; + + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(eTkCallbackBreak, buf); + free(buf); + break; + + case TAG_NEXT: + errtype = "LocalJumpError: "; + errtype_len = strlen(errtype); + len = errtype_len + RSTRING(rb_obj_as_string(ruby_errinfo))->len; + buf = ALLOC_N(char, len + 1); + strncpy(buf, errtype, errtype_len); + strncpy(buf + errtype_len, + RSTRING(rb_obj_as_string(ruby_errinfo))->ptr, + RSTRING(rb_obj_as_string(ruby_errinfo))->len); + *(buf + len) = 0; + + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(eTkCallbackContinue,buf); + free(buf); + break; + + case TAG_RETRY: + case TAG_REDO: + RARRAY(arg->failed)->ptr[0] = ruby_errinfo; + break; + + case TAG_RAISE: + case TAG_FATAL: + RARRAY(arg->failed)->ptr[0] = ruby_errinfo; + break; + + default: + buf = ALLOC_N(char, 256); + sprintf(buf, "unknown loncaljmp status %d", status); + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(rb_eException, buf); + free(buf); + break; + } + + if (old_gc == Qfalse) rb_gc_enable(); + + ret = Qnil; + } +#endif + + rb_thread_critical = thr_crit_bup; + + return ret; } static VALUE ip_ruby_eval_ensure(trapflag) - VALUE trapflag; + VALUE trapflag; { rb_trap_immediate = NUM2INT(trapflag); return Qnil; } + static int #if TCL_MAJOR_VERSION >= 8 -ip_ruby(clientData, interp, argc, argv) +ip_ruby_eval(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; Tcl_Obj *CONST argv[]; -#else -ip_ruby(clientData, interp, argc, argv) +#else /* TCL_MAJOR_VERSION < 8 */ +ip_ruby_eval(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char *argv[]; #endif { - VALUE res; + volatile VALUE res; + volatile VALUE exception = rb_ary_new2(1); int old_trapflag; - struct eval_body_arg arg; - int dummy; + struct eval_body_arg *arg; + int thr_crit_bup; /* ruby command has 1 arg. */ if (argc != 2) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); + rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", + argc - 1); } + /* allocate */ + arg = ALLOC(struct eval_body_arg); + /* get C string from Tcl object */ #if TCL_MAJOR_VERSION >= 8 - arg.string = Tcl_GetStringFromObj(argv[1], &dummy); -#else - arg.string = argv[1]; + { + char *str; + int len; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + str = Tcl_GetStringFromObj(argv[1], &len); + arg->string = ALLOC_N(char, len + 1); + strncpy(arg->string, str, len); + arg->string[len] = 0; + + rb_thread_critical = thr_crit_bup; + + } +#else /* TCL_MAJOR_VERSION < 8 */ + arg->string = argv[1]; #endif - arg.failed = 0; + /* arg.failed = 0; */ + RARRAY(exception)->ptr[0] = Qnil; + arg->failed = exception; /* evaluate the argument string by ruby */ - DUMP2("rb_eval_string(%s)", arg.string); + DUMP2("rb_eval_string(%s)", arg->string); old_trapflag = rb_trap_immediate; - res = rb_ensure(ip_ruby_eval_body, (VALUE)&arg, +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread()) { + rb_bug("cross-thread violation on ip_ruby_eval()"); + } +#endif + res = rb_ensure(ip_ruby_eval_body, (VALUE)arg, ip_ruby_eval_ensure, INT2FIX(old_trapflag)); +#if TCL_MAJOR_VERSION >= 8 + free(arg->string); +#endif + + free(arg); + /* status check */ - if (arg.failed) { - VALUE eclass = rb_obj_class(arg.failed); + /* if (arg.failed) { */ + if (!NIL_P(RARRAY(exception)->ptr[0])) { + VALUE eclass; + volatile VALUE backtrace; + DUMP1("(rb_eval_string result) failed"); + Tcl_ResetResult(interp); - Tcl_AppendResult(interp, StringValuePtr(arg.failed), (char*)NULL); - if (eclass == eTkCallbackBreak) { + + res = RARRAY(exception)->ptr[0]; + eclass = rb_obj_class(res); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + DUMP1("set backtrace"); + backtrace = rb_ary_join(rb_funcall(res, ID_backtrace, 0, 0), + rb_str_new2("\n")); + StringValue(backtrace); + Tcl_AddErrorInfo(interp, RSTRING(backtrace)->ptr); + + rb_thread_critical = thr_crit_bup; + + if (eclass == eTkCallbackReturn) { + return TCL_RETURN; + + } else if (eclass == eTkCallbackBreak) { return TCL_BREAK; + } else if (eclass == eTkCallbackContinue) { return TCL_CONTINUE; + } else if (eclass == rb_eSystemExit) { - Tcl_Eval(interp, "destroy ."); - rb_raise(rb_eSystemExit, StringValuePtr(arg.failed)); + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* Tcl_Eval(interp, "destroy ."); */ + if (Tk_GetNumMainWindows() > 0) { + Tk_Window main_win = Tk_MainWindow(interp); + if (main_win != (Tk_Window)NULL) { + Tk_DestroyWindow(main_win); + } + } + + /* StringValue(res); */ + res = rb_funcall(res, ID_message, 0, 0); + + Tcl_AppendResult(interp, RSTRING(res)->ptr, (char*)NULL); + + rb_thread_critical = thr_crit_bup; + + rb_raise(rb_eSystemExit, RSTRING(res)->ptr); + + } else if (rb_obj_is_kind_of(res, eLocalJumpError)) { + VALUE reason = rb_ivar_get(res, ID_at_reason); + + if (TYPE(reason) != T_SYMBOL) { + ip_set_exc_message(interp, res); + return TCL_ERROR; + } + + if (SYM2ID(reason) == ID_return) { + return TCL_RETURN; + + } else if (SYM2ID(reason) == ID_break) { + return TCL_BREAK; + + } else if (SYM2ID(reason) == ID_next) { + return TCL_CONTINUE; + + } else { + ip_set_exc_message(interp, res); + return TCL_ERROR; + } } else { + ip_set_exc_message(interp, res); return TCL_ERROR; } } @@ -854,11 +1260,390 @@ ip_ruby(clientData, interp, argc, argv) } /* copy result to the tcl interpreter */ - DUMP2("(rb_eval_string result) %s", StringValuePtr(res)); + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + res = TkStringValue(res); + DUMP2("(rb_eval_string result) %s", RSTRING(res)->ptr); DUMP1("Tcl_AppendResult"); Tcl_ResetResult(interp); - Tcl_AppendResult(interp, StringValuePtr(res), (char *)NULL); + Tcl_AppendResult(interp, RSTRING(res)->ptr, (char *)NULL); + rb_thread_critical = thr_crit_bup; + + return TCL_OK; +} + + +/* Tcl command `ruby_cmd' */ +struct cmd_body_arg { + VALUE receiver; + ID method; + VALUE args; + VALUE failed; +}; + +static VALUE +ip_ruby_cmd_core(arg) + struct cmd_body_arg *arg; +{ + VALUE ret; + + DUMP1("call ip_ruby_cmd_core"); + ret = rb_apply(arg->receiver, arg->method, arg->args); + DUMP1("finish ip_ruby_cmd_core"); + + return ret; +} + +static VALUE +ip_ruby_cmd_rescue(failed, einfo) + VALUE failed; + VALUE einfo; +{ + DUMP1("call ip_ruby_cmd_rescue"); + RARRAY(failed)->ptr[0] = einfo; + return Qnil; +} + +static VALUE +ip_ruby_cmd_body(arg) + struct cmd_body_arg *arg; +{ + VALUE ret; + int status = 0; + int thr_crit_bup; + VALUE old_gc; + + volatile VALUE receiver = arg->receiver; + volatile VALUE args = arg->args; + volatile VALUE failed = arg->failed; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + DUMP1("call ip_ruby_cmd_body"); + rb_trap_immediate = 0; + +#if 0 + ret = rb_rescue2(ip_ruby_cmd_core, (VALUE)arg, + ip_ruby_cmd_rescue, arg->failed, + rb_eStandardError, rb_eScriptError, rb_eSystemExit, + (VALUE)0); +#else + ret = rb_protect(ip_ruby_cmd_core, (VALUE)arg, &status); + + if (status) { + char *errtype, *buf; + int errtype_len, len; + + old_gc = rb_gc_disable(); + + switch(status) { + case TAG_RETURN: + errtype = "LocalJumpError: "; + errtype_len = strlen(errtype); + len = errtype_len + RSTRING(rb_obj_as_string(ruby_errinfo))->len; + buf = ALLOC_N(char, len + 1); + strncpy(buf, errtype, errtype_len); + strncpy(buf + errtype_len, + RSTRING(rb_obj_as_string(ruby_errinfo))->ptr, + RSTRING(rb_obj_as_string(ruby_errinfo))->len); + *(buf + len) = 0; + + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(eTkCallbackReturn, buf); + free(buf); + break; + + case TAG_BREAK: + errtype = "LocalJumpError: "; + errtype_len = strlen(errtype); + len = errtype_len + RSTRING(rb_obj_as_string(ruby_errinfo))->len; + buf = ALLOC_N(char, len + 1); + strncpy(buf, errtype, errtype_len); + strncpy(buf + errtype_len, + RSTRING(rb_obj_as_string(ruby_errinfo))->ptr, + RSTRING(rb_obj_as_string(ruby_errinfo))->len); + *(buf + len) = 0; + + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(eTkCallbackBreak, buf); + free(buf); + break; + + case TAG_NEXT: + errtype = "LocalJumpError: "; + errtype_len = strlen(errtype); + len = errtype_len + RSTRING(rb_obj_as_string(ruby_errinfo))->len; + buf = ALLOC_N(char, len + 1); + strncpy(buf, errtype, errtype_len); + strncpy(buf + errtype_len, + RSTRING(rb_obj_as_string(ruby_errinfo))->ptr, + RSTRING(rb_obj_as_string(ruby_errinfo))->len); + *(buf + len) = 0; + + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(eTkCallbackContinue,buf); + free(buf); + break; + + case TAG_RETRY: + case TAG_REDO: + RARRAY(arg->failed)->ptr[0] = ruby_errinfo; + break; + + case TAG_RAISE: + case TAG_FATAL: + RARRAY(arg->failed)->ptr[0] = ruby_errinfo; + break; + + default: + buf = ALLOC_N(char, 256); + rb_warn(buf, "unknown loncaljmp status %d", status); + RARRAY(arg->failed)->ptr[0] = rb_exc_new2(rb_eException, buf); + free(buf); + break; + } + + if (old_gc == Qfalse) rb_gc_enable(); + + ret = Qnil; + } +#endif + + rb_thread_critical = thr_crit_bup; + DUMP1("finish ip_ruby_cmd_body"); + + return ret; +} + +static VALUE +ip_ruby_cmd_ensure(trapflag) + VALUE trapflag; +{ + rb_trap_immediate = NUM2INT(trapflag); + return Qnil; +} + +/* ruby_cmd receiver method arg ... */ +static int +#if TCL_MAJOR_VERSION >= 8 +ip_ruby_cmd(clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + Tcl_Obj *CONST argv[]; +#else /* TCL_MAJOR_VERSION < 8 */ +ip_ruby_cmd(clientData, interp, argc, argv) + ClientData clientData; + Tcl_Interp *interp; + int argc; + char *argv[]; +#endif +{ + volatile VALUE res; + volatile VALUE receiver; + volatile ID method; + volatile VALUE args = rb_ary_new2(argc - 2); + volatile VALUE exception = rb_ary_new2(1); + char *str; + int i; + int len; + int old_trapflag; + struct cmd_body_arg *arg; + int thr_crit_bup; + VALUE old_gc; + + if (argc < 3) { + rb_raise(rb_eArgError, "too few arguments"); + } + + /* allocate */ + arg = ALLOC(struct cmd_body_arg); + + /* get arguments from Tcl objects */ + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + old_gc = rb_gc_disable(); + + /* get receiver */ +#if TCL_MAJOR_VERSION >= 8 + str = Tcl_GetStringFromObj(argv[1], &len); +#else /* TCL_MAJOR_VERSION < 8 */ + str = argv[1]; +#endif + DUMP2("receiver:%s",str); + if (str[0] == ':' || ('A' <= str[0] && str[0] <= 'Z')) { + /* class | module | constant */ + receiver = rb_const_get(rb_cObject, rb_intern(str)); + } else if (str[0] == '$') { + /* global variable */ + receiver = rb_gv_get(str); + } else { + /* global variable omitted '$' */ + char *buf; + + len = strlen(str); + buf = ALLOC_N(char, len + 2); + buf[0] = '$'; + strncpy(buf + 1, str, len); + buf[len + 1] = 0; + receiver = rb_gv_get(buf); + free(buf); + } + if (NIL_P(receiver)) { + rb_raise(rb_eArgError, "unknown class/module/global-variable '%s'", + str); + } + + /* get metrhod */ +#if TCL_MAJOR_VERSION >= 8 + str = Tcl_GetStringFromObj(argv[2], &len); +#else /* TCL_MAJOR_VERSION < 8 */ + str = argv[2]; +#endif + method = rb_intern(str); + + /* get args */ + RARRAY(args)->len = 0; + for(i = 3; i < argc; i++) { +#if TCL_MAJOR_VERSION >= 8 + str = Tcl_GetStringFromObj(argv[i], &len); + DUMP2("arg:%s",str); + RARRAY(args)->ptr[RARRAY(args)->len++] = rb_tainted_str_new(str, len); +#else /* TCL_MAJOR_VERSION < 8 */ + DUMP2("arg:%s",argv[i]); + RARRAY(args)->ptr[RARRAY(args)->len++] = rb_tainted_str_new2(argv[i]); +#endif + } + + if (old_gc == Qfalse) rb_gc_enable(); + rb_thread_critical = thr_crit_bup; + + RARRAY(exception)->ptr[0] = Qnil; + + arg->receiver = receiver; + arg->method = method; + arg->args = args; + arg->failed = exception; + + /* evaluate the argument string by ruby */ + old_trapflag = rb_trap_immediate; +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread()) { + rb_bug("cross-thread violation on ip_ruby_cmd()"); + } +#endif + + res = rb_ensure(ip_ruby_cmd_body, (VALUE)arg, + ip_ruby_cmd_ensure, INT2FIX(old_trapflag)); + + free(arg); + + /* status check */ + /* if (arg.failed) { */ + if (!NIL_P(RARRAY(exception)->ptr[0])) { + VALUE eclass; + volatile VALUE backtrace; + + DUMP1("(rb_eval_cmd result) failed"); + + Tcl_ResetResult(interp); + + res = RARRAY(exception)->ptr[0]; + eclass = rb_obj_class(res); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + DUMP1("set backtrace"); + backtrace = rb_ary_join(rb_funcall(res, ID_backtrace, 0, 0), + rb_str_new2("\n")); + StringValue(backtrace); + Tcl_AddErrorInfo(interp, RSTRING(backtrace)->ptr); + + rb_thread_critical = thr_crit_bup; + + if (eclass == eTkCallbackReturn) { + return TCL_RETURN; + + } else if (eclass == eTkCallbackBreak) { + return TCL_BREAK; + + } else if (eclass == eTkCallbackContinue) { + return TCL_CONTINUE; + + } else if (eclass == rb_eSystemExit) { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* Tcl_Eval(interp, "destroy ."); */ + if (Tk_GetNumMainWindows() > 0) { + Tk_Window main_win = Tk_MainWindow(interp); + if (main_win != (Tk_Window)NULL) { + Tk_DestroyWindow(main_win); + } + } + + /* StringValue(res); */ + res = rb_funcall(res, ID_message, 0, 0); + + Tcl_AppendResult(interp, RSTRING(res)->ptr, (char*)NULL); + + rb_thread_critical = thr_crit_bup; + + rb_raise(rb_eSystemExit, RSTRING(res)->ptr); + } else if (rb_obj_is_kind_of(res, eLocalJumpError)) { + VALUE reason = rb_ivar_get(res, ID_at_reason); + + if (TYPE(reason) != T_SYMBOL) { + ip_set_exc_message(interp, res); + return TCL_ERROR; + } + + if (SYM2ID(reason) == ID_return) { + return TCL_RETURN; + + } else if (SYM2ID(reason) == ID_break) { + return TCL_BREAK; + + } else if (SYM2ID(reason) == ID_next) { + return TCL_CONTINUE; + + } else { + ip_set_exc_message(interp, res); + return TCL_ERROR; + } + } else { + ip_set_exc_message(interp, res); + return TCL_ERROR; + } + } + + /* result must be string or nil */ + if (NIL_P(res)) { + DUMP1("(rb_eval_cmd result) nil"); + Tcl_ResetResult(interp); + return TCL_OK; + } + + + /* copy result to the tcl interpreter */ + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + + old_gc = rb_gc_disable(); + + res = TkStringValue(res); + + if (old_gc == Qfalse) rb_gc_enable(); + DUMP2("(rb_eval_cmd result) '%s'", RSTRING(res)->ptr); + DUMP1("Tcl_AppendResult"); + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, RSTRING(res)->ptr, (char *)NULL); + + rb_thread_critical = thr_crit_bup; + + DUMP1("end of ip_ruby_cmd"); return TCL_OK; } @@ -866,8 +1651,236 @@ ip_ruby(clientData, interp, argc, argv) /**************************/ /* based on tclEvent.c */ /**************************/ -static char *VwaitVarProc _((ClientData, Tcl_Interp *, CONST84 char *, - CONST84 char *, int)); + +#if 0 /* + Disable the following "update" and "thread_update". Bcause, + they don't work in a callback-proc. After calling update in + a callback-proc, the callback proc never be worked. + If the problem will be fixed in the future, may enable the + functions. + */ +/*********************/ +/* replace of update */ +/*********************/ +#if TCL_MAJOR_VERSION >= 8 +static int ip_rbUpdateObjCmd _((ClientData, Tcl_Interp *, int, + Tcl_Obj *CONST [])); +static int +ip_rbUpdateObjCmd(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +#else /* TCL_MAJOR_VERSION < 8 */ +static int ip_rbUpdateCommand _((ClientData, Tcl_Interp *, int, char *[])); +static int +ip_rbUpdateCommand(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + char *objv[]; +#endif +{ + int optionIndex; + int ret, done; + int flags = 0; + static CONST char *updateOptions[] = {"idletasks", (char *) NULL}; + enum updateOptions {REGEXP_IDLETASKS}; + char *nameString; + int dummy; + + DUMP1("Ruby's 'update' is called"); + if (objc == 1) { + flags = TCL_ALL_EVENTS|TCL_DONT_WAIT; + + } else if (objc == 2) { + if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, + "option", 0, &optionIndex) != TCL_OK) { + return TCL_ERROR; + } + switch ((enum updateOptions) optionIndex) { + case REGEXP_IDLETASKS: { + flags = TCL_WINDOW_EVENTS|TCL_IDLE_EVENTS|TCL_DONT_WAIT; + break; + } + default: { + Tcl_Panic("ip_rbUpdateObjCmd: bad option index to UpdateOptions"); + } + } + } else { +#ifdef Tcl_WrongNumArgs + Tcl_WrongNumArgs(interp, 1, objv, "[ idletasks ]"); +#else +# if TCL_MAJOR_VERSION >= 8 + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", + Tcl_GetStringFromObj(objv[0], &dummy), + " [ idletasks ]\"", + (char *) NULL); +# else /* TCL_MAJOR_VERSION < 8 */ + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", + objv[0], " [ idletasks ]\"", (char *) NULL); +# endif +#endif + return TCL_ERROR; + } + + /* call eventloop */ +#if 1 + ret = lib_eventloop_core(0, flags, (int *)NULL); /* ignore result */ +#else + Tcl_UpdateObjCmd(clientData, interp, objc, objv); +#endif + + /* + * Must clear the interpreter's result because event handlers could + * have executed commands. + */ + + DUMP2("last result '%s'", Tcl_GetStringResult(interp)); + Tcl_ResetResult(interp); + DUMP1("finish Ruby's 'update'"); + return TCL_OK; +} + + +/**********************/ +/* update with thread */ +/**********************/ +struct th_update_param { + VALUE thread; + int done; +}; + +static void rb_threadUpdateProc _((ClientData)); +static void +rb_threadUpdateProc(clientData) + ClientData clientData; /* Pointer to integer to set to 1. */ +{ + struct th_update_param *param = (struct th_update_param *) clientData; + + DUMP1("threadUpdateProc is called"); + param->done = 1; + rb_thread_run(param->thread); + + return; +} + +#if TCL_MAJOR_VERSION >= 8 +static int ip_rb_threadUpdateObjCmd _((ClientData, Tcl_Interp *, int, + Tcl_Obj *CONST [])); +static int +ip_rb_threadUpdateObjCmd(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj *CONST objv[]; +#else /* TCL_MAJOR_VERSION < 8 */ +static int ip_rb_threadUpdateCommand _((ClientData, Tcl_Interp *, int, + char *[])); +static int +ip_rb_threadUpdateCommand(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + char *objv[]; +#endif +{ + int optionIndex; + int ret, done; + int flags = 0; + int dummy; + struct th_update_param *param; + static CONST char *updateOptions[] = {"idletasks", (char *) NULL}; + enum updateOptions {REGEXP_IDLETASKS}; + volatile VALUE current_thread = rb_thread_current(); + + DUMP1("Ruby's 'thread_update' is called"); + + if (rb_thread_alone() || eventloop_thread == current_thread) { +#define USE_TCL_UPDATE 0 +#if TCL_MAJOR_VERSION >= 8 +# if USE_TCL_UPDATE + DUMP1("call Tcl_UpdateObjCmd"); + return Tcl_UpdateObjCmd(clientData, interp, objc, objv); +# else + DUMP1("call ip_rbUpdateObjCmd"); + return ip_rbUpdateObjCmd(clientData, interp, objc, objv); +# endif +#else /* TCL_MAJOR_VERSION < 8 */ +# if USE_TCL_UPDATE + DUMP1("call ip_rbUpdateCommand"); + return Tcl_UpdateCommand(clientData, interp, objc, objv); +# else + DUMP1("call ip_rbUpdateCommand"); + return ip_rbUpdateCommand(clientData, interp, objc, objv); +# endif +#endif + } + + DUMP1("start Ruby's 'thread_update' body"); + + if (objc == 1) { + flags = TCL_ALL_EVENTS|TCL_DONT_WAIT; + + } else if (objc == 2) { + if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, + "option", 0, &optionIndex) != TCL_OK) { + return TCL_ERROR; + } + switch ((enum updateOptions) optionIndex) { + case REGEXP_IDLETASKS: { + flags = TCL_WINDOW_EVENTS|TCL_IDLE_EVENTS|TCL_DONT_WAIT; + break; + } + default: { + Tcl_Panic("ip_rb_threadUpdateObjCmd: bad option index to UpdateOptions"); + } + } + } else { +#ifdef Tcl_WrongNumArgs + Tcl_WrongNumArgs(interp, 1, objv, "[ idletasks ]"); +#else +# if TCL_MAJOR_VERSION >= 8 + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", + Tcl_GetStringFromObj(objv[0], &dummy), + " [ idletasks ]\"", + (char *) NULL); +# else /* TCL_MAJOR_VERSION < 8 */ + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", + objv[0], " [ idletasks ]\"", (char *) NULL); +# endif +#endif + return TCL_ERROR; + } + + DUMP1("pass argument check"); + + param = (struct th_update_param *)Tcl_Alloc(sizeof(struct th_update_param)); + param->thread = current_thread; + param->done = 0; + + DUMP1("set idle proc"); + Tcl_DoWhenIdle(rb_threadUpdateProc, (ClientData) param); + + while(!param->done) { + DUMP1("wait for complete idle proc"); + rb_thread_stop(); + } + + Tcl_Free((char *)param); + + DUMP1("finish Ruby's 'thread_update'"); + return TCL_OK; +} +#endif /* update and thread_update don't work internal callback proc */ + + +/***************************/ +/* replace of vwait/tkwait */ +/***************************/ +#if TCL_MAJOR_VERSION >= 8 +static char *VwaitVarProc _((ClientData, Tcl_Interp *, + CONST84 char *,CONST84 char *, int)); static char * VwaitVarProc(clientData, interp, name1, name2, flags) ClientData clientData; /* Pointer to integer to set to 1. */ @@ -875,6 +1888,16 @@ VwaitVarProc(clientData, interp, name1, name2, flags) CONST84 char *name1; /* Name of variable. */ CONST84 char *name2; /* Second part of variable name. */ int flags; /* Information about what happened. */ +#else /* TCL_MAJOR_VERSION < 8 */ +static char *VwaitVarProc _((ClientData, Tcl_Interp *, char *, char *, int)); +static char * +VwaitVarProc(clientData, interp, name1, name2, flags) + ClientData clientData; /* Pointer to integer to set to 1. */ + Tcl_Interp *interp; /* Interpreter containing variable. */ + char *name1; /* Name of variable. */ + char *name2; /* Second part of variable name. */ + int flags; /* Information about what happened. */ +#endif { int *donePtr = (int *) clientData; @@ -891,7 +1914,7 @@ ip_rbVwaitObjCmd(clientData, interp, objc, objv) Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; -#else +#else /* TCL_MAJOR_VERSION < 8 */ static int ip_rbVwaitCommand _((ClientData, Tcl_Interp *, int, char *[])); static int ip_rbVwaitCommand(clientData, interp, objc, objv) @@ -901,44 +1924,71 @@ ip_rbVwaitCommand(clientData, interp, objc, objv) char *objv[]; #endif { - int done, foundEvent; + int ret, done, foundEvent; char *nameString; int dummy; + int thr_crit_bup; DUMP1("Ruby's 'vwait' is called"); if (objc != 2) { #ifdef Tcl_WrongNumArgs Tcl_WrongNumArgs(interp, 1, objv, "name"); #else + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 /* nameString = Tcl_GetString(objv[0]); */ nameString = Tcl_GetStringFromObj(objv[0], &dummy); -#else +#else /* TCL_MAJOR_VERSION < 8 */ nameString = objv[0]; #endif - Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", nameString, " name\"", (char *) NULL); + + rb_thread_critical = thr_crit_bup; #endif return TCL_ERROR; } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 /* nameString = Tcl_GetString(objv[1]); */ nameString = Tcl_GetStringFromObj(objv[1], &dummy); -#else +#else /* TCL_MAJOR_VERSION < 8 */ nameString = objv[1]; #endif + /* if (Tcl_TraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VwaitVarProc, (ClientData) &done) != TCL_OK) { return TCL_ERROR; - }; + } + */ + ret = Tcl_TraceVar(interp, nameString, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + VwaitVarProc, (ClientData) &done); + + rb_thread_critical = thr_crit_bup; + + if (ret != TCL_OK) { + return TCL_ERROR; + } done = 0; - foundEvent = lib_eventloop_core(/* not check root-widget */0, &done); + foundEvent = lib_eventloop_core(/* not check root-widget */0, 0, &done); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tcl_UntraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VwaitVarProc, (ClientData) &done); + rb_thread_critical = thr_crit_bup; + /* * Clear out the interpreter's result, since it may have been set * by event handlers. @@ -946,8 +1996,14 @@ ip_rbVwaitCommand(clientData, interp, objc, objv) Tcl_ResetResult(interp); if (!foundEvent) { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tcl_AppendResult(interp, "can't wait for variable \"", nameString, "\": would wait forever", (char *) NULL); + + rb_thread_critical = thr_crit_bup; + return TCL_ERROR; } return TCL_OK; @@ -957,8 +2013,9 @@ ip_rbVwaitCommand(clientData, interp, objc, objv) /**************************/ /* based on tkCmd.c */ /**************************/ -static char *WaitVariableProc _((ClientData, Tcl_Interp *, CONST84 char *, - CONST84 char *, int)); +#if TCL_MAJOR_VERSION >= 8 +static char *WaitVariableProc _((ClientData, Tcl_Interp *, + CONST84 char *,CONST84 char *, int)); static char * WaitVariableProc(clientData, interp, name1, name2, flags) ClientData clientData; /* Pointer to integer to set to 1. */ @@ -966,6 +2023,17 @@ WaitVariableProc(clientData, interp, name1, name2, flags) CONST84 char *name1; /* Name of variable. */ CONST84 char *name2; /* Second part of variable name. */ int flags; /* Information about what happened. */ +#else /* TCL_MAJOR_VERSION < 8 */ +static char *WaitVariableProc _((ClientData, Tcl_Interp *, + char *, char *, int)); +static char * +WaitVariableProc(clientData, interp, name1, name2, flags) + ClientData clientData; /* Pointer to integer to set to 1. */ + Tcl_Interp *interp; /* Interpreter containing variable. */ + char *name1; /* Name of variable. */ + char *name2; /* Second part of variable name. */ + int flags; /* Information about what happened. */ +#endif { int *donePtr = (int *) clientData; @@ -1011,7 +2079,7 @@ ip_rbTkWaitObjCmd(clientData, interp, objc, objv) Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; -#else +#else /* TCL_MAJOR_VERSION < 8 */ static int ip_rbTkWaitCommand _((ClientData, Tcl_Interp *, int, char *[])); static int ip_rbTkWaitCommand(clientData, interp, objc, objv) @@ -1027,7 +2095,8 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv) (char *) NULL }; enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW }; char *nameString; - int dummy; + int ret, dummy; + int thr_crit_bup; DUMP1("Ruby's 'tkwait' is called"); @@ -1035,27 +2104,46 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv) #ifdef Tcl_WrongNumArgs Tcl_WrongNumArgs(interp, 1, objv, "variable|visibility|window name"); #else + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 - Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", Tcl_GetStringFromObj(objv[0], &dummy), " variable|visibility|window name\"", (char *) NULL); -#else - Tcl_AppendResult(interp, "wrong # args: should be \"", +#else /* TCL_MAJOR_VERSION < 8 */ + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", objv[0], " variable|visibility|window name\"", (char *) NULL); #endif + + rb_thread_critical = thr_crit_bup; #endif return TCL_ERROR; } #if TCL_MAJOR_VERSION >= 8 + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)optionStrings, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } -#else + */ + ret = Tcl_GetIndexFromObj(interp, objv[1], + (CONST84 char **)optionStrings, + "option", 0, &index); + + rb_thread_critical = thr_crit_bup; + + if (ret != TCL_OK) { + return TCL_ERROR; + } +#else /* TCL_MAJOR_VERSION < 8 */ { int c = objv[1][0]; size_t length = strlen(objv[1]); @@ -1077,69 +2165,122 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv) } #endif + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 /* nameString = Tcl_GetString(objv[2]); */ nameString = Tcl_GetStringFromObj(objv[2], &dummy); -#else +#else /* TCL_MAJOR_VERSION < 8 */ nameString = objv[2]; #endif + rb_thread_critical = thr_crit_bup; + switch ((enum options) index) { case TKWAIT_VARIABLE: { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + /* if (Tcl_TraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, WaitVariableProc, (ClientData) &done) != TCL_OK) { return TCL_ERROR; } + */ + ret = Tcl_TraceVar(interp, nameString, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + WaitVariableProc, (ClientData) &done); + + rb_thread_critical = thr_crit_bup; + + if (ret != TCL_OK) { + return TCL_ERROR; + } done = 0; - lib_eventloop_core(check_rootwidget_flag, &done); + lib_eventloop_core(check_rootwidget_flag, 0, &done); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tcl_UntraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, WaitVariableProc, (ClientData) &done); + + rb_thread_critical = thr_crit_bup; + break; } case TKWAIT_VISIBILITY: { Tk_Window window; + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + window = Tk_NameToWindow(interp, nameString, tkwin); if (window == NULL) { + rb_thread_critical = thr_crit_bup; return TCL_ERROR; } + Tk_CreateEventHandler(window, VisibilityChangeMask|StructureNotifyMask, WaitVisibilityProc, (ClientData) &done); + + rb_thread_critical = thr_crit_bup; + done = 0; - lib_eventloop_core(check_rootwidget_flag, &done); + lib_eventloop_core(check_rootwidget_flag, 0, &done); if (done != 1) { /* * Note that we do not delete the event handler because it * was deleted automatically when the window was destroyed. */ + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; Tcl_ResetResult(interp); Tcl_AppendResult(interp, "window \"", nameString, "\" was deleted before its visibility changed", (char *) NULL); + + rb_thread_critical = thr_crit_bup; + return TCL_ERROR; } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tk_DeleteEventHandler(window, VisibilityChangeMask|StructureNotifyMask, WaitVisibilityProc, (ClientData) &done); + + rb_thread_critical = thr_crit_bup; + break; } case TKWAIT_WINDOW: { Tk_Window window; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; window = Tk_NameToWindow(interp, nameString, tkwin); if (window == NULL) { + rb_thread_critical = thr_crit_bup; return TCL_ERROR; } + Tk_CreateEventHandler(window, StructureNotifyMask, WaitWindowProc, (ClientData) &done); + + rb_thread_critical = thr_crit_bup; + done = 0; - lib_eventloop_core(check_rootwidget_flag, &done); + lib_eventloop_core(check_rootwidget_flag, 0, &done); /* * Note: there's no need to delete the event handler. It was * deleted automatically when the window was destroyed. @@ -1165,8 +2306,9 @@ struct th_vwait_param { int done; }; -static char *rb_threadVwaitProc _((ClientData, Tcl_Interp *, CONST84 char *, - CONST84 char *, int)); +#if TCL_MAJOR_VERSION >= 8 +static char *rb_threadVwaitProc _((ClientData, Tcl_Interp *, + CONST84 char *,CONST84 char *, int)); static char * rb_threadVwaitProc(clientData, interp, name1, name2, flags) ClientData clientData; /* Pointer to integer to set to 1. */ @@ -1174,6 +2316,17 @@ rb_threadVwaitProc(clientData, interp, name1, name2, flags) CONST84 char *name1; /* Name of variable. */ CONST84 char *name2; /* Second part of variable name. */ int flags; /* Information about what happened. */ +#else /* TCL_MAJOR_VERSION < 8 */ +static char *rb_threadVwaitProc _((ClientData, Tcl_Interp *, + char *, char *, int)); +static char * +rb_threadVwaitProc(clientData, interp, name1, name2, flags) + ClientData clientData; /* Pointer to integer to set to 1. */ + Tcl_Interp *interp; /* Interpreter containing variable. */ + char *name1; /* Name of variable. */ + char *name2; /* Second part of variable name. */ + int flags; /* Information about what happened. */ +#endif { struct th_vwait_param *param = (struct th_vwait_param *) clientData; @@ -1197,6 +2350,7 @@ rb_threadWaitVisibilityProc(clientData, eventPtr) if (eventPtr->type == DestroyNotify) { param->done = 2; } + rb_thread_run(param->thread); } static void rb_threadWaitWindowProc _((ClientData, XEvent *)); @@ -1210,6 +2364,7 @@ rb_threadWaitWindowProc(clientData, eventPtr) if (eventPtr->type == DestroyNotify) { param->done = 1; } + rb_thread_run(param->thread); } #if TCL_MAJOR_VERSION >= 8 @@ -1221,7 +2376,7 @@ ip_rb_threadVwaitObjCmd(clientData, interp, objc, objv) Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; -#else +#else /* TCL_MAJOR_VERSION < 8 */ static int ip_rb_threadVwaitCommand _((ClientData, Tcl_Interp *, int, char *[])); static int @@ -1234,15 +2389,17 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) { struct th_vwait_param *param; char *nameString; - int dummy; + int ret, dummy; + int thr_crit_bup; + volatile VALUE current_thread = rb_thread_current(); DUMP1("Ruby's 'thread_vwait' is called"); - if (eventloop_thread == rb_thread_current()) { + if (rb_thread_alone() || eventloop_thread == current_thread) { #if TCL_MAJOR_VERSION >= 8 DUMP1("call ip_rbVwaitObjCmd"); return ip_rbVwaitObjCmd(clientData, interp, objc, objv); -#else +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("call ip_rbVwaitCommand"); return ip_rbVwaitCommand(clientData, interp, objc, objv); #endif @@ -1252,44 +2409,69 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) #ifdef Tcl_WrongNumArgs Tcl_WrongNumArgs(interp, 1, objv, "name"); #else + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 /* nameString = Tcl_GetString(objv[0]); */ nameString = Tcl_GetStringFromObj(objv[0], &dummy); -#else +#else /* TCL_MAJOR_VERSION < 8 */ nameString = objv[0]; #endif - Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", nameString, " name\"", (char *) NULL); + + rb_thread_critical = thr_crit_bup; #endif return TCL_ERROR; } #if TCL_MAJOR_VERSION >= 8 /* nameString = Tcl_GetString(objv[1]); */ nameString = Tcl_GetStringFromObj(objv[1], &dummy); -#else +#else /* TCL_MAJOR_VERSION < 8 */ nameString = objv[1]; #endif + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); - param->thread = rb_thread_current(); + param->thread = current_thread; param->done = 0; + /* if (Tcl_TraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, rb_threadVwaitProc, (ClientData) param) != TCL_OK) { return TCL_ERROR; - }; + } + */ + ret = Tcl_TraceVar(interp, nameString, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + rb_threadVwaitProc, (ClientData) param); - if (!param->done) { + rb_thread_critical = thr_crit_bup; + + if (ret != TCL_OK) { + return TCL_ERROR; + } + + /* if (!param->done) { */ + while(!param->done) { rb_thread_stop(); } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tcl_UntraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, rb_threadVwaitProc, (ClientData) param); Tcl_Free((char *)param); + rb_thread_critical = thr_crit_bup; + return TCL_OK; } @@ -1302,7 +2484,7 @@ ip_rb_threadTkWaitObjCmd(clientData, interp, objc, objv) Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; -#else +#else /* TCL_MAJOR_VERSION < 8 */ static int ip_rb_threadTkWaitCommand _((ClientData, Tcl_Interp *, int, char *[])); static int @@ -1320,15 +2502,17 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) (char *) NULL }; enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW }; char *nameString; - int dummy; + int ret, dummy; + int thr_crit_bup; + volatile VALUE current_thread = rb_thread_current(); DUMP1("Ruby's 'thread_tkwait' is called"); - if (eventloop_thread == rb_thread_current()) { + if (rb_thread_alone() || eventloop_thread == current_thread) { #if TCL_MAJOR_VERSION >= 8 DUMP1("call ip_rbTkWaitObjCmd"); return ip_rbTkWaitObjCmd(clientData, interp, objc, objv); -#else +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("call rb_VwaitCommand"); return ip_rbTkWaitCommand(clientData, interp, objc, objv); #endif @@ -1338,27 +2522,45 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) #ifdef Tcl_WrongNumArgs Tcl_WrongNumArgs(interp, 1, objv, "variable|visibility|window name"); #else + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 - Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", Tcl_GetStringFromObj(objv[0], &dummy), " variable|visibility|window name\"", (char *) NULL); -#else - Tcl_AppendResult(interp, "wrong # args: should be \"", +#else /* TCL_MAJOR_VERSION < 8 */ + Tcl_AppendResult(interp, "wrong number of arguments: should be \"", objv[0], " variable|visibility|window name\"", (char *) NULL); #endif + + rb_thread_critical = thr_crit_bup; #endif return TCL_ERROR; } #if TCL_MAJOR_VERSION >= 8 + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + /* if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)optionStrings, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } -#else + */ + ret = Tcl_GetIndexFromObj(interp, objv[1], + (CONST84 char **)optionStrings, + "option", 0, &index); + + rb_thread_critical = thr_crit_bup; + + if (ret != TCL_OK) { + return TCL_ERROR; + } +#else /* TCL_MAJOR_VERSION < 8 */ { int c = objv[1][0]; size_t length = strlen(objv[1]); @@ -1380,85 +2582,139 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) } #endif + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + #if TCL_MAJOR_VERSION >= 8 /* nameString = Tcl_GetString(objv[2]); */ nameString = Tcl_GetStringFromObj(objv[2], &dummy); -#else +#else /* TCL_MAJOR_VERSION < 8 */ nameString = objv[2]; #endif param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); - param->thread = rb_thread_current(); + param->thread = current_thread; param->done = 0; + rb_thread_critical = thr_crit_bup; + switch ((enum options) index) { case TKWAIT_VARIABLE: { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + /* if (Tcl_TraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, rb_threadVwaitProc, (ClientData) param) != TCL_OK) { return TCL_ERROR; - }; + } + */ + ret = Tcl_TraceVar(interp, nameString, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + rb_threadVwaitProc, (ClientData) param); - if (!param->done) { + rb_thread_critical = thr_crit_bup; + + if (ret != TCL_OK) { + return TCL_ERROR; + } + + /* if (!param->done) { */ + while(!param->done) { rb_thread_stop(); } + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + Tcl_UntraceVar(interp, nameString, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, rb_threadVwaitProc, (ClientData) param); + + rb_thread_critical = thr_crit_bup; + break; } case TKWAIT_VISIBILITY: { Tk_Window window; + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + window = Tk_NameToWindow(interp, nameString, tkwin); if (window == NULL) { + rb_thread_critical = thr_crit_bup; return TCL_ERROR; } + Tk_CreateEventHandler(window, VisibilityChangeMask|StructureNotifyMask, rb_threadWaitVisibilityProc, (ClientData) param); - if (!param->done) { + + rb_thread_critical = thr_crit_bup; + + /* if (!param->done) { */ + while(!param->done) { rb_thread_stop(); } - if (param->done != 1) { - /* - * Note that we do not delete the event handler because it - * was deleted automatically when the window was destroyed. - */ + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + Tk_DeleteEventHandler(window, + VisibilityChangeMask|StructureNotifyMask, + rb_threadWaitVisibilityProc, (ClientData) param); + + if (param->done != 1) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "window \"", nameString, "\" was deleted before its visibility changed", (char *) NULL); + + rb_thread_critical = thr_crit_bup; + return TCL_ERROR; } - Tk_DeleteEventHandler(window, - VisibilityChangeMask|StructureNotifyMask, - rb_threadWaitVisibilityProc, (ClientData) param); + + rb_thread_critical = thr_crit_bup; + break; } case TKWAIT_WINDOW: { Tk_Window window; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; window = Tk_NameToWindow(interp, nameString, tkwin); if (window == NULL) { + rb_thread_critical = thr_crit_bup; return TCL_ERROR; } + Tk_CreateEventHandler(window, StructureNotifyMask, rb_threadWaitWindowProc, (ClientData) param); - if (!param->done) { + + rb_thread_critical = thr_crit_bup; + + /* if (!param->done) { */ + while(!param->done) { rb_thread_stop(); } - /* - * Note: there's no need to delete the event handler. It was - * deleted automatically when the window was destroyed. - */ + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + Tk_DeleteEventHandler(window, StructureNotifyMask, + rb_threadWaitWindowProc, (ClientData) param); + + rb_thread_critical = thr_crit_bup; + break; } - } + } /* end of 'switch' statement */ Tcl_Free((char *)param); @@ -1499,16 +2755,48 @@ ip_thread_tkwait(self, mode, target) /* destroy interpreter */ +VALUE del_root(ip) + Tcl_Interp *ip; +{ + Tcl_Preserve(ip); + Tk_DestroyWindow(Tk_MainWindow(ip)); + Tcl_Release(ip); + return Qnil; +} + static void ip_free(ptr) struct tcltkip *ptr; { - DUMP1("Tcl_DeleteInterp"); + int try = 3; + Tcl_CmdInfo info; + int thr_crit_bup; + + DUMP1("free Tcl Interp"); if (ptr) { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + if (!Tcl_InterpDeleted(ptr->ip)) { + Tcl_ResetResult(ptr->ip); + Tcl_Preserve(ptr->ip); + 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); + } + for(; try > 0; try--) { + if (!Tk_GetNumMainWindows()) break; + rb_protect(del_root, (VALUE)(ptr->ip), 0); + } + Tcl_Release(ptr->ip); + Tcl_DeleteInterp(ptr->ip); + } Tcl_Release((ClientData)ptr->ip); - Tcl_DeleteInterp(ptr->ip); free(ptr); + + rb_thread_critical = thr_crit_bup; } + DUMP1("complete freeing Tcl Interp"); } /* create and initialize interpreter */ @@ -1530,6 +2818,7 @@ ip_init(argc, argv, self) VALUE argv0, opts; int cnt; int with_tk = 1; + Tk_Window mainWin; /* create object */ Data_Get_Struct(self, struct tcltkip, ptr); @@ -1546,7 +2835,11 @@ ip_init(argc, argv, self) /* from Tcl_AppInit() */ DUMP1("Tcl_Init"); if (Tcl_Init(ptr->ip) == TCL_ERROR) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif } /* set variables */ @@ -1554,7 +2847,7 @@ ip_init(argc, argv, self) switch(cnt) { case 2: /* options */ - if (opts == Qnil || opts == Qfalse) { + if (NIL_P(opts) || opts == Qfalse) { /* without Tk */ with_tk = 0; } else { @@ -1562,7 +2855,7 @@ ip_init(argc, argv, self) } case 1: /* argv0 */ - if (argv0 != Qnil) { + if (!NIL_P(argv0)) { Tcl_SetVar(ptr->ip, "argv0", StringValuePtr(argv0), 0); } case 0: @@ -1574,70 +2867,119 @@ ip_init(argc, argv, self) if (with_tk) { DUMP1("Tk_Init"); if (Tk_Init(ptr->ip) == TCL_ERROR) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif } DUMP1("Tcl_StaticPackage(\"Tk\")"); #if TCL_MAJOR_VERSION >= 8 Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit); -#else +#else /* TCL_MAJOR_VERSION < 8 */ Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); #endif } + /* get main window */ + mainWin = Tk_MainWindow(ptr->ip); + /* add ruby command to the interpreter */ #if TCL_MAJOR_VERSION >= 8 DUMP1("Tcl_CreateObjCommand(\"ruby\")"); - Tcl_CreateObjCommand(ptr->ip, "ruby", ip_ruby, (ClientData)NULL, + Tcl_CreateObjCommand(ptr->ip, "ruby", ip_ruby_eval, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -#else + DUMP1("Tcl_CreateObjCommand(\"ruby_eval\")"); + Tcl_CreateObjCommand(ptr->ip, "ruby_eval", ip_ruby_eval, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + DUMP1("Tcl_CreateObjCommand(\"ruby_cmd\")"); + Tcl_CreateObjCommand(ptr->ip, "ruby_cmd", ip_ruby_cmd, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("Tcl_CreateCommand(\"ruby\")"); - Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby, (ClientData)NULL, + Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby_eval, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + DUMP1("Tcl_CreateCommand(\"ruby_eval\")"); + Tcl_CreateCommand(ptr->ip, "ruby_eval", ip_ruby_eval, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + DUMP1("Tcl_CreateCommand(\"ruby_cmd\")"); + Tcl_CreateCommand(ptr->ip, "ruby_cmd", ip_ruby_cmd, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); +#endif + +#if 0 /* + Disable the following "update" and "thread_update". Bcause, + they don't work in a callback-proc. After calling update in + a callback-proc, the callback proc never be worked. + If the problem will be fixed in the future, may enable the + functions. + */ + /* replace 'update' command */ +# if TCL_MAJOR_VERSION >= 8 + DUMP1("Tcl_CreateObjCommand(\"update\")"); + Tcl_CreateObjCommand(ptr->ip, "update", ip_rbUpdateObjCmd, + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +# else /* TCL_MAJOR_VERSION < 8 */ + DUMP1("Tcl_CreateCommand(\"update\")"); + Tcl_CreateCommand(ptr->ip, "update", ip_rbUpdateCommand, + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +# endif + + /* add 'thread_update' command */ +# if TCL_MAJOR_VERSION >= 8 + DUMP1("Tcl_CreateObjCommand(\"thread_update\")"); + Tcl_CreateObjCommand(ptr->ip, "thread_update", ip_rb_threadUpdateObjCmd, + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +# else /* TCL_MAJOR_VERSION < 8 */ + DUMP1("Tcl_CreateCommand(\"thread_update\")"); + Tcl_CreateCommand(ptr->ip, "thread_update", ip_rb_threadUpdateCommand, + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +# endif #endif /* replace 'vwait' command */ #if TCL_MAJOR_VERSION >= 8 DUMP1("Tcl_CreateObjCommand(\"vwait\")"); Tcl_CreateObjCommand(ptr->ip, "vwait", ip_rbVwaitObjCmd, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -#else + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("Tcl_CreateCommand(\"vwait\")"); Tcl_CreateCommand(ptr->ip, "vwait", ip_rbVwaitCommand, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); #endif /* replace 'tkwait' command */ #if TCL_MAJOR_VERSION >= 8 DUMP1("Tcl_CreateObjCommand(\"tkwait\")"); Tcl_CreateObjCommand(ptr->ip, "tkwait", ip_rbTkWaitObjCmd, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -#else + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("Tcl_CreateCommand(\"tkwait\")"); Tcl_CreateCommand(ptr->ip, "tkwait", ip_rbTkWaitCommand, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); #endif /* add 'thread_vwait' command */ #if TCL_MAJOR_VERSION >= 8 DUMP1("Tcl_CreateObjCommand(\"thread_vwait\")"); Tcl_CreateObjCommand(ptr->ip, "thread_vwait", ip_rb_threadVwaitObjCmd, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -#else + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("Tcl_CreateCommand(\"thread_vwait\")"); Tcl_CreateCommand(ptr->ip, "thread_vwait", ip_rb_threadVwaitCommand, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); #endif /* add 'thread_tkwait' command */ #if TCL_MAJOR_VERSION >= 8 DUMP1("Tcl_CreateObjCommand(\"thread_tkwait\")"); Tcl_CreateObjCommand(ptr->ip, "thread_tkwait", ip_rb_threadTkWaitObjCmd, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -#else + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); +#else /* TCL_MAJOR_VERSION < 8 */ DUMP1("Tcl_CreateCommand(\"thread_tkwait\")"); Tcl_CreateCommand(ptr->ip, "thread_tkwait", ip_rb_threadTkWaitCommand, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL); #endif return self; @@ -1651,9 +2993,10 @@ ip_create_slave(argc, argv, self) { struct tcltkip *master = get_ip(self); struct tcltkip *slave = ALLOC(struct tcltkip); - VALUE name; VALUE safemode; + VALUE name; int safe; + int thr_crit_bup; /* safe-mode check */ if (rb_scan_args(argc, argv, "11", &name, &safemode) == 1) { @@ -1661,21 +3004,26 @@ ip_create_slave(argc, argv, self) } if (Tcl_IsSafe(master->ip) == 1) { safe = 1; - } else if (safemode == Qfalse || safemode == Qnil) { + } else if (safemode == Qfalse || NIL_P(safemode)) { safe = 0; rb_secure(4); } else { safe = 1; } + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + /* create slave-ip */ - if ((slave->ip = Tcl_CreateSlave(master->ip, StringValuePtr(name), safe)) - == NULL) { + slave->ip = Tcl_CreateSlave(master->ip, StringValuePtr(name), safe); + if (slave->ip == NULL) { rb_raise(rb_eRuntimeError, "fail to create the new slave interpreter"); } Tcl_Preserve((ClientData)slave->ip); slave->return_value = 0; + rb_thread_critical = thr_crit_bup; + return Data_Wrap_Struct(CLASS_OF(self), 0, ip_free, slave); } @@ -1687,7 +3035,11 @@ ip_make_safe(self) struct tcltkip *ptr = get_ip(self); if (Tcl_MakeSafe(ptr->ip) == TCL_ERROR) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif } return self; @@ -1734,277 +3086,6 @@ ip_is_deleted_p(self) } -/* eval string in tcl by Tcl_Eval() */ -static VALUE -ip_eval_real(self, str) - VALUE self; - VALUE str; -{ - char *s; - char *buf; /* Tcl_Eval requires re-writable string region */ - struct tcltkip *ptr = get_ip(self); - - /* call Tcl_Eval() */ - s = StringValuePtr(str); - buf = ALLOCA_N(char, strlen(s)+1); - strcpy(buf, s); - DUMP2("Tcl_Eval(%s)", buf); - ptr->return_value = Tcl_Eval(ptr->ip, buf); - if (ptr->return_value == TCL_ERROR) { - rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); - } - DUMP2("(TCL_Eval result) %d", ptr->return_value); - - /* pass back the result (as string) */ - /* return(rb_str_new2(ptr->ip->result)); */ - return(rb_tainted_str_new2(ptr->ip->result)); -} - -static VALUE -evq_safelevel_handler(arg, evq) - VALUE arg; - VALUE evq; -{ - struct eval_queue *q; - - Data_Get_Struct(evq, struct eval_queue, q); - DUMP2("(safe-level handler) $SAFE = %d", q->safe_level); - rb_set_safe_level(q->safe_level); - return ip_eval_real(q->obj, q->str); -} - -int eval_queue_handler _((Tcl_Event *, int)); -int -eval_queue_handler(evPtr, flags) - Tcl_Event *evPtr; - int flags; -{ - struct eval_queue *q = (struct eval_queue *)evPtr; - - DUMP2("do_eval_queue_handler : evPtr = %p", evPtr); - DUMP2("eval queue_thread : %lx", rb_thread_current()); - DUMP2("added by thread : %lx", q->thread); - - if (q->done) { - DUMP1("processed by another event-loop"); - return 0; - } else { - DUMP1("process it on current event-loop"); - } - - /* process it */ - q->done = 1; - - /* check safe-level */ - if (rb_safe_level() != q->safe_level) { - *(q->result) - = rb_funcall(rb_proc_new(evq_safelevel_handler, - Data_Wrap_Struct(rb_cData,0,0,q)), - rb_intern("call"), 0); - } else { - DUMP2("call eval_real (for caller thread:%lx)", q->thread); - DUMP2("call eval_real (current thread:%lx)", rb_thread_current()); - *(q->result) = ip_eval_real(q->obj, q->str); - } - - /* back to caller */ - DUMP2("back to caller (caller thread:%lx)", q->thread); - DUMP2(" (current thread:%lx)", rb_thread_current()); - rb_thread_run(q->thread); - DUMP1("finish back to caller"); - - /* end of handler : remove it */ - return 1; -} - -static VALUE -ip_eval(self, str) - VALUE self; - VALUE str; -{ - struct eval_queue *tmp; - VALUE current = rb_thread_current(); - VALUE result; - VALUE *alloc_result; - Tcl_QueuePosition position; - - if (eventloop_thread == 0 || current == eventloop_thread) { - if (eventloop_thread) { - DUMP2("eval from current eventloop %lx", current); - } else { - DUMP2("eval from thread:%lx but no eventloop", current); - } - result = ip_eval_real(self, str); - if (rb_obj_is_kind_of(result, rb_eException)) { - rb_exc_raise(result); - } - return result; - } - - DUMP2("eval from thread %lx (NOT current eventloop)", current); - - /* allocate memory (protected from Tcl_ServiceEvent) */ - alloc_result = ALLOC(VALUE); - - /* allocate memory (freed by Tcl_ServiceEvent) */ - tmp = (struct eval_queue *)Tcl_Alloc(sizeof(struct eval_queue)); - - /* construct event data */ - tmp->done = 0; - tmp->obj = self; - tmp->str = str; - tmp->result = alloc_result; - tmp->thread = current; - tmp->safe_level = rb_safe_level(); - tmp->ev.proc = eval_queue_handler; - position = TCL_QUEUE_TAIL; - - /* add the handler to Tcl event queue */ - DUMP1("add handler"); - Tcl_QueueEvent(&(tmp->ev), position); - - /* wait for the handler to be processed */ - DUMP2("wait for handler (current thread:%lx)", current); - rb_thread_stop(); - DUMP2("back from handler (current thread:%lx)", current); - - /* get result & free allocated memory */ - result = *alloc_result; - free(alloc_result); - if (rb_obj_is_kind_of(result, rb_eException)) { - rb_exc_raise(result); - } - - return result; -} - - -/* restart Tk */ -static VALUE -lib_restart(self) - VALUE self; -{ - struct tcltkip *ptr = get_ip(self); - - rb_secure(4); - - /* destroy the root wdiget */ - /* ptr->return_value = Tcl_Eval(ptr->ip, "destroy ."); */ - ptr->return_value = FIX2INT(ip_eval(self, "destroy .")); - /* ignore ERROR */ - DUMP2("(TCL_Eval result) %d", ptr->return_value); - Tcl_ResetResult(ptr->ip); - - /* execute Tk_Init of Tk_SafeInit */ -#if TCL_MAJOR_VERSION >= 8 - if (Tcl_IsSafe(ptr->ip)) { - DUMP1("Tk_SafeInit"); - if (Tk_SafeInit(ptr->ip) == TCL_ERROR) { - rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); - } - } else { - DUMP1("Tk_Init"); - if (Tk_Init(ptr->ip) == TCL_ERROR) { - rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); - } - } -#else - DUMP1("Tk_Init"); - if (Tk_Init(ptr->ip) == TCL_ERROR) { - rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); - } -#endif - - return Qnil; -} - - -static VALUE -ip_restart(self) - VALUE self; -{ - struct tcltkip *ptr = get_ip(self); - - rb_secure(4); - if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) { - /* slave IP */ - return Qnil; - } - return lib_restart(self); -} - -static VALUE -ip_toUTF8(self, str, encodename) - VALUE self; - VALUE str; - VALUE encodename; -{ -#ifdef TCL_UTF_MAX - Tcl_Interp *interp; - Tcl_Encoding encoding; - Tcl_DString dstr; - struct tcltkip *ptr; - char *buf; - - ptr = get_ip(self); - interp = ptr->ip; - - StringValue(encodename); - StringValue(str); - encoding = Tcl_GetEncoding(interp, RSTRING(encodename)->ptr); - if (!RSTRING(str)->len) return str; - buf = ALLOCA_N(char,strlen(RSTRING(str)->ptr)+1); - strcpy(buf, RSTRING(str)->ptr); - - Tcl_DStringInit(&dstr); - Tcl_DStringFree(&dstr); - Tcl_ExternalToUtfDString(encoding,buf,strlen(buf),&dstr); - /* str = rb_str_new2(Tcl_DStringValue(&dstr)); */ - str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); - - Tcl_FreeEncoding(encoding); - Tcl_DStringFree(&dstr); -#endif - return str; -} - -static VALUE -ip_fromUTF8(self, str, encodename) - VALUE self; - VALUE str; - VALUE encodename; -{ -#ifdef TCL_UTF_MAX - Tcl_Interp *interp; - Tcl_Encoding encoding; - Tcl_DString dstr; - struct tcltkip *ptr; - char *buf; - - ptr = get_ip(self); - interp = ptr->ip; - - StringValue(encodename); - StringValue(str); - encoding = Tcl_GetEncoding(interp,RSTRING(encodename)->ptr); - if (!RSTRING(str)->len) return str; - buf = ALLOCA_N(char,strlen(RSTRING(str)->ptr)+1); - strcpy(buf,RSTRING(str)->ptr); - - Tcl_DStringInit(&dstr); - Tcl_DStringFree(&dstr); - Tcl_UtfToExternalDString(encoding,buf,strlen(buf),&dstr); - /* str = rb_str_new2(Tcl_DStringValue(&dstr)); */ - str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); - - Tcl_FreeEncoding(encoding); - Tcl_DStringFree(&dstr); - -#endif - return str; -} - - static VALUE #ifdef HAVE_STDARG_PROTOTYPES create_ip_exc(VALUE interp, VALUE exc, const char *fmt, ...) @@ -2025,50 +3106,718 @@ create_ip_exc(interp, exc, fmt, va_alist) buf[BUFSIZ - 1] = '\0'; va_end(args); einfo = rb_exc_new2(exc, buf); - rb_iv_set(einfo, "interp", interp); + rb_ivar_set(einfo, ID_at_interp, interp); Tcl_ResetResult(get_ip(interp)->ip); + return einfo; } +static VALUE +ip_get_result_string_obj(interp) + Tcl_Interp *interp; +{ +#if TCL_MAJOR_VERSION >= 8 + int len; + char *s; + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + s = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &len); + return(rb_tainted_str_new(s, len)); + +# else /* TCL_VERSION >= 8.1 */ + volatile VALUE strval; + Tcl_Obj *retobj = Tcl_GetObjResult(interp); + int thr_crit_bup; + + Tcl_IncrRefCount(retobj); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + if (Tcl_GetCharLength(retobj) != Tcl_UniCharLen(Tcl_GetUnicode(retobj))) { + /* possibly binary string */ + s = Tcl_GetByteArrayFromObj(retobj, &len); + 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); + } + + rb_thread_critical = thr_crit_bup; + + Tcl_DecrRefCount(retobj); + + return(strval); + +# endif +#else /* TCL_MAJOR_VERSION < 8 */ + return(rb_tainted_str_new2(interp->result)); +#endif +} + +/* eval string in tcl by Tcl_Eval() */ +static VALUE +ip_eval_real(self, cmd_str, cmd_len) + VALUE self; + char *cmd_str; + int cmd_len; +{ + char *s; + int len; + struct tcltkip *ptr = get_ip(self); + int thr_crit_bup; + +#if TCL_MAJOR_VERSION >= 8 + /* call Tcl_EvalObj() */ + { + Tcl_Obj *cmd; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + cmd = Tcl_NewStringObj(cmd_str, cmd_len); + Tcl_IncrRefCount(cmd); + ptr->return_value = Tcl_EvalObj(ptr->ip, cmd); + /* ptr->return_value = Tcl_GlobalEvalObj(ptr->ip, cmd); */ + Tcl_DecrRefCount(cmd); + + rb_thread_critical = thr_crit_bup; + } +#else /* TCL_MAJOR_VERSION < 8 */ + DUMP2("Tcl_Eval(%s)", cmd_str); + ptr->return_value = Tcl_Eval(ptr->ip, cmd_str); + /* ptr->return_value = Tcl_GlobalEval(ptr->ip, cmd_str); */ +#endif + + if (ptr->return_value == TCL_ERROR) { +#if TCL_MAJOR_VERSION >= 8 + return create_ip_exc(self, rb_eRuntimeError, + "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + return create_ip_exc(self, rb_eRuntimeError, + "%s", ptr->ip->result); +#endif + } + DUMP2("(TCL_Eval result) %d", ptr->return_value); + + /* pass back the result (as string) */ + return ip_get_result_string_obj(ptr->ip); +} + +static VALUE +evq_safelevel_handler(arg, evq) + VALUE arg; + VALUE evq; +{ + struct eval_queue *q; + + Data_Get_Struct(evq, struct eval_queue, q); + DUMP2("(safe-level handler) $SAFE = %d", q->safe_level); + rb_set_safe_level(q->safe_level); + return ip_eval_real(q->interp, q->str, q->len); +} + +int eval_queue_handler _((Tcl_Event *, int)); +int +eval_queue_handler(evPtr, flags) + Tcl_Event *evPtr; + int flags; +{ + struct eval_queue *q = (struct eval_queue *)evPtr; + volatile VALUE ret; + + DUMP2("do_eval_queue_handler : evPtr = %p", evPtr); + DUMP2("eval queue_thread : %lx", rb_thread_current()); + DUMP2("added by thread : %lx", q->thread); + + if (*(q->done)) { + DUMP1("processed by another event-loop"); + return 0; + } else { + DUMP1("process it on current event-loop"); + } + + /* process it */ + *(q->done) = 1; + + /* check safe-level */ + if (rb_safe_level() != q->safe_level) { + volatile VALUE q_dat; +#ifdef HAVE_NATIVETHREAD + if (!is_ruby_native_thread()) { + rb_bug("cross-thread violation on eval_queue_handler()"); + } +#endif + q_dat = Data_Wrap_Struct(rb_cData,eval_queue_mark,0,q); + ret = rb_funcall(rb_proc_new(evq_safelevel_handler, q_dat), + ID_call, 0); + } else { + DUMP2("call eval_real (for caller thread:%lx)", q->thread); + DUMP2("call eval_real (current thread:%lx)", rb_thread_current()); + ret = ip_eval_real(q->interp, q->str, q->len); + } + + /* set result */ + RARRAY(q->result)->ptr[0] = ret; + + /* complete */ + *(q->done) = -1; + + /* back to caller */ + DUMP2("back to caller (caller thread:%lx)", q->thread); + DUMP2(" (current thread:%lx)", rb_thread_current()); + rb_thread_run(q->thread); + DUMP1("finish back to caller"); + + /* end of handler : remove it */ + return 1; +} + +static VALUE +ip_eval(self, str) + VALUE self; + VALUE str; +{ + struct eval_queue *evq; + char *eval_str; + int *alloc_done; + int thr_crit_bup; + VALUE current = rb_thread_current(); + volatile VALUE result = rb_ary_new2(1); + volatile VALUE ret; + Tcl_QueuePosition position; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + StringValue(str); + rb_thread_critical = thr_crit_bup; + + if (eventloop_thread == 0 || current == eventloop_thread) { + if (eventloop_thread) { + DUMP2("eval from current eventloop %lx", current); + } else { + DUMP2("eval from thread:%lx but no eventloop", current); + } + result = ip_eval_real(self, RSTRING(str)->ptr, RSTRING(str)->len); + if (rb_obj_is_kind_of(result, rb_eException)) { + rb_exc_raise(result); + } + return result; + } + + DUMP2("eval from thread %lx (NOT current eventloop)", current); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* allocate memory (protected from Tcl_ServiceEvent) */ + alloc_done = (int*)ALLOC(int); + *alloc_done = 0; + + eval_str = ALLOC_N(char, RSTRING(str)->len + 1); + strncpy(eval_str, RSTRING(str)->ptr, RSTRING(str)->len); + eval_str[RSTRING(str)->len] = 0; + + /* allocate memory (freed by Tcl_ServiceEvent) */ + evq = (struct eval_queue *)Tcl_Alloc(sizeof(struct eval_queue)); + + /* construct event data */ + evq->done = alloc_done; + evq->str = eval_str; + evq->len = RSTRING(str)->len; + evq->interp = self; + evq->result = result; + evq->thread = current; + evq->safe_level = rb_safe_level(); + evq->ev.proc = eval_queue_handler; + position = TCL_QUEUE_TAIL; + + /* add the handler to Tcl event queue */ + DUMP1("add handler"); + Tcl_QueueEvent(&(evq->ev), position); + + rb_thread_critical = thr_crit_bup; + + /* wait for the handler to be processed */ + DUMP2("wait for handler (current thread:%lx)", current); + while(*alloc_done >= 0) { + rb_thread_stop(); + } + DUMP2("back from handler (current thread:%lx)", current); + + /* get result & free allocated memory */ + ret = RARRAY(result)->ptr[0]; + free(alloc_done); + free(eval_str); + if (rb_obj_is_kind_of(ret, rb_eException)) { + rb_exc_raise(ret); + } + + return ret; +} + + +/* restart Tk */ +static VALUE +lib_restart(self) + VALUE self; +{ + struct tcltkip *ptr = get_ip(self); + int thr_crit_bup; + + rb_secure(4); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* destroy the root wdiget */ + ptr->return_value = Tcl_Eval(ptr->ip, "destroy ."); + /* ignore ERROR */ + DUMP2("(TCL_Eval result) %d", ptr->return_value); + Tcl_ResetResult(ptr->ip); + + /* delete namespace ( tested on tk8.4.5 ) */ + ptr->return_value = Tcl_Eval(ptr->ip, "namespace delete ::tk::msgcat"); + /* ignore ERROR */ + DUMP2("(TCL_Eval result) %d", ptr->return_value); + Tcl_ResetResult(ptr->ip); + + /* delete trace proc ( tested on tk8.4.5 ) */ + ptr->return_value = Tcl_Eval(ptr->ip, "trace vdelete ::tk_strictMotif w ::tk::EventMotifBindings"); + /* ignore ERROR */ + DUMP2("(TCL_Eval result) %d", ptr->return_value); + Tcl_ResetResult(ptr->ip); + + /* execute Tk_Init of Tk_SafeInit */ +#if TCL_MAJOR_VERSION >= 8 + if (Tcl_IsSafe(ptr->ip)) { + DUMP1("Tk_SafeInit"); + if (Tk_SafeInit(ptr->ip) == TCL_ERROR) { + rb_thread_critical = thr_crit_bup; + /* rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); */ + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); + } + } else { + DUMP1("Tk_Init"); + if (Tk_Init(ptr->ip) == TCL_ERROR) { + rb_thread_critical = thr_crit_bup; + /* rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); */ + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); + } + } +#else /* TCL_MAJOR_VERSION < 8 */ + DUMP1("Tk_Init"); + if (Tk_Init(ptr->ip) == TCL_ERROR) { + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); + } +#endif + + rb_thread_critical = thr_crit_bup; + + return Qnil; +} + static VALUE -ip_invoke_real(argc, argv, obj) - int argc; - VALUE *argv; - VALUE obj; +ip_restart(self) + VALUE self; { - VALUE v; - struct tcltkip *ptr; /* tcltkip data struct */ + struct tcltkip *ptr = get_ip(self); + + rb_secure(4); + if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) { + /* slave IP */ + return Qnil; + } + return lib_restart(self); +} + +static VALUE +lib_toUTF8_core(ip_obj, src, encodename) + VALUE ip_obj; + VALUE src; + VALUE encodename; +{ + volatile VALUE str = src; + +#ifdef TCL_UTF_MAX + Tcl_Interp *interp; + Tcl_Encoding encoding; + Tcl_DString dstr; + int taint_flag = OBJ_TAINTED(str); + struct tcltkip *ptr; + char *buf; + int thr_crit_bup; + + if (NIL_P(ip_obj)) { + interp = (Tcl_Interp *)NULL; + } else { + interp = get_ip(ip_obj)->ip; + } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + if (NIL_P(encodename)) { + if (TYPE(str) == T_STRING) { + volatile VALUE enc; + + enc = rb_ivar_get(str, ID_at_enc); + if (NIL_P(enc)) { + if (NIL_P(ip_obj)) { + encoding = (Tcl_Encoding)NULL; + } else { + enc = rb_ivar_get(ip_obj, ID_at_enc); + if (NIL_P(enc)) { + encoding = (Tcl_Encoding)NULL; + } else { + StringValue(enc); + encoding = Tcl_GetEncoding(interp, RSTRING(enc)->ptr); + if (encoding == (Tcl_Encoding)NULL) { + rb_warning("Tk-interp has unknown encoding information (@encoding:'%s')", RSTRING(enc)->ptr); + } + } + } + } else { + StringValue(enc); + if (strcmp(RSTRING(enc)->ptr, "binary") == 0) { + rb_thread_critical = thr_crit_bup; + return str; + } + encoding = Tcl_GetEncoding(interp, RSTRING(enc)->ptr); + if (encoding == (Tcl_Encoding)NULL) { + rb_warning("string has unknown encoding information (@encoding:'%s')", RSTRING(enc)->ptr); + } + } + } else { + encoding = (Tcl_Encoding)NULL; + } + } else { + StringValue(encodename); + encoding = Tcl_GetEncoding(interp, RSTRING(encodename)->ptr); + if (encoding == (Tcl_Encoding)NULL) { + rb_warning("unknown encoding name '%s'", RSTRING(encodename)->ptr); + } + } + + StringValue(str); + if (!RSTRING(str)->len) { + rb_thread_critical = thr_crit_bup; + return str; + } + + buf = ALLOC_N(char,(RSTRING(str)->len)+1); + strncpy(buf, RSTRING(str)->ptr, RSTRING(str)->len); + buf[RSTRING(str)->len] = 0; + + Tcl_DStringInit(&dstr); + Tcl_DStringFree(&dstr); + /* Tcl_ExternalToUtfDString(encoding,buf,strlen(buf),&dstr); */ + Tcl_ExternalToUtfDString(encoding, buf, RSTRING(str)->len, &dstr); + + /* str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); */ + str = rb_str_new2(Tcl_DStringValue(&dstr)); + rb_ivar_set(str, ID_at_enc, rb_tainted_str_new2("utf-8")); + if (taint_flag) OBJ_TAINT(str); + + if (encoding != (Tcl_Encoding)NULL) { + Tcl_FreeEncoding(encoding); + } + Tcl_DStringFree(&dstr); + + free(buf); + + rb_thread_critical = thr_crit_bup; +#endif + + return str; +} + +static VALUE +lib_toUTF8(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE str, encodename; + + if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) { + encodename = Qnil; + } + return lib_toUTF8_core(Qnil, str, encodename); +} + +static VALUE +ip_toUTF8(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE str, encodename; + + if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) { + encodename = Qnil; + } + return lib_toUTF8_core(self, str, encodename); +} + +static VALUE +lib_fromUTF8_core(ip_obj, src, encodename) + VALUE ip_obj; + VALUE src; + VALUE encodename; +{ + volatile VALUE str = src; + +#ifdef TCL_UTF_MAX + Tcl_Interp *interp; + Tcl_Encoding encoding; + Tcl_DString dstr; + int taint_flag = OBJ_TAINTED(str); + char *buf; + int thr_crit_bup; + + if (NIL_P(ip_obj)) { + interp = (Tcl_Interp *)NULL; + } else { + interp = get_ip(ip_obj)->ip; + } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + if (NIL_P(encodename)) { + volatile VALUE enc; + + if (TYPE(str) == T_STRING) { + enc = rb_ivar_get(str, ID_at_enc); + if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) { + rb_thread_critical = thr_crit_bup; + return str; + } + } + + if (NIL_P(ip_obj)) { + encoding = (Tcl_Encoding)NULL; + } else { + enc = rb_ivar_get(ip_obj, ID_at_enc); + if (NIL_P(enc)) { + encoding = (Tcl_Encoding)NULL; + } else { + StringValue(enc); + encoding = Tcl_GetEncoding(interp, RSTRING(enc)->ptr); + if (encoding == (Tcl_Encoding)NULL) { + rb_warning("Tk-interp has unknown encoding information (@encoding:'%s')", RSTRING(enc)->ptr); + } else { + encodename = rb_obj_dup(enc); + } + } + } + + } else { + StringValue(encodename); + + if (strcmp(RSTRING(encodename)->ptr, "binary") == 0) { + char *s; + int len; + + s = Tcl_GetByteArrayFromObj(Tcl_NewStringObj(RSTRING(str)->ptr, + RSTRING(str)->len), + &len); + str = rb_tainted_str_new(s, len); + rb_ivar_set(str, ID_at_enc, rb_tainted_str_new2("binary")); + + rb_thread_critical = thr_crit_bup; + return str; + } + + encoding = Tcl_GetEncoding(interp, RSTRING(encodename)->ptr); + if (encoding == (Tcl_Encoding)NULL) { + rb_warning("unknown encoding name '%s'", RSTRING(encodename)->ptr); + encodename = Qnil; + } + } + + StringValue(str); + + if (RSTRING(str)->len == 0) { + rb_thread_critical = thr_crit_bup; + return rb_tainted_str_new2(""); + } + + buf = ALLOC_N(char,strlen(RSTRING(str)->ptr)+1); + strncpy(buf, RSTRING(str)->ptr, RSTRING(str)->len); + buf[RSTRING(str)->len] = 0; + + Tcl_DStringInit(&dstr); + Tcl_DStringFree(&dstr); + /* Tcl_UtfToExternalDString(encoding,buf,strlen(buf),&dstr); */ + Tcl_UtfToExternalDString(encoding,buf,RSTRING(str)->len,&dstr); + + /* str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); */ + str = rb_str_new2(Tcl_DStringValue(&dstr)); + rb_ivar_set(str, ID_at_enc, encodename); + if (taint_flag) OBJ_TAINT(str); + + if (encoding != (Tcl_Encoding)NULL) { + Tcl_FreeEncoding(encoding); + } + Tcl_DStringFree(&dstr); + + free(buf); + + rb_thread_critical = thr_crit_bup; +#endif + + return str; +} + +static VALUE +lib_fromUTF8(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE str, encodename; + + if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) { + encodename = Qnil; + } + return lib_fromUTF8_core(Qnil, str, encodename); +} + +static VALUE +ip_fromUTF8(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE str, encodename; + + if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) { + encodename = Qnil; + } + return lib_fromUTF8_core(self, str, encodename); +} + +static VALUE +lib_UTF_backslash_core(self, str, all_bs) + VALUE self; + VALUE str; + int all_bs; +{ +#ifdef TCL_UTF_MAX + char *src_buf, *dst_buf, *ptr; + int read_len = 0, dst_len = 0; + int taint_flag = OBJ_TAINTED(str); + int thr_crit_bup; + + StringValue(str); + if (!RSTRING(str)->len) { + return str; + } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + src_buf = ALLOC_N(char,(RSTRING(str)->len)+1); + strncpy(src_buf, RSTRING(str)->ptr, RSTRING(str)->len); + src_buf[RSTRING(str)->len] = 0; + + dst_buf = ALLOC_N(char,(RSTRING(str)->len)+1); + + ptr = src_buf; + while(RSTRING(str)->len > ptr - src_buf) { + if (*ptr == '\\' && (all_bs || *(ptr + 1) == 'u')) { + dst_len += Tcl_UtfBackslash(ptr, &read_len, (dst_buf + dst_len)); + ptr += read_len; + } else { + *(dst_buf + (dst_len++)) = *(ptr++); + } + } + + str = rb_str_new(dst_buf, dst_len); + if (taint_flag) OBJ_TAINT(str); + + free(src_buf); + free(dst_buf); + + rb_thread_critical = thr_crit_bup; +#endif + + return str; +} + +static VALUE +lib_UTF_backslash(self, str) + VALUE self; + VALUE str; +{ + return lib_UTF_backslash_core(self, str, 0); +} + +static VALUE +lib_Tcl_backslash(self, str) + VALUE self; + VALUE str; +{ + return lib_UTF_backslash_core(self, str, 1); +} + +#if TCL_MAJOR_VERSION >= 8 +static VALUE +ip_invoke_core(interp, objc, objv) + VALUE interp; + int objc; + Tcl_Obj **objv; +#else +static VALUE +ip_invoke_core(interp, argc, argv) + VALUE interp; + int argc; + char **argv; +#endif +{ + struct tcltkip *ptr; int i; Tcl_CmdInfo info; - char *cmd, *s; - char **av = (char **)NULL; + char *cmd; + char *s; + int len; + int thr_crit_bup; + #if TCL_MAJOR_VERSION >= 8 - Tcl_Obj **ov = (Tcl_Obj **)NULL; + int argc = objc; + char **argv = (char **)NULL; Tcl_Obj *resultPtr; #endif - DUMP2("invoke_real called by thread:%lx", rb_thread_current()); - /* get the command name string */ - v = argv[0]; - cmd = StringValuePtr(v); - /* get the data struct */ - ptr = get_ip(obj); + ptr = get_ip(interp); /* ip is deleted? */ if (Tcl_InterpDeleted(ptr->ip)) { + DUMP1("ip is deleted"); return rb_tainted_str_new2(""); } + /* get the command name string */ +#if TCL_MAJOR_VERSION >= 8 + cmd = Tcl_GetStringFromObj(objv[0], &len); +#else /* TCL_MAJOR_VERSION < 8 */ + cmd = argv[0]; +#endif + /* map from the command name to a C procedure */ DUMP2("call Tcl_GetCommandInfo, %s", cmd); if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) { - DUMP1("error Tcl_GetCommandInfo"); + DUMP1("error Tcl_GetCommandInfo"); /* if (event_loop_abort_on_exc || cmd[0] != '.') { */ if (event_loop_abort_on_exc > 0) { /*rb_ip_raise(obj,rb_eNameError,"invalid command name `%s'",cmd);*/ - return create_ip_exc(obj, rb_eNameError, + return create_ip_exc(interp, rb_eNameError, "invalid command name `%s'", cmd); } else { if (event_loop_abort_on_exc < 0) { @@ -2082,74 +3831,75 @@ ip_invoke_real(argc, argv, obj) } DUMP1("end Tcl_GetCommandInfo"); + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + /* memory allocation for arguments of this command */ #if TCL_MAJOR_VERSION >= 8 - if (info.isNativeObjectProc) { - /* object interface */ - ov = (Tcl_Obj **)ALLOCA_N(Tcl_Obj *, argc+1); - for (i = 0; i < argc; ++i) { - v = argv[i]; - s = StringValuePtr(v); - ov[i] = Tcl_NewStringObj(s, RSTRING(v)->len); - Tcl_IncrRefCount(ov[i]); - } - ov[argc] = (Tcl_Obj *)NULL; - } - else -#endif - { + if (!info.isNativeObjectProc) { /* string interface */ - av = (char **)ALLOCA_N(char *, argc+1); + argv = (char **)ALLOC_N(char *, argc+1); for (i = 0; i < argc; ++i) { - v = argv[i]; - s = StringValuePtr(v); - av[i] = ALLOCA_N(char, strlen(s)+1); - strcpy(av[i], s); + argv[i] = Tcl_GetStringFromObj(objv[i], &len); } - av[argc] = (char *)NULL; + argv[argc] = (char *)NULL; } +#endif Tcl_ResetResult(ptr->ip); /* Invoke the C procedure */ #if TCL_MAJOR_VERSION >= 8 if (info.isNativeObjectProc) { - int dummy; - ptr->return_value = (*info.objProc)(info.objClientData, - ptr->ip, argc, ov); - + ptr->return_value = (*info.objProc)(info.objClientData, ptr->ip, + objc, objv); +#if 0 /* get the string value from the result object */ resultPtr = Tcl_GetObjResult(ptr->ip); - Tcl_SetResult(ptr->ip, Tcl_GetStringFromObj(resultPtr, &dummy), + Tcl_SetResult(ptr->ip, Tcl_GetStringFromObj(resultPtr, &len), TCL_VOLATILE); - - for (i=0; i= 8 ptr->return_value = (*info.proc)(info.clientData, ptr->ip, - argc, (CONST84 char **)av); + argc, (CONST84 char **)argv); + + free(argv); + #else /* TCL_MAJOR_VERSION < 8 */ - ptr->return_value = (*info.proc)(info.clientData, ptr->ip, argc, av); + ptr->return_value = (*info.proc)(info.clientData, ptr->ip, + argc, argv); #endif - TRAP_END; } + rb_thread_critical = thr_crit_bup; + /* exception on mainloop */ if (ptr->return_value == TCL_ERROR) { if (event_loop_abort_on_exc > 0 && !Tcl_InterpDeleted(ptr->ip)) { - /*rb_ip_raise(obj, rb_eRuntimeError, "%s", ptr->ip->result);*/ - return create_ip_exc(obj, rb_eRuntimeError, "%s", ptr->ip->result); +#if TCL_MAJOR_VERSION >= 8 + return create_ip_exc(interp, rb_eRuntimeError, + "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + return create_ip_exc(interp, rb_eRuntimeError, + "%s", ptr->ip->result); +#endif } else { if (event_loop_abort_on_exc < 0) { +#if TCL_MAJOR_VERSION >= 8 + rb_warning("%s (ignore)", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ rb_warning("%s (ignore)", ptr->ip->result); +#endif } else { +#if TCL_MAJOR_VERSION >= 8 + rb_warn("%s (ignore)", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ rb_warn("%s (ignore)", ptr->ip->result); +#endif } Tcl_ResetResult(ptr->ip); return rb_tainted_str_new2(""); @@ -2157,8 +3907,143 @@ ip_invoke_real(argc, argv, obj) } /* pass back the result (as string) */ - /* return rb_str_new2(ptr->ip->result); */ - return rb_tainted_str_new2(ptr->ip->result); + return ip_get_result_string_obj(ptr->ip); +} + + +#if TCL_MAJOR_VERSION >= 8 +static Tcl_Obj ** +#else /* TCL_MAJOR_VERSION < 8 */ +static char ** +#endif +alloc_invoke_arguments(argc, argv) + int argc; + VALUE *argv; +{ + int i; + VALUE v; + char *s; + int thr_crit_bup; + +#if TCL_MAJOR_VERSION >= 8 + Tcl_Obj **av = (Tcl_Obj **)NULL; + Tcl_Obj *resultPtr; +#else /* TCL_MAJOR_VERSION < 8 */ + char **av = (char **)NULL; +#endif + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* memory allocation */ +#if TCL_MAJOR_VERSION >= 8 + av = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, argc+1); + for (i = 0; i < argc; ++i) { + VALUE enc; + + v = argv[i]; + s = StringValuePtr(v); + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + av[i] = Tcl_NewStringObj(s, RSTRING(v)->len); +# else /* TCL_VERSION >= 8.1 */ + enc = rb_ivar_get(v, ID_at_enc); + if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) { + /* binary string */ + av[i] = Tcl_NewByteArrayObj(s, RSTRING(v)->len); + } else if (strlen(s) != RSTRING(v)->len) { + /* probably binary string */ + av[i] = Tcl_NewByteArrayObj(s, RSTRING(v)->len); + } else { + /* probably text string */ + av[i] = Tcl_NewStringObj(s, RSTRING(v)->len); + } +# endif + Tcl_IncrRefCount(av[i]); + } + av[argc] = (Tcl_Obj *)NULL; + +#else /* TCL_MAJOR_VERSION < 8 */ + /* string interface */ + av = (char **)ALLOC_N(char *, argc+1); + for (i = 0; i < argc; ++i) { + v = argv[i]; + s = StringValuePtr(v); + av[i] = ALLOC_N(char, strlen(s)+1); + strcpy(av[i], s); + } + av[argc] = (char *)NULL; +#endif + + rb_thread_critical = thr_crit_bup; + + return av; +} + +static void +free_invoke_arguments(argc, av) + int argc; +#if TCL_MAJOR_VERSION >= 8 + Tcl_Obj **av; +#else /* TCL_MAJOR_VERSION < 8 */ + char **av; +#endif +{ + int i; + + for (i = 0; i < argc; ++i) { +#if TCL_MAJOR_VERSION >= 8 + Tcl_DecrRefCount(av[i]); +#else /* TCL_MAJOR_VERSION < 8 */ + free(av[i]); +#endif + } + free(av); +} + +static VALUE +ip_invoke_real(argc, argv, interp) + int argc; + VALUE *argv; + VALUE interp; +{ + VALUE v; + struct tcltkip *ptr; /* tcltkip data struct */ + int i; + Tcl_CmdInfo info; + char *s; + int len; + int thr_crit_bup; + +#if TCL_MAJOR_VERSION >= 8 + Tcl_Obj **av = (Tcl_Obj **)NULL; + Tcl_Obj *resultPtr; +#else /* TCL_MAJOR_VERSION < 8 */ + char **av = (char **)NULL; +#endif + + DUMP2("invoke_real called by thread:%lx", rb_thread_current()); + + /* get the data struct */ + ptr = get_ip(interp); + + /* ip is deleted? */ + if (Tcl_InterpDeleted(ptr->ip)) { + DUMP1("ip is deleted"); + return rb_tainted_str_new2(""); + } + + /* allocate memory for arguments */ + av = alloc_invoke_arguments(argc, argv); + + /* Invoke the C procedure */ + Tcl_ResetResult(ptr->ip); + v = ip_invoke_core(interp, argc, av); + + /* free allocated memory */ + free_invoke_arguments(argc, av); + + return v; } VALUE @@ -2171,7 +4056,7 @@ ivq_safelevel_handler(arg, ivq) Data_Get_Struct(ivq, struct invoke_queue, q); DUMP2("(safe-level handler) $SAFE = %d", q->safe_level); rb_set_safe_level(q->safe_level); - return ip_invoke_real(q->argc, q->argv, q->obj); + return ip_invoke_core(q->interp, q->argc, q->argv); } int invoke_queue_handler _((Tcl_Event *, int)); @@ -2181,12 +4066,13 @@ invoke_queue_handler(evPtr, flags) int flags; { struct invoke_queue *q = (struct invoke_queue *)evPtr; + volatile VALUE ret; DUMP2("do_invoke_queue_handler : evPtr = %p", evPtr); DUMP2("invoke queue_thread : %lx", rb_thread_current()); DUMP2("added by thread : %lx", q->thread); - if (q->done) { + if (*(q->done)) { DUMP1("processed by another event-loop"); return 0; } else { @@ -2194,20 +4080,26 @@ invoke_queue_handler(evPtr, flags) } /* process it */ - q->done = 1; + *(q->done) = 1; /* check safe-level */ if (rb_safe_level() != q->safe_level) { - *(q->result) - = rb_funcall(rb_proc_new(ivq_safelevel_handler, - Data_Wrap_Struct(rb_cData,0,0,q)), - rb_intern("call"), 0); + volatile VALUE q_dat; + q_dat = Data_Wrap_Struct(rb_cData,invoke_queue_mark,0,q); + ret = rb_funcall(rb_proc_new(evq_safelevel_handler, q_dat), + ID_call, 0); } else { - DUMP2("call invoke_real (for caller thread:%lx)", q->thread); - DUMP2("call invoke_real (current thread:%lx)", rb_thread_current()); - *(q->result) = ip_invoke_real(q->argc, q->argv, q->obj); + DUMP2("call invoke_real (for caller thread:%lx)", q->thread); + DUMP2("call invoke_real (current thread:%lx)", rb_thread_current()); + ret = ip_invoke_core(q->interp, q->argc, q->argv); } + /* set result */ + RARRAY(q->result)->ptr[0] = ret; + + /* complete */ + *(q->done) = -1; + /* back to caller */ DUMP2("back to caller (caller thread:%lx)", q->thread); DUMP2(" (current thread:%lx)", rb_thread_current()); @@ -2219,16 +4111,28 @@ invoke_queue_handler(evPtr, flags) } static VALUE -ip_invoke(argc, argv, obj) +ip_invoke_with_position(argc, argv, obj, position) int argc; VALUE *argv; VALUE obj; -{ - struct invoke_queue *tmp; - VALUE current = rb_thread_current(); - VALUE result; - VALUE *alloc_argv, *alloc_result; Tcl_QueuePosition position; +{ + struct invoke_queue *ivq; + char *s; + int len; + int i; + int *alloc_done; + int thr_crit_bup; + VALUE v; + VALUE current = rb_thread_current(); + volatile VALUE result = rb_ary_new2(1); + volatile VALUE ret; + +#if TCL_MAJOR_VERSION >= 8 + Tcl_Obj **av = (Tcl_Obj **)NULL; +#else /* TCL_MAJOR_VERSION < 8 */ + char **av = (char **)NULL; +#endif if (argc < 1) { rb_raise(rb_eArgError, "command name missing"); @@ -2248,45 +4152,60 @@ ip_invoke(argc, argv, obj) DUMP2("invoke from thread %lx (NOT current eventloop)", current); - /* allocate memory (protected from Tcl_ServiceEvent) */ - alloc_argv = ALLOC_N(VALUE,argc); - MEMCPY(alloc_argv, argv, VALUE, argc); - alloc_result = ALLOC(VALUE); + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + /* allocate memory (for arguments) */ + av = alloc_invoke_arguments(argc, argv); + + /* allocate memory (keep result) */ + alloc_done = (int*)ALLOC(int); + *alloc_done = 0; /* allocate memory (freed by Tcl_ServiceEvent) */ - tmp = (struct invoke_queue *)Tcl_Alloc(sizeof(struct invoke_queue)); + ivq = (struct invoke_queue *)Tcl_Alloc(sizeof(struct invoke_queue)); /* construct event data */ - tmp->done = 0; - tmp->obj = obj; - tmp->argc = argc; - tmp->argv = alloc_argv; - tmp->result = alloc_result; - tmp->thread = current; - tmp->safe_level = rb_safe_level(); - tmp->ev.proc = invoke_queue_handler; - position = TCL_QUEUE_TAIL; + ivq->done = alloc_done; + ivq->argc = argc; + ivq->argv = av; + ivq->interp = obj; + ivq->result = result; + ivq->thread = current; + ivq->safe_level = rb_safe_level(); + ivq->ev.proc = invoke_queue_handler; /* add the handler to Tcl event queue */ DUMP1("add handler"); - Tcl_QueueEvent(&(tmp->ev), position); + Tcl_QueueEvent(&(ivq->ev), position); + + rb_thread_critical = thr_crit_bup; /* wait for the handler to be processed */ DUMP2("wait for handler (current thread:%lx)", current); - rb_thread_stop(); + while(*alloc_done >= 0) { + rb_thread_stop(); + } DUMP2("back from handler (current thread:%lx)", current); /* get result & free allocated memory */ - result = *alloc_result; - free(alloc_argv); - free(alloc_result); - if (rb_obj_is_kind_of(result, rb_eException)) { - rb_exc_raise(result); + ret = RARRAY(result)->ptr[0]; + free(alloc_done); + + /* free allocated memory */ + free_invoke_arguments(argc, av); + + /* exception? */ + if (rb_obj_is_kind_of(ret, rb_eException)) { + DUMP1("raise exception"); + rb_exc_raise(ret); } - return result; + DUMP1("exit ip_invoke"); + return ret; } + /* get return code from Tcl_Eval() */ static VALUE ip_retval(self) @@ -2300,6 +4219,864 @@ ip_retval(self) return (INT2FIX(ptr->return_value)); } +static VALUE +ip_invoke(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ + return ip_invoke_with_position(argc, argv, obj, TCL_QUEUE_TAIL); +} + +static VALUE +ip_invoke_immediate(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ + return ip_invoke_with_position(argc, argv, obj, TCL_QUEUE_HEAD); +} + +/* access Tcl variables */ +static VALUE +ip_get_variable(self, varname_arg, flag_arg) + VALUE self; + VALUE varname_arg; + VALUE flag_arg; +{ + struct tcltkip *ptr = get_ip(self); + int thr_crit_bup; + volatile VALUE varname, flag; + + varname = varname_arg; + flag = flag_arg; + + StringValue(varname); + +#if TCL_MAJOR_VERSION >= 8 + { + Tcl_Obj *nameobj, *ret; + char *s; + int len; + VALUE strval; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + nameobj = Tcl_NewStringObj(RSTRING(varname)->ptr, + RSTRING(varname)->len); + Tcl_IncrRefCount(nameobj); + + ret = Tcl_ObjGetVar2(ptr->ip, nameobj, (Tcl_Obj*)NULL, FIX2INT(flag)); + + Tcl_DecrRefCount(nameobj); + + rb_thread_critical = thr_crit_bup; + + if (ret == (Tcl_Obj*)NULL) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif + } + + Tcl_IncrRefCount(ret); + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + s = Tcl_GetStringFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); + Tcl_DecrRefCount(ret); + return(strval); +# else /* TCL_VERSION >= 8.1 */ + { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + if (Tcl_GetCharLength(ret) + != Tcl_UniCharLen(Tcl_GetUnicode(ret))) { + /* possibly binary string */ + s = Tcl_GetByteArrayFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); + rb_ivar_set(strval, ID_at_enc, rb_tainted_str_new2("binary")); + } else { + /* possibly text string */ + s = Tcl_GetStringFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); + } + + rb_thread_critical = thr_crit_bup; + } + + Tcl_DecrRefCount(ret); + return(strval); +# endif + } +#else /* TCL_MAJOR_VERSION < 8 */ + { + char *ret; + + ret = Tcl_GetVar2(ptr->ip, RSTRING(varname)->ptr, + (char*)NULL, FIX2INT(flag)); + if (ret == (char*)NULL) { + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); + } + return(rb_tainted_str_new2(ret)); + } +#endif +} + +static VALUE +ip_get_variable2(self, varname_arg, index_arg, flag_arg) + VALUE self; + VALUE varname_arg; + VALUE index_arg; + VALUE flag_arg; +{ + struct tcltkip *ptr = get_ip(self); + int thr_crit_bup; + volatile VALUE varname, index, flag; + + if (NIL_P(index_arg)) { + return ip_get_variable(self, varname_arg, flag_arg); + } + + varname = varname_arg; + index = index_arg; + flag = flag_arg; + + StringValue(varname); + StringValue(index); + +#if TCL_MAJOR_VERSION >= 8 + { + Tcl_Obj *nameobj, *idxobj, *ret; + char *s; + int len; + volatile VALUE strval; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + nameobj = Tcl_NewStringObj(RSTRING(varname)->ptr, + RSTRING(varname)->len); + Tcl_IncrRefCount(nameobj); + idxobj = Tcl_NewStringObj(RSTRING(index)->ptr, RSTRING(index)->len); + Tcl_IncrRefCount(idxobj); + + ret = Tcl_ObjGetVar2(ptr->ip, nameobj, idxobj, FIX2INT(flag)); + + Tcl_IncrRefCount(ret); + Tcl_DecrRefCount(nameobj); + Tcl_DecrRefCount(idxobj); + + rb_thread_critical = thr_crit_bup; + + if (ret == (Tcl_Obj*)NULL) { + Tcl_DecrRefCount(ret); +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif + } +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + s = Tcl_GetStringFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); + Tcl_DecrRefCount(ret); + return(strval); +# else /* TCL_VERSION >= 8.1 */ + { + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + if (Tcl_GetCharLength(ret) + != Tcl_UniCharLen(Tcl_GetUnicode(ret))) { + /* possibly binary string */ + s = Tcl_GetByteArrayFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); + rb_ivar_set(strval, ID_at_enc, rb_tainted_str_new2("binary")); + } else { + /* possibly text string */ + s = Tcl_GetStringFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); + } + + rb_thread_critical = thr_crit_bup; + } + + Tcl_DecrRefCount(ret); + return(strval); +# endif + } +#else /* TCL_MAJOR_VERSION < 8 */ + { + char *ret; + + ret = Tcl_GetVar2(ptr->ip, RSTRING(varname)->ptr, RSTRING(index)->ptr, + FIX2INT(flag)); + if (ret == (char*)NULL) { + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); + } + return(rb_tainted_str_new2(ret)); + } +#endif +} + +static VALUE +ip_set_variable(self, varname_arg, value_arg, flag_arg) + VALUE self; + VALUE varname_arg; + VALUE value_arg; + VALUE flag_arg; +{ + struct tcltkip *ptr = get_ip(self); + int thr_crit_bup; + volatile VALUE varname, value, flag; + + varname = varname_arg; + value = value_arg; + flag = flag_arg; + + StringValue(varname); + StringValue(value); + +#if TCL_MAJOR_VERSION >= 8 + { + Tcl_Obj *nameobj, *valobj, *ret; + char *s; + int len; + volatile VALUE strval; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + nameobj = Tcl_NewStringObj(RSTRING(varname)->ptr, + RSTRING(varname)->len); + Tcl_IncrRefCount(nameobj); + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + valobj = Tcl_NewStringObj(RSTRING(value)->ptr, + RSTRING(value)->len); + Tcl_IncrRefCount(valobj); +# else /* TCL_VERSION >= 8.1 */ + { + VALUE enc = rb_ivar_get(value, ID_at_enc); + + if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) { + /* binary string */ + valobj = Tcl_NewByteArrayObj(RSTRING(value)->ptr, + RSTRING(value)->len); + } else if (strlen(RSTRING(value)->ptr) != RSTRING(value)->len) { + /* probably binary string */ + valobj = Tcl_NewByteArrayObj(RSTRING(value)->ptr, + RSTRING(value)->len); + } else { + /* probably text string */ + valobj = Tcl_NewStringObj(RSTRING(value)->ptr, + RSTRING(value)->len); + } + + Tcl_IncrRefCount(valobj); + } +# endif + + ret = Tcl_ObjSetVar2(ptr->ip, nameobj, (Tcl_Obj*)NULL, valobj, + FIX2INT(flag)); + + Tcl_DecrRefCount(nameobj); + Tcl_DecrRefCount(valobj); + + if (ret == (Tcl_Obj*)NULL) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif + } + + Tcl_IncrRefCount(ret); + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + s = Tcl_GetStringFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); +# else /* TCL_VERSION >= 8.1 */ + if (Tcl_GetCharLength(ret) != Tcl_UniCharLen(Tcl_GetUnicode(ret))) { + /* possibly binary string */ + s = Tcl_GetByteArrayFromObj(ret, &len); + 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(ret, &len); + strval = rb_tainted_str_new(s, len); + } +# endif + + rb_thread_critical = thr_crit_bup; + + Tcl_DecrRefCount(ret); + + return(strval); + } +#else /* TCL_MAJOR_VERSION < 8 */ + { + CONST char *ret; + + ret = Tcl_SetVar2(ptr->ip, RSTRING(varname)->ptr, (char*)NULL, + RSTRING(value)->ptr, (int)FIX2INT(flag)); + if (ret == NULL) { + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); + } + return(rb_tainted_str_new2(ret)); + } +#endif +} + +static VALUE +ip_set_variable2(self, varname_arg, index_arg, value_arg, flag_arg) + VALUE self; + VALUE varname_arg; + VALUE index_arg; + VALUE value_arg; + VALUE flag_arg; +{ + struct tcltkip *ptr = get_ip(self); + int thr_crit_bup; + volatile VALUE varname, index, value, flag; + + if (NIL_P(index_arg)) { + return ip_set_variable(self, varname_arg, value_arg, flag_arg); + } + + varname = varname_arg; + index = index_arg; + value = value_arg; + flag = flag_arg; + + StringValue(varname); + StringValue(index); + StringValue(value); + +#if TCL_MAJOR_VERSION >= 8 + { + Tcl_Obj *nameobj, *idxobj, *valobj, *ret; + char *s; + int len; + volatile VALUE strval; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + nameobj = Tcl_NewStringObj(RSTRING(varname)->ptr, + RSTRING(varname)->len); + Tcl_IncrRefCount(nameobj); + + idxobj = Tcl_NewStringObj(RSTRING(index)->ptr, + RSTRING(index)->len); + Tcl_IncrRefCount(idxobj); + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + valobj = Tcl_NewStringObj(RSTRING(value)->ptr, + RSTRING(value)->len); +# else /* TCL_VERSION >= 8.1 */ + { + VALUE enc = rb_ivar_get(value, ID_at_enc); + + if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) { + /* binary string */ + valobj = Tcl_NewByteArrayObj(RSTRING(value)->ptr, + RSTRING(value)->len); + } else if (strlen(RSTRING(value)->ptr) != RSTRING(value)->len) { + /* probably binary string */ + valobj = Tcl_NewByteArrayObj(RSTRING(value)->ptr, + RSTRING(value)->len); + } else { + /* probably text string */ + valobj = Tcl_NewStringObj(RSTRING(value)->ptr, + RSTRING(value)->len); + } + } + +# endif + Tcl_IncrRefCount(valobj); + + ret = Tcl_ObjSetVar2(ptr->ip, nameobj, idxobj, valobj, FIX2INT(flag)); + + Tcl_DecrRefCount(nameobj); + Tcl_DecrRefCount(idxobj); + Tcl_DecrRefCount(valobj); + + rb_thread_critical = thr_crit_bup; + + if (ret == (Tcl_Obj*)NULL) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif + } + + Tcl_IncrRefCount(ret); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + s = Tcl_GetStringFromObj(ret, &len); + strval = rb_tainted_str_new(s, len); +# else /* TCL_VERSION >= 8.1 */ + if (Tcl_GetCharLength(ret) != Tcl_UniCharLen(Tcl_GetUnicode(ret))) { + /* possibly binary string */ + s = Tcl_GetByteArrayFromObj(ret, &len); + 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(ret, &len); + strval = rb_tainted_str_new(s, len); + } +# endif + + rb_thread_critical = thr_crit_bup; + + Tcl_DecrRefCount(ret); + + return(strval); + } +#else /* TCL_MAJOR_VERSION < 8 */ + { + CONST char *ret; + + ret = Tcl_SetVar2(ptr->ip, RSTRING(varname)->ptr, RSTRING(index)->ptr, + RSTRING(value)->ptr, FIX2INT(flag)); + if (ret == (char*)NULL) { + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); + } + return(rb_tainted_str_new2(ret)); + } +#endif +} + +static VALUE +ip_unset_variable(self, varname_arg, flag_arg) + VALUE self; + VALUE varname_arg; + VALUE flag_arg; +{ + struct tcltkip *ptr = get_ip(self); + volatile VALUE varname, value, flag; + + varname = varname_arg; + flag = flag_arg; + + StringValue(varname); + ptr->return_value = Tcl_UnsetVar(ptr->ip, RSTRING(varname)->ptr, + FIX2INT(flag)); + if (ptr->return_value == TCL_ERROR) { + if (FIX2INT(flag) & TCL_LEAVE_ERR_MSG) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif + } + return Qfalse; + } + return Qtrue; +} + +static VALUE +ip_unset_variable2(self, varname_arg, index_arg, flag_arg) + VALUE self; + VALUE varname_arg; + VALUE index_arg; + VALUE flag_arg; +{ + struct tcltkip *ptr = get_ip(self); + volatile VALUE varname, index, value, flag; + + if (NIL_P(index_arg)) { + return ip_unset_variable(self, varname_arg, flag_arg); + } + + varname = varname_arg; + index = index_arg; + flag = flag_arg; + + StringValue(varname); + StringValue(index); + + ptr->return_value = Tcl_UnsetVar2(ptr->ip, RSTRING(varname)->ptr, + RSTRING(index)->ptr, FIX2INT(flag)); + if (ptr->return_value == TCL_ERROR) { + if (FIX2INT(flag) & TCL_LEAVE_ERR_MSG) { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); +#endif + } + return Qfalse; + } + return Qtrue; +} + +static VALUE +ip_get_global_var(self, varname) + VALUE self; + VALUE varname; +{ + return ip_get_variable(self, varname, + INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); +} + +static VALUE +ip_get_global_var2(self, varname, index) + VALUE self; + VALUE varname; + VALUE index; +{ + return ip_get_variable2(self, varname, index, + INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); +} + +static VALUE +ip_set_global_var(self, varname, value) + VALUE self; + VALUE varname; + VALUE value; +{ + return ip_set_variable(self, varname, value, + INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); +} + +static VALUE +ip_set_global_var2(self, varname, index, value) + VALUE self; + VALUE varname; + VALUE index; + VALUE value; +{ + return ip_set_variable2(self, varname, index, value, + INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); +} + +static VALUE +ip_unset_global_var(self, varname) + VALUE self; + VALUE varname; +{ + return ip_unset_variable(self, varname, + INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); +} + +static VALUE +ip_unset_global_var2(self, varname, index) + VALUE self; + VALUE varname; + VALUE index; +{ + return ip_unset_variable2(self, varname, index, + INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)); +} + + +/* treat Tcl_List */ +static VALUE +lib_split_tklist_core(ip_obj, list_str) + VALUE ip_obj; + VALUE list_str; +{ + Tcl_Interp *interp; + volatile VALUE ary, elem; + int idx; + int taint_flag = OBJ_TAINTED(list_str); + int result; + VALUE old_gc; + + if (NIL_P(ip_obj)) { + interp = (Tcl_Interp *)NULL; + } else { + interp = get_ip(ip_obj)->ip; + } + + StringValue(list_str); + + { +#if TCL_MAJOR_VERSION >= 8 + /* object style interface */ + Tcl_Obj *listobj; + int objc; + Tcl_Obj **objv; + int thr_crit_bup; + +# if 1 +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + listobj = Tcl_NewStringObj(RSTRING(list_str)->ptr, + RSTRING(list_str)->len); +# else /* TCL_VERSION >= 8.1 */ + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + { + VALUE enc = rb_ivar_get(list_str, ID_at_enc); + + if (!NIL_P(enc) && strcmp(StringValuePtr(enc), "binary") == 0) { + /* binary string */ + listobj = Tcl_NewByteArrayObj(RSTRING(list_str)->ptr, + RSTRING(list_str)->len); + } else if (strlen(RSTRING(list_str)->ptr) + != RSTRING(list_str)->len) { + /* probably binary string */ + listobj = Tcl_NewByteArrayObj(RSTRING(list_str)->ptr, + RSTRING(list_str)->len); + } else { + /* probably text string */ + listobj = Tcl_NewStringObj(RSTRING(list_str)->ptr, + RSTRING(list_str)->len); + } + } + + rb_thread_critical = thr_crit_bup; +# endif +# else + listobj = Tcl_NewStringObj(RSTRING(list_str)->ptr, + RSTRING(list_str)->len); +# endif + + Tcl_IncrRefCount(listobj); + + result = Tcl_ListObjGetElements(interp, listobj, &objc, &objv); + + if (result == TCL_ERROR) { + Tcl_DecrRefCount(listobj); + if (interp == (Tcl_Interp*)NULL) { + rb_raise(rb_eRuntimeError, "cannot get elements from list"); + } else { +#if TCL_MAJOR_VERSION >= 8 + rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(interp)); +#else /* TCL_MAJOR_VERSION < 8 */ + rb_raise(rb_eRuntimeError, "%s", interp->result); +#endif + } + } + + for(idx = 0; idx < objc; idx++) { + Tcl_IncrRefCount(objv[idx]); + } + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + ary = rb_ary_new2(objc); + if (taint_flag) OBJ_TAINT(ary); + + old_gc = rb_gc_disable(); + + for(idx = 0; idx < objc; idx++) { + char *str; + int len; + +# if 1 +# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 + str = Tcl_GetStringFromObj(objv[idx], &len); + elem = rb_str_new(str, len); +# else /* TCL_VERSION >= 8.1 */ + if (Tcl_GetCharLength(objv[idx]) + != Tcl_UniCharLen(Tcl_GetUnicode(objv[idx]))) { + /* possibly binary string */ + str = Tcl_GetByteArrayFromObj(objv[idx], &len); + elem = rb_str_new(str, len); + rb_ivar_set(elem, ID_at_enc, rb_tainted_str_new2("binary")); + } else { + /* possibly text string */ + str = Tcl_GetStringFromObj(objv[idx], &len); + elem = rb_str_new(str, len); + } +# endif +# else + str = Tcl_GetStringFromObj(objv[idx], &len); + elem = rb_str_new(str, len); +# endif + + if (taint_flag) OBJ_TAINT(elem); + RARRAY(ary)->ptr[idx] = elem; + } + + RARRAY(ary)->len = objc; + + if (old_gc == Qfalse) rb_gc_enable(); + + rb_thread_critical = thr_crit_bup; + + for(idx = 0; idx < objc; idx++) { + Tcl_DecrRefCount(objv[idx]); + } + + Tcl_DecrRefCount(listobj); + +#else /* TCL_MAJOR_VERSION < 8 */ + /* string style interface */ + int argc; + char **argv; + + if (Tcl_SplitList(interp, RSTRING(list_str)->ptr, + &argc, &argv) == TCL_ERROR) { + if (interp == (Tcl_Interp*)NULL) { + rb_raise(rb_eRuntimeError, "cannot get elements from list"); + } else { + rb_raise(rb_eRuntimeError, "%s", interp->result); + } + } + + ary = rb_ary_new2(argc); + if (taint_flag) OBJ_TAINT(ary); + + old_gc = rb_gc_disable(); + + for(idx = 0; idx < argc; idx++) { + if (taint_flag) { + elem = rb_tainted_str_new2(argv[idx]); + } else { + elem = rb_str_new2(argv[idx]); + } + /* rb_ivar_set(elem, ID_at_enc, rb_str_new2("binary")); */ + RARRAY(ary)->ptr[idx] = elem; + } + RARRAY(ary)->len = argc; + + if (old_gc == Qfalse) rb_gc_enable(); +#endif + } + + return ary; +} + +static VALUE +lib_split_tklist(self, list_str) + VALUE self; + VALUE list_str; +{ + return lib_split_tklist_core(Qnil, list_str); +} + + +static VALUE +ip_split_tklist(self, list_str) + VALUE self; + VALUE list_str; +{ + return lib_split_tklist_core(self, list_str); +} + +static VALUE +lib_merge_tklist(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ + int num, len; + int *flagPtr; + char *dst, *result; + volatile VALUE str; + int taint_flag = 0; + int thr_crit_bup; + VALUE old_gc; + + if (argc == 0) return rb_str_new2(""); + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + old_gc = rb_gc_disable(); + + /* based on Tcl/Tk's Tcl_Merge() */ + flagPtr = ALLOC_N(unsigned, argc); + + /* pass 1 */ + len = 1; + for(num = 0; num < argc; num++) { + if (OBJ_TAINTED(argv[num])) taint_flag = 1; + dst = StringValuePtr(argv[num]); +#if TCL_MAJOR_VERSION >= 8 + len += Tcl_ScanCountedElement(dst, RSTRING(argv[num])->len, + &flagPtr[num]) + 1; +#else /* TCL_MAJOR_VERSION < 8 */ + len += Tcl_ScanElement(dst, &flagPtr[num]) + 1; +#endif + } + + /* pass 2 */ + result = (char *)Tcl_Alloc(len); + dst = result; + for(num = 0; num < argc; num++) { +#if TCL_MAJOR_VERSION >= 8 + len = Tcl_ConvertCountedElement(RSTRING(argv[num])->ptr, + RSTRING(argv[num])->len, + dst, flagPtr[num]); +#else /* TCL_MAJOR_VERSION < 8 */ + len = Tcl_ConvertElement(RSTRING(argv[num])->ptr, dst, flagPtr[num]); +#endif + dst += len; + *dst = ' '; + dst++; + } + if (dst == result) { + *dst = 0; + } else { + dst[-1] = 0; + } + + free(flagPtr); + + /* create object */ + str = rb_str_new(result, dst - result - 1); + if (taint_flag) OBJ_TAINT(str); + Tcl_Free(result); + + if (old_gc == Qfalse) rb_gc_enable(); + rb_thread_critical = thr_crit_bup; + + return str; +} + +static VALUE +lib_conv_listelement(self, src) + VALUE self; + VALUE src; +{ + int len, scan_flag; + volatile VALUE dst; + int taint_flag = OBJ_TAINTED(src); + int thr_crit_bup; + + thr_crit_bup = rb_thread_critical; + rb_thread_critical = Qtrue; + + StringValue(src); + +#if TCL_MAJOR_VERSION >= 8 + len = Tcl_ScanCountedElement(RSTRING(src)->ptr, RSTRING(src)->len, + &scan_flag); + dst = rb_str_new(0, len + 1); + len = Tcl_ConvertCountedElement(RSTRING(src)->ptr, RSTRING(src)->len, + RSTRING(dst)->ptr, scan_flag); +#else /* TCL_MAJOR_VERSION < 8 */ + len = Tcl_ScanElement(RSTRING(src)->ptr, &scan_flag); + dst = rb_str_new(0, len + 1); + len = Tcl_ConvertElement(RSTRING(src)->ptr, RSTRING(dst)->ptr, scan_flag); +#endif + + RSTRING(dst)->len = len; + RSTRING(dst)->ptr[len] = '\0'; + if (taint_flag) OBJ_TAINT(dst); + + rb_thread_critical = thr_crit_bup; + + return dst; +} + + #ifdef __MACOS__ static void _macinit() @@ -2313,18 +5090,40 @@ _macinit() void Init_tcltklib() { + int thr_crit_bup; + VALUE lib = rb_define_module("TclTkLib"); VALUE ip = rb_define_class("TclTkIp", rb_cObject); VALUE ev_flag = rb_define_module_under(lib, "EventFlag"); + VALUE var_flag = rb_define_module_under(lib, "VarAccessFlag"); + + /* --------------------------------------------------------------- */ #if defined USE_TCL_STUBS && defined USE_TK_STUBS extern int ruby_tcltk_stubs(); int ret = ruby_tcltk_stubs(); + if (ret) rb_raise(rb_eLoadError, "tcltklib: tcltk_stubs init error(%d)", ret); #endif + /* --------------------------------------------------------------- */ + + rb_global_variable(&eTkCallbackReturn); + rb_global_variable(&eTkCallbackBreak); + rb_global_variable(&eTkCallbackContinue); + + rb_global_variable(&eventloop_thread); + rb_global_variable(&watchdog_thread); + + /* --------------------------------------------------------------- */ + + rb_define_const(lib, "FINALIZE_PROC_NAME", + rb_str_new2(finalize_hook_name)); + + /* --------------------------------------------------------------- */ + rb_define_const(ev_flag, "NONE", INT2FIX(0)); rb_define_const(ev_flag, "WINDOW", INT2FIX(TCL_WINDOW_EVENTS)); rb_define_const(ev_flag, "FILE", INT2FIX(TCL_FILE_EVENTS)); @@ -2333,10 +5132,56 @@ Init_tcltklib() rb_define_const(ev_flag, "ALL", INT2FIX(TCL_ALL_EVENTS)); rb_define_const(ev_flag, "DONT_WAIT", INT2FIX(TCL_DONT_WAIT)); + /* --------------------------------------------------------------- */ + + rb_define_const(var_flag, "NONE", INT2FIX(0)); + rb_define_const(var_flag, "GLOBAL_ONLY", INT2FIX(TCL_GLOBAL_ONLY)); +#ifdef TCL_NAMESPACE_ONLY + rb_define_const(var_flag, "NAMESPACE_ONLY", INT2FIX(TCL_NAMESPACE_ONLY)); +#else /* probably Tcl7.6 */ + rb_define_const(var_flag, "NAMESPACE_ONLY", INT2FIX(0)); +#endif + rb_define_const(var_flag, "LEAVE_ERR_MSG", INT2FIX(TCL_LEAVE_ERR_MSG)); + rb_define_const(var_flag, "APPEND_VALUE", INT2FIX(TCL_APPEND_VALUE)); + rb_define_const(var_flag, "LIST_ELEMENT", INT2FIX(TCL_LIST_ELEMENT)); +#ifdef TCL_PARSE_PART1 + rb_define_const(var_flag, "PARSE_VARNAME", INT2FIX(TCL_PARSE_PART1)); +#else /* probably Tcl7.6 */ + rb_define_const(var_flag, "PARSE_VARNAME", INT2FIX(0)); +#endif + + /* --------------------------------------------------------------- */ + + eTkCallbackBreak = rb_define_class("TkCallbackReturn", rb_eStandardError); eTkCallbackBreak = rb_define_class("TkCallbackBreak", rb_eStandardError); eTkCallbackContinue = rb_define_class("TkCallbackContinue", rb_eStandardError); + /* --------------------------------------------------------------- */ + + eLocalJumpError = rb_const_get(rb_cObject, rb_intern("LocalJumpError")); + + ID_at_enc = rb_intern("@encoding"); + ID_at_interp = rb_intern("@interp"); + + ID_stop_p = rb_intern("stop?"); + ID_kill = rb_intern("kill"); + ID_join = rb_intern("join"); + + ID_call = rb_intern("call"); + ID_backtrace = rb_intern("backtrace"); + ID_message = rb_intern("message"); + + ID_at_reason = rb_intern("@reason"); + ID_return = rb_intern("return"); + ID_break = rb_intern("break"); + ID_next = rb_intern("next"); + + ID_to_s = rb_intern("to_s"); + ID_inspect = rb_intern("inspect"); + + /* --------------------------------------------------------------- */ + rb_define_module_function(lib, "mainloop", lib_mainloop, -1); rb_define_module_function(lib, "mainloop_watchdog", lib_mainloop_watchdog, -1); @@ -2351,11 +5196,27 @@ Init_tcltklib() rb_define_module_function(lib, "get_no_event_wait", get_no_event_wait, 0); rb_define_module_function(lib, "set_eventloop_weight", set_eventloop_weight, 2); + rb_define_module_function(lib, "set_max_block_time", set_max_block_time,1); rb_define_module_function(lib, "get_eventloop_weight", get_eventloop_weight, 0); rb_define_module_function(lib, "num_of_mainwindows", lib_num_of_mainwindows, 0); + /* --------------------------------------------------------------- */ + + rb_define_module_function(lib, "_split_tklist", lib_split_tklist, 1); + rb_define_module_function(lib, "_merge_tklist", lib_merge_tklist, -1); + rb_define_module_function(lib, "_conv_listelement", + lib_conv_listelement, 1); + rb_define_module_function(lib, "_toUTF8", lib_toUTF8, -1); + rb_define_module_function(lib, "_fromUTF8", lib_fromUTF8, -1); + rb_define_module_function(lib, "_subst_UTF_backslash", + lib_UTF_backslash, 1); + rb_define_module_function(lib, "_subst_Tcl_backslash", + lib_Tcl_backslash, 1); + + /* --------------------------------------------------------------- */ + rb_define_alloc_func(ip, ip_alloc); rb_define_method(ip, "initialize", ip_init, -1); rb_define_method(ip, "create_slave", ip_create_slave, -1); @@ -2364,13 +5225,36 @@ Init_tcltklib() rb_define_method(ip, "delete", ip_delete, 0); rb_define_method(ip, "deleted?", ip_is_deleted_p, 0); rb_define_method(ip, "_eval", ip_eval, 1); - rb_define_method(ip, "_toUTF8",ip_toUTF8, 2); - rb_define_method(ip, "_fromUTF8",ip_fromUTF8, 2); + rb_define_method(ip, "_toUTF8", ip_toUTF8, -1); + rb_define_method(ip, "_fromUTF8", ip_fromUTF8, -1); rb_define_method(ip, "_thread_vwait", ip_thread_vwait, 1); rb_define_method(ip, "_thread_tkwait", ip_thread_tkwait, 2); rb_define_method(ip, "_invoke", ip_invoke, -1); rb_define_method(ip, "_return_value", ip_retval, 0); + /* --------------------------------------------------------------- */ + + rb_define_method(ip, "_get_variable", ip_get_variable, 2); + rb_define_method(ip, "_get_variable2", ip_get_variable2, 3); + rb_define_method(ip, "_set_variable", ip_set_variable, 3); + rb_define_method(ip, "_set_variable2", ip_set_variable2, 4); + rb_define_method(ip, "_unset_variable", ip_unset_variable, 2); + rb_define_method(ip, "_unset_variable2", ip_unset_variable2, 3); + rb_define_method(ip, "_get_global_var", ip_get_global_var, 1); + rb_define_method(ip, "_get_global_var2", ip_get_global_var2, 2); + rb_define_method(ip, "_set_global_var", ip_set_global_var, 2); + rb_define_method(ip, "_set_global_var2", ip_set_global_var2, 3); + rb_define_method(ip, "_unset_global_var", ip_unset_global_var, 1); + rb_define_method(ip, "_unset_global_var2", ip_unset_global_var2, 2); + + /* --------------------------------------------------------------- */ + + rb_define_method(ip, "_split_tklist", ip_split_tklist, 1); + rb_define_method(ip, "_merge_tklist", lib_merge_tklist, -1); + rb_define_method(ip, "_conv_listelement", lib_conv_listelement, 1); + + /* --------------------------------------------------------------- */ + rb_define_method(ip, "mainloop", ip_mainloop, -1); rb_define_method(ip, "mainloop_watchdog", ip_mainloop_watchdog, -1); rb_define_method(ip, "do_one_event", ip_do_one_event, -1); @@ -2384,19 +5268,25 @@ Init_tcltklib() rb_define_method(ip, "get_no_event_wait", ip_get_no_event_wait, 0); rb_define_method(ip, "set_eventloop_weight", ip_set_eventloop_weight, 2); rb_define_method(ip, "get_eventloop_weight", ip_get_eventloop_weight, 0); + rb_define_method(ip, "set_max_block_time", set_max_block_time, 1); rb_define_method(ip, "restart", ip_restart, 0); + /* --------------------------------------------------------------- */ + eventloop_thread = 0; watchdog_thread = 0; + /* --------------------------------------------------------------- */ + #ifdef __MACOS__ _macinit(); #endif - /*---- initialize tcl/tk libraries ----*/ /* from Tk_Main() */ DUMP1("Tcl_FindExecutable"); Tcl_FindExecutable(RSTRING(rb_argv0)->ptr); + + /* --------------------------------------------------------------- */ } /* eof */ diff --git a/ext/tk/MANIFEST b/ext/tk/MANIFEST index 503adaabb7..32d8029de1 100644 --- a/ext/tk/MANIFEST +++ b/ext/tk/MANIFEST @@ -1,5 +1,6 @@ MANIFEST README.1st +README.fork extconf.rb depend tkutil.c @@ -22,6 +23,77 @@ lib/tkscrollbox.rb lib/tktext.rb lib/tkvirtevent.rb lib/tkwinpkg.rb +lib/tk/after.rb +lib/tk/autoload.rb +lib/tk/bgerror.rb +lib/tk/bindtag.rb +lib/tk/button.rb +lib/tk/canvas.rb +lib/tk/canvastag.rb +lib/tk/checkbutton.rb +lib/tk/clipboard.rb +lib/tk/clock.rb +lib/tk/composite.rb +lib/tk/console.rb +lib/tk/dialog.rb +lib/tk/encodedstr.rb +lib/tk/entry.rb +lib/tk/event.rb +lib/tk/font.rb +lib/tk/frame.rb +lib/tk/grid.rb +lib/tk/image.rb +lib/tk/itemfont.rb +lib/tk/kinput.rb +lib/tk/label.rb +lib/tk/labelframe.rb +lib/tk/listbox.rb +lib/tk/macpkg.rb +lib/tk/menu.rb +lib/tk/menubar.rb +lib/tk/message.rb +lib/tk/mngfocus.rb +lib/tk/msgcat.rb +lib/tk/namespace.rb +lib/tk/optiondb.rb +lib/tk/pack.rb +lib/tk/package.rb +lib/tk/palette.rb +lib/tk/panedwindow.rb +lib/tk/place.rb +lib/tk/radiobutton.rb +lib/tk/root.rb +lib/tk/scale.rb +lib/tk/scrollable.rb +lib/tk/scrollbar.rb +lib/tk/scrollbox.rb +lib/tk/selection.rb +lib/tk/spinbox.rb +lib/tk/tagfont.rb +lib/tk/text.rb +lib/tk/textimage.rb +lib/tk/textmark.rb +lib/tk/texttag.rb +lib/tk/textwindow.rb +lib/tk/timer.rb +lib/tk/toplevel.rb +lib/tk/txtwin_abst.rb +lib/tk/validation.rb +lib/tk/variable.rb +lib/tk/virtevent.rb +lib/tk/winfo.rb +lib/tk/winpkg.rb +lib/tk/wm.rb +lib/tk/xim.rb +sample/binding_sample.rb +sample/bindtag_sample.rb +sample/binstr_usage.rb +sample/btn_with_frame.rb +sample/encstr_usage.rb +sample/iso2022-kr.txt +sample/propagate.rb +sample/resource.en +sample/resource.ja sample/safe-tk.rb sample/tkalignbox.rb sample/tkballoonhelp.rb @@ -33,20 +105,22 @@ sample/tkfrom.rb sample/tkhello.rb sample/tkline.rb sample/tkmenubutton.rb +sample/tkmsgcat-load_rb.rb +sample/tkmsgcat-load_rb2.rb +sample/tkmsgcat-load_tk.rb sample/tkmulticolumnlist.rb sample/tkmultilistbox.rb sample/tkmultilistframe.rb sample/tkoptdb-safeTk.rb sample/tkoptdb.rb sample/tktextframe.rb -sample/resource.ja -sample/resource.en sample/tktimer.rb sample/tktimer2.rb sample/tktimer3.rb sample/demos-en/ChangeLog sample/demos-en/ChangeLog.prev sample/demos-en/README +sample/demos-en/README.1st sample/demos-en/README.tkencoding sample/demos-en/arrow.rb sample/demos-en/bind.rb @@ -55,6 +129,7 @@ sample/demos-en/browse1 sample/demos-en/browse2 sample/demos-en/button.rb sample/demos-en/check.rb +sample/demos-en/check2.rb sample/demos-en/clrpick.rb sample/demos-en/colors.rb sample/demos-en/cscroll.rb @@ -71,6 +146,7 @@ sample/demos-en/entry2.rb sample/demos-en/entry3.rb sample/demos-en/filebox.rb sample/demos-en/floor.rb +sample/demos-en/floor2.rb sample/demos-en/form.rb sample/demos-en/hello sample/demos-en/hscale.rb @@ -78,19 +154,6 @@ sample/demos-en/icon.rb sample/demos-en/image1.rb sample/demos-en/image2.rb sample/demos-en/image3.rb -sample/demos-en/images/earth.gif -sample/demos-en/images/earthris.gif -sample/demos-en/images/face.xbm -sample/demos-en/images/flagdown.xbm -sample/demos-en/images/flagup.xbm -sample/demos-en/images/gray25.xbm -sample/demos-en/images/grey.25 -sample/demos-en/images/grey.5 -sample/demos-en/images/letters.xbm -sample/demos-en/images/noletter.xbm -sample/demos-en/images/pattern.xbm -sample/demos-en/images/tcllogo.gif -sample/demos-en/images/teapot.ppm sample/demos-en/items.rb sample/demos-en/ixset sample/demos-en/ixset2 @@ -107,6 +170,7 @@ sample/demos-en/plot.rb sample/demos-en/puzzle.rb sample/demos-en/radio.rb sample/demos-en/radio2.rb +sample/demos-en/radio3.rb sample/demos-en/rmt sample/demos-en/rolodex sample/demos-en/rolodex-j @@ -123,6 +187,7 @@ sample/demos-en/text.rb sample/demos-en/timer sample/demos-en/tkencoding.rb sample/demos-en/twind.rb +sample/demos-en/twind2.rb sample/demos-en/unicodeout.rb sample/demos-en/vscale.rb sample/demos-en/widget @@ -134,6 +199,7 @@ sample/demos-jp/browse1 sample/demos-jp/browse2 sample/demos-jp/button.rb sample/demos-jp/check.rb +sample/demos-jp/check2.rb sample/demos-jp/clrpick.rb sample/demos-jp/colors.rb sample/demos-jp/cscroll.rb @@ -150,6 +216,7 @@ sample/demos-jp/entry2.rb sample/demos-jp/entry3.rb sample/demos-jp/filebox.rb sample/demos-jp/floor.rb +sample/demos-jp/floor2.rb sample/demos-jp/form.rb sample/demos-jp/hello sample/demos-jp/hscale.rb @@ -157,19 +224,6 @@ sample/demos-jp/icon.rb sample/demos-jp/image1.rb sample/demos-jp/image2.rb sample/demos-jp/image3.rb -sample/demos-jp/images/earth.gif -sample/demos-jp/images/earthris.gif -sample/demos-jp/images/face.bmp -sample/demos-jp/images/flagdown.bmp -sample/demos-jp/images/flagup.bmp -sample/demos-jp/images/gray25.bmp -sample/demos-jp/images/grey.25 -sample/demos-jp/images/grey.5 -sample/demos-jp/images/letters.bmp -sample/demos-jp/images/noletter.bmp -sample/demos-jp/images/pattern.bmp -sample/demos-jp/images/tcllogo.gif -sample/demos-jp/images/teapot.ppm sample/demos-jp/items.rb sample/demos-jp/ixset sample/demos-jp/ixset2 @@ -186,6 +240,7 @@ sample/demos-jp/plot.rb sample/demos-jp/puzzle.rb sample/demos-jp/radio.rb sample/demos-jp/radio2.rb +sample/demos-jp/radio3.rb sample/demos-jp/rmt sample/demos-jp/rolodex sample/demos-jp/rolodex-j @@ -200,6 +255,51 @@ sample/demos-jp/tcolor sample/demos-jp/text.rb sample/demos-jp/timer sample/demos-jp/twind.rb +sample/demos-jp/twind2.rb sample/demos-jp/unicodeout.rb sample/demos-jp/vscale.rb sample/demos-jp/widget +sample/images/earth.gif +sample/images/earthris.gif +sample/images/face.xbm +sample/images/flagdown.xbm +sample/images/flagup.xbm +sample/images/gray25.xbm +sample/images/grey.25 +sample/images/grey.5 +sample/images/letters.xbm +sample/images/noletter.xbm +sample/images/pattern.xbm +sample/images/tcllogo.gif +sample/images/teapot.ppm +sample/msgs_rb/README +sample/msgs_rb/cs.msg +sample/msgs_rb/de.msg +sample/msgs_rb/el.msg +sample/msgs_rb/en.msg +sample/msgs_rb/en_gb.msg +sample/msgs_rb/eo.msg +sample/msgs_rb/es.msg +sample/msgs_rb/fr.msg +sample/msgs_rb/it.msg +sample/msgs_rb/ja.msg +sample/msgs_rb/nl.msg +sample/msgs_rb/pl.msg +sample/msgs_rb/ru.msg +sample/msgs_rb2/README +sample/msgs_rb2/de.msg +sample/msgs_rb2/ja.msg +sample/msgs_tk/README +sample/msgs_tk/cs.msg +sample/msgs_tk/de.msg +sample/msgs_tk/el.msg +sample/msgs_tk/en.msg +sample/msgs_tk/en_gb.msg +sample/msgs_tk/eo.msg +sample/msgs_tk/es.msg +sample/msgs_tk/fr.msg +sample/msgs_tk/it.msg +sample/msgs_tk/ja.msg +sample/msgs_tk/nl.msg +sample/msgs_tk/pl.msg +sample/msgs_tk/ru.msg diff --git a/ext/tk/README.fork b/ext/tk/README.fork new file mode 100644 index 0000000000..cda89b003c --- /dev/null +++ b/ext/tk/README.fork @@ -0,0 +1,29 @@ +Ruby/Tk does NOT support forking the process on which Tk interpreter +is running (unless NEVER control Tk interpreter under the forked child +process). In the library 'tk.rb', a Tk interpreter is initialized. +Therefore, if you want running Tk under a child process, please call +"require 'tk'" in the child process. + +For example, the following sample1 will NOT work, and sample2 will +work properly. + +------------------------------------------ +require 'tk' ## init Tk interpreter under parent process + +exit! if fork ## exit parent process + +## child process +TkButton.new(:text=>'QUIT', :command=>proc{exit}).pack +Tk.mainloop +------------------------------------------------------------- + +----------------------------------------- +exit! if fork ## exit main process + +## child process +require 'tk' ## init Tk interpreter under child process +TkButton.new(:text=>'QUIT', :command=>proc{exit}).pack +Tk.mainloop +------------------------------------------------------------- + + 2004/04/20 Hidetoshi NAGAI diff --git a/ext/tk/extconf.rb b/ext/tk/extconf.rb index f769b06e30..4f87d527ae 100644 --- a/ext/tk/extconf.rb +++ b/ext/tk/extconf.rb @@ -1,2 +1,3 @@ require 'mkmf' +$preload = ["tcltklib"] create_makefile("tkutil") diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index c2dcb4f971..a3cd3857a0 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -3,6 +3,7 @@ # by Hidetoshi NAGAI require 'tcltklib' +require 'tkutil' require 'thread' ################################################ @@ -13,7 +14,6 @@ TclTkLib.mainloop_abort_on_exception = true # TclTkLib.mainloop_abort_on_exception = nil - ################################################ # exceptiopn to treat the return value from IP class MultiTkIp_OK < Exception @@ -48,12 +48,15 @@ class MultiTkIp ###################################### - @@CB_ENTRY_CLASS = Class.new{|c| + @@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){|c| def initialize(ip, cmd) @ip = ip @cmd = cmd end attr_reader :ip, :cmd + def inspect + cmd.inspect + end def call(*args) begin unless @ip.deleted? @@ -68,8 +71,11 @@ class MultiTkIp ###################################### - def _keys2opts(keys) - keys.collect{|k,v| "-#{k} #{v}"}.join(' ') + def _keys2opts(src_keys) + return nil if src_keys == nil + keys = {}; src_keys.each{|k, v| keys[k.to_s] = v} + #keys.collect{|k,v| "-#{k} #{v}"}.join(' ') + keys.collect{|k,v| "-#{k} #{TclTkLib._conv_listelement(TkComm::_get_eval_string(v))}"}.join(' ') end private :_keys2opts @@ -136,10 +142,11 @@ class MultiTkIp rescue SystemExit # delete IP unless @interp.deleted? - if @interp._invoke('info', 'command', '.') != "" - @interp._invoke('destroy', '.') - end - @interp.delete + # if @interp._invoke('info', 'command', '.') != "" + # @interp._invoke('destroy', '.') + # end + # @interp.delete + @interp._eval_without_enc('exit') end _check_and_return(thread, MultiTkIp_OK.new(nil)) break @@ -200,14 +207,14 @@ class MultiTkIp @@DEFAULT_MASTER = self.allocate @@DEFAULT_MASTER.instance_eval{ - @encoding = [].taint - @tk_windows = {}.taint @tk_table_list = [].taint @slave_ip_tbl = {}.taint + @slave_ip_top = {}.taint + unless keys.kind_of? Hash fail ArgumentError, "expecting a Hash object for the 2nd argument" end @@ -274,23 +281,28 @@ class MultiTkIp tk_opts = {} keys.each{|k,v| - if k.to_s == 'name' + k_str = k.to_s + if k_str == 'name' name = v - elsif k.to_s == 'safe' + elsif k_str == 'safe' safe = v - elsif SAFE_OPT_LIST.member?(k.to_s) - safe_opts[k] = v + elsif SAFE_OPT_LIST.member?(k_str) + safe_opts[k_str] = v else - tk_opts[k] = v + tk_opts[k_str] = v end } - [name, safe, safe_opts, tk_opts] + if keys['without_tk'] || keys[:without_tk] + [name, safe, safe_opts, nil] + else + [name, safe, safe_opts, tk_opts] + end end private :_parse_slaveopts def _create_slave_ip_name - name = SLAVE_IP_ID.join + name = SLAVE_IP_ID.join('') SLAVE_IP_ID[1].succ! name end @@ -388,14 +400,18 @@ class MultiTkIp # procedure to delete slave interpreter slave_delete_proc = proc{ unless slave_ip.deleted? - if slave_ip._invoke('info', 'command', '.') != "" - slave_ip._invoke('destroy', '.') - end - slave_ip.delete + #if slave_ip._invoke('info', 'command', '.') != "" + # slave_ip._invoke('destroy', '.') + #end + #slave_ip.delete + slave_ip._eval_without_enc('exit') end + top.destroy if top.winfo_exist? } tag = TkBindTag.new.bind('Destroy', slave_delete_proc) + top.bindtags = top.bindtags.unshift(tag) + # create control frame TkFrame.new(top, :bg=>'red', :borderwidth=>3, :relief=>'ridge') {|fc| fc.bindtags = fc.bindtags.unshift(tag) @@ -421,23 +437,45 @@ class MultiTkIp # return keys loadTk_keys['use'] = TkWinfo.id(c) - loadTk_keys + [loadTk_keys, top.path] end private :__create_safetk_frame def __create_safe_slave_obj(safe_opts, app_name, tk_opts) # safe interpreter - # at present, not enough support for '-deleteHook' option ip_name = _create_slave_ip_name slave_ip = @interp.create_slave(ip_name, true) - @interp._eval("::safe::interpInit #{ip_name} "+_keys2opts(safe_opts)) - tk_opts = __check_safetk_optkeys(tk_opts) - unless tk_opts.key?('use') - tk_opts = __create_safetk_frame(slave_ip, ip_name, app_name, tk_opts) - end - slave_ip._invoke('set', 'argv0', app_name) if app_name.kind_of?(String) - @interp._eval("::safe::loadTk #{ip_name} #{_keys2opts(tk_opts)}") @slave_ip_tbl[ip_name] = slave_ip + + @interp._eval("::safe::interpInit #{ip_name}") + + slave_ip._invoke('set', 'argv0', app_name) if app_name.kind_of?(String) + + if tk_opts + tk_opts = __check_safetk_optkeys(tk_opts) + if tk_opts.key?('use') + @slave_ip_top[ip_name] = '' + else + tk_opts, top_path = __create_safetk_frame(slave_ip, ip_name, app_name, + tk_opts) + @slave_ip_top[ip_name] = top_path + end + @interp._eval("::safe::loadTk #{ip_name} #{_keys2opts(tk_opts)}") + else + @slave_ip_top[ip_name] = nil + end + + if safe_opts.key?('deleteHook') || safe_opts.key?(:deleteHook) + @interp._eval("::safe::interpConfigure #{ip_name} " + + _keys2opts(safe_opts)) + else + @interp._eval("::safe::interpConfigure #{ip_name} " + + _keys2opts(safe_opts) + '-deleteHook {' + + TkComm._get_eval_string(proc{|slave| + self._default_delete_hook(slave) + }) + '}') + end + [slave_ip, ip_name] end @@ -481,15 +519,15 @@ class MultiTkIp fail ArgumentError, "expecting a Hash object for the 2nd argument" end - @encoding = [] @tk_windows = {} @tk_table_list = [] @slave_ip_tbl = {} + @slave_ip_top = {} - @encoding.taint unless @encoding.tainted? @tk_windows.taint unless @tk_windows.tainted? @tk_table_list.taint unless @tk_table_list.tainted? @slave_ip_tbl.taint unless @slave_ip_tbl.tainted? + @slave_ip_top.taint unless @slave_ip_top.tainted? name, safe, safe_opts, tk_opts = _parse_slaveopts(keys) @@ -532,6 +570,34 @@ class MultiTkIp self.freeze # defend against modification end + + ###################################### + + def _default_delete_hook(slave) + if @slave_ip_top[slave].kind_of?(String) + # call default hook of safetk.tcl (ignore exceptions) + if @slave_ip_top[slave] == '' + begin + @interp._eval("::safe::disallowTk #{slave}") + rescue + warn("Waring: fail to call '::safe::disallowTk'") if $DEBUG + end + else # toplevel path + begin + @interp._eval("::safe::tkDelete {} #{@slave_ip_top[slave]} #{slave}") + rescue + warn("Waring: fail to call '::safe::tkDelete'") if $DEBUG + begin + @interp._eval("destroy #{@slave_ip_top[slave]}") + rescue + warn("Waring: fail to destroy toplevel") if $DEBUG + end + end + end + end + @slave_ip_tbl.delete(slave) + @slave_ip_top.delete(slave) + end end @@ -796,6 +862,10 @@ class MultiTkIp rescue SystemExit # exit IP warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG + begin + self._eval_without_enc('exit') + rescue Exception + end self.delete ret = nil rescue Exception => e @@ -823,6 +893,10 @@ class MultiTkIp rescue SystemExit # exit IP warn("Warning: " + $! + " on " + self.inspect) if $DEBUG + begin + self._eval_without_enc('exit') + rescue Exception + end self.delete rescue Exception => e # others --> warning @@ -868,10 +942,12 @@ class << MultiTkIp __getip.do_one_event(flag) end def mainloop_abort_on_exception - __getip.mainloop_abort_on_exception + # __getip.mainloop_abort_on_exception + TclTkLib.mainloop_abort_on_exception end def mainloop_abort_on_exception=(mode) - __getip.mainloop_abort_on_exception=(mode) + # __getip.mainloop_abort_on_exception=(mode) + TclTkLib.mainloop_abort_on_exception=(mode) end def set_eventloop_tick(tick) __getip.set_eventloop_tick(tick) @@ -919,6 +995,22 @@ class << MultiTkIp __getip._invoke(*args) end + def _eval_without_enc(str) + __getip._eval_without_enc(str) + end + + def _invoke_without_enc(*args) + __getip._invoke_without_enc(*args) + end + + def _eval_with_enc(str) + __getip._eval_with_enc(str) + end + + def _invoke_with_enc(*args) + __getip._invoke_with_enc(*args) + end + def _toUTF8(str, encoding) __getip._toUTF8(str, encoding) end @@ -938,6 +1030,54 @@ class << MultiTkIp def _return_value __getip._return_value end + + def _get_variable(var, flag) + __getip._get_variable(var, flag) + end + def _get_variable2(var, idx, flag) + __getip._get_variable2(var, idx, flag) + end + def _set_variable(var, value, flag) + __getip._set_variable(var, value, flag) + end + def _set_variable2(var, idx, value, flag) + __getip._set_variable2(var, idx, value, flag) + end + def _unset_variable(var, flag) + __getip._unset_variable(var, flag) + end + def _unset_variable2(var, idx, flag) + __getip._unset_variable2(var, idx, flag) + end + + def _get_global_var(var) + __getip._get_global_var(var) + end + def _get_global_var2(var, idx) + __getip._get_global_var2(var, idx) + end + def _set_global_var(var, value) + __getip._set_global_var(var, value) + end + def _set_global_var2(var, idx, value) + __getip._set_global_var2(var, idx, value) + end + def _unset_global_var(var) + __getip._unset_global_var(var) + end + def _unset_global_var2(var, idx) + __getip._unset_global_var2(var, idx) + end + + def _split_tklist(str) + __getip._split_tklist(str) + end + def _merge_tklist(*args) + __getip._merge_tklist(*args) + end + def _conv_listelement(arg) + __getip._conv_listelement(arg) + end end @@ -952,12 +1092,12 @@ class << TclTkLib def do_one_event(flag = TclTkLib::EventFlag::ALL) MultiTkIp.do_one_event(flag) end - def mainloop_abort_on_exception - MultiTkIp.mainloop_abort_on_exception - end - def mainloop_abort_on_exception=(mode) - MultiTkIp.mainloop_abort_on_exception=(mode) - end + #def mainloop_abort_on_exception + # MultiTkIp.mainloop_abort_on_exception + #end + #def mainloop_abort_on_exception=(mode) + # MultiTkIp.mainloop_abort_on_exception=(mode) + #end def set_eventloop_tick(tick) MultiTkIp.set_eventloop_tick(tick) end @@ -979,12 +1119,19 @@ class << TclTkLib def restart MultiTkIp.restart end + + def _merge_tklist(*args) + MultiTkIp._merge_tklist(*args) + end + def _conv_listelement(arg) + MultiTkIp._conv_listelement(arg) + end end # depend on TclTkIp class MultiTkIp - def mainloop(check_root = true, restart_on_dead = true) + def mainloop(check_root = true, restart_on_dead = false) return self if self.slave? unless restart_on_dead @interp.mainloop(check_root) @@ -1022,6 +1169,10 @@ class MultiTkIp end def delete + if safe? + # do 'exit' to call the delete_hook procedure + @interp._eval_without_enc('exit') + end @interp.delete end @@ -1041,6 +1192,22 @@ class MultiTkIp @interp._invoke(*args) end + def _eval_without_enc(str) + @interp._eval_without_enc(str) + end + + def _invoke_without_enc(*args) + @interp._invoke_without_enc(*args) + end + + def _eval_with_enc(str) + @interp._eval_with_enc(str) + end + + def _invoke_with_enc(*args) + @interp._invoke_with_enc(*args) + end + def _toUTF8(str, encoding) @interp._toUTF8(str, encoding) end @@ -1060,6 +1227,54 @@ class MultiTkIp def _return_value @interp._return_value end + + def _get_variable(var, flag) + @interp._get_variable(var, flag) + end + def _get_variable2(var, idx, flag) + @interp._get_variable2(var, idx, flag) + end + def _set_variable(var, value, flag) + @interp._set_variable(var, value, flag) + end + def _set_variable2(var, idx, value, flag) + @interp._set_variable2(var, idx, value, flag) + end + def _unset_variable(var, flag) + @interp._unset_variable(var, flag) + end + def _unset_variable2(var, idx, flag) + @interp._unset_variable2(var, idx, flag) + end + + def _get_global_var(var) + @interp._get_global_var(var) + end + def _get_global_var2(var, idx) + @interp._get_global_var2(var, idx) + end + def _set_global_var(var, value) + @interp._set_global_var(var, value) + end + def _set_global_var2(var, idx, value) + @interp._set_global_var2(var, idx, value) + end + def _unset_global_var(var) + @interp._unset_global_var(var) + end + def _unset_global_var2(var, idx) + @interp._unset_global_var2(var, idx) + end + + def _split_tklist(str) + @interp._split_tklist(str) + end + def _merge_tklist(*args) + @interp._merge_tklist(*args) + end + def _conv_listelement(arg) + @interp._conv_listelement(arg) + end end @@ -1090,7 +1305,7 @@ class MultiTkIp else list.push str[0..i-1] end - list += tk_split_simplelist(str[i+1..-1]) + list += _lst2ary(str[i+1..-1]) list end private :_lst2ary @@ -1224,6 +1439,14 @@ class MultiTkIp self end + def recursion_limit(slave = '', limit = None) + number(@interp._invoke('interp', 'recursionlimit', + _slavearg(slave), limit)) + end + def self.recursion_limit(slave = '', limit = None) + __getip.recursion_limit(slave) + end + def alias_target(aliascmd, slave = '') @interp._invoke('interp', 'target', _slavearg(slave), aliascmd) end @@ -1309,35 +1532,94 @@ class MultiTkIp end +# Safe Base :: manipulating safe interpreter +class MultiTkIp + def safeip_configure(slave, slot, value=None) + # use for '-noStatics' option ==> {statics=>false} + # for '-nestedLoadOk' option ==> {nested=>true} + if slot.kind_of?(Hash) + ip = MultiTkIp.__getip + ip._eval('::safe::interpConfigure ' + @ip_name + ' ' + + hash_kv(slot).join(' ')) + else + ip._eval('::safe::interpConfigure ' + @ip_name + ' ' + + "-#{slot} #{_get_eval_string(value)}") + end + self + end + + def safeip_configinfo(slot = nil) + ip = MultiTkIp.__getip + ret = {} + if slot + conf = _lst2ary(ip._eval("::safe::interpConfigure " + + @ip_name + " -#{slot}")) + if conf[0] == '-deleteHook' + if conf[1] =~ /^rb_out (c\d+)/ + ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$1] + else + ret[conf[0][1..-1]] = conf[1] + end + else + ret[conf[0][1..-1]] = conf[1] + end + else + Hash[*_lst2ary(ip._eval("::safe::interpConfigure " + + @ip_name))].each{|k, v| + if k == '-deleteHook' + if v =~ /^rb_out (c\d+)/ + ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$1] + else + ret[k[1..-1]] = v + end + else + ret[k[1..-1]] = v + end + } + end + ret + end + + def safeip_delete(slave) + ip = MultiTkIp.__getip + ip._eval("::safe::interpDelete " + @ip_name) + end + + def safeip_add_to_access_path(slave, dir) + ip = MultiTkIp.__getip + ip._eval("::safe::interpAddToAccessPath #{@ip_name} #{dir}") + end + + def safeip_find_in_access_path(slave, dir) + ip = MultiTkIp.__getip + ip._eval("::safe::interpFindInAccessPath #{@ip_name} #{dir}") + end + + def safeip_set_log_cmd(slave, cmd = Proc.new) + ip = MultiTkIp.__getip + ip._eval("::safe::setLogCmd #{@ip_name} #{_get_eval_string(cmd)}") + end +end + + # encoding convert class MultiTkIp - # from tkencoding.rb by ttate@jaist.ac.jp - alias __eval _eval - alias __invoke _invoke - def encoding - @encoding[0] + @interp.encoding end def encoding=(enc) - @encoding[0] = enc - end - - def _eval(cmd) - if @encoding[0] != nil - _fromUTF8(__eval(_toUTF8(cmd, @encoding[0])), @encoding[0]) - else - __eval(cmd) - end + @interp.encoding = enc end - def _invoke(*cmds) - if defined?(@encoding[0]) && @encoding[0] != nil - cmds = cmds.collect{|cmd| _toUTF8(cmd, @encoding[0])} - _fromUTF8(__invoke(*cmds), @encoding[0]) - else - __invoke(*cmds) - end + def encoding_convertfrom(str, enc=None) + @interp.encoding_convertfrom(str, enc) end + alias encoding_convert_from encoding_convertfrom + + def encoding_convertto(str, enc=None) + @interp.encoding_convertto(str, enc) + end + alias encoding_convert_to encoding_convertto end diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index f098772a28..36a9e54f2e 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -4,17 +4,30 @@ # by Yukihiro Matsumoto # use Shigehiro's tcltklib -require "tcltklib" -require "tkutil" +require 'tcltklib' +require 'tkutil' +# autoload +require 'tk/autoload' + +class TclTkIp + # backup original (without encoding) _eval and _invoke + alias _eval_without_enc _eval + alias _invoke_without_enc _invoke +end + +# define TkComm module (step 1: basic functions) module TkComm + include TkUtil + extend TkUtil + WidgetClassNames = {}.taint - None = Object.new - def None.to_s - 'None' - end - None.freeze + # None = Object.new ### --> definition is moved to TkUtil module + # def None.to_s + # 'None' + # end + # None.freeze #Tk_CMDTBL = {} #Tk_WINDOWS = {} @@ -36,6 +49,21 @@ module TkComm @cmdtbl = [].taint } + unless const_defined?(:GET_CONFIGINFO_AS_ARRAY) + # GET_CONFIGINFO_AS_ARRAY = false => returns a Hash { opt =>val, ... } + # true => returns an Array [[opt,val], ... ] + # val is a list which includes resource info. + GET_CONFIGINFO_AS_ARRAY = true + end + unless const_defined?(:GET_CONFIGINFOwoRES_AS_ARRAY) + # for configinfo without resource info; list of [opt, value] pair + # false => returns a Hash { opt=>val, ... } + # true => returns an Array [[opt,val], ... ] + GET_CONFIGINFOwoRES_AS_ARRAY = true + end + # *** ATTENTION *** + # 'current_configinfo' method always returns a Hash under all cases of above. + def error_at frames = caller() frames.delete_if do |c| @@ -50,7 +78,7 @@ module TkComm begin #tk_class = TkCore::INTERP._invoke('winfo', 'class', path) - tk_class = Tk.ip_invoke('winfo', 'class', path) + tk_class = Tk.ip_invoke_without_enc('winfo', 'class', path) rescue return path end @@ -82,10 +110,16 @@ module TkComm private :_genobj_for_tkwidget module_function :_genobj_for_tkwidget - def tk_tcl2ruby(val) + def tk_tcl2ruby(val, enc_mode = nil) if val =~ /^rb_out (c\d+)/ #return Tk_CMDTBL[$1] return TkCore::INTERP.tk_cmd_tbl[$1] + #cmd_obj = TkCore::INTERP.tk_cmd_tbl[$1] + #if cmd_obj.kind_of?(Proc) || cmd_obj.kind_of?(Method) + # cmd_obj + #else + # cmd_obj.cmd + #end end #if val.include? ?\s # return val.split.collect{|v| tk_tcl2ruby(v)} @@ -110,10 +144,76 @@ module TkComm when /\\ / val.gsub(/\\ /, ' ') else - val + if enc_mode + _fromUTF8(val) + else + val + end end end + private :tk_tcl2ruby + +unless const_defined?(:USE_TCLs_LIST_FUNCTIONS) + USE_TCLs_LIST_FUNCTIONS = true +end + +if USE_TCLs_LIST_FUNCTIONS + ########################################################################### + # use Tcl function version of split_list + ########################################################################### + + def tk_split_escstr(str) + TkCore::INTERP._split_tklist(str) + end + + def tk_split_sublist(str) + return [] if str == "" + list = TkCore::INTERP._split_tklist(str) + if list.size == 1 + tk_tcl2ruby(list[0]) + else + list.collect{|token| tk_split_sublist(token)} + end + end + + def tk_split_list(str) + return [] if str == "" + TkCore::INTERP._split_tklist(str).collect{|token| tk_split_sublist(token)} + end + + def tk_split_simplelist(str) + #lst = TkCore::INTERP._split_tklist(str) + #if (lst.size == 1 && lst =~ /^\{.*\}$/) + # TkCore::INTERP._split_tklist(str[1..-2]) + #else + # lst + #end + TkCore::INTERP._split_tklist(str) + end + + def array2tk_list(ary) + return "" if ary.size == 0 + + dst = ary.collect{|e| + if e.kind_of? Array + array2tk_list(e) + elsif e.kind_of? Hash + tmp_ary = [] + e.each{|k,v| tmp_ary << k << v } + array2tk_list(tmp_ary) + else + _get_eval_string(e) + end + } + TkCore::INTERP._merge_tklist(*dst) + end + +else + ########################################################################### + # use Ruby script version of split_list (traditional methods) + ########################################################################### + def tk_split_escstr(str) return [] if str == "" list = [] @@ -201,7 +301,7 @@ module TkComm if c == '\\' && !escape escape = true token = (token || "") << c if brace > 0 - next + next end brace += 1 if c == '{' && !escape brace -= 1 if c == '}' && !escape @@ -216,62 +316,6 @@ module TkComm list << token.gsub(/^\{(.*)\}$/, '\1') if token list end -=begin - def tk_split_simplelist(str) - return [] if str == "" - idx = str.index('{') - while idx and idx > 0 and str[idx-1] == ?\\ - idx = str.index('{', idx+1) - end - return str.split unless idx - - list = str[0,idx].split - str = str[idx+1..-1] - i = -1 - escape = false - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ && !escape - brace -= 1 if c == ?} && !escape - escape = (c == ?\\) - break if brace == 0 - } - if i == 0 - list.push '' - elsif str[0, i] == ' ' - list.push ' ' - else - #list.push str[0..i-1] - list.push(str[0..i-1].gsub(/\\(\{|\})/, '\1')) - end - list += tk_split_simplelist(str[i+1..-1]) - list - end -=end - - private :tk_tcl2ruby, :tk_split_escstr, - :tk_split_sublist, :tk_split_list, :tk_split_simplelist - - def _symbolkey2str(keys) - h = {} - keys.each{|key,value| h[key.to_s] = value} - h - end - private :_symbolkey2str - - def hash_kv(keys) - conf = [] - if keys and keys != None - for k, v in keys - conf.push("-#{k}") - conf.push(v) - end - end - conf - end - private :hash_kv - module_function :hash_kv def array2tk_list(ary) ary.collect{|e| @@ -285,9 +329,61 @@ module TkComm end }.join(" ") end +end + + private :tk_split_escstr, :tk_split_sublist + private :tk_split_list, :tk_split_simplelist private :array2tk_list + + module_function :tk_split_escstr, :tk_split_sublist + module_function :tk_split_list, :tk_split_simplelist module_function :array2tk_list + private_class_method :tk_split_escstr, :tk_split_sublist + private_class_method :tk_split_list, :tk_split_simplelist + private_class_method :array2tk_list + +=begin + ### --> definition is moved to TkUtil module + def _symbolkey2str(keys) + h = {} + keys.each{|key,value| h[key.to_s] = value} + h + end + private :_symbolkey2str + module_function :_symbolkey2str +=end + +=begin + ### --> definition is moved to TkUtil module + # def hash_kv(keys, enc_mode = nil, conf = [], flat = false) + def hash_kv(keys, enc_mode = nil, conf = nil) + # Hash {key=>val, key=>val, ... } or Array [ [key, val], [key, val], ... ] + # ==> Array ['-key', val, '-key', val, ... ] + dst = [] + if keys and keys != None + keys.each{|k, v| + #dst.push("-#{k}") + dst.push('-' + k.to_s) + if v != None + # v = _get_eval_string(v, enc_mode) if (enc_mode || flat) + v = _get_eval_string(v, enc_mode) if enc_mode + dst.push(v) + end + } + end + if conf + conf + dst + else + dst + end + end + private :hash_kv + module_function :hash_kv +=end + +=begin + ### --> definition is moved to TkUtil module def bool(val) case val when "1", 1, 'yes', 'true' @@ -296,6 +392,7 @@ module TkComm false end end + def number(val) case val when /^-?\d+$/ @@ -303,8 +400,7 @@ module TkComm when /^-?\d+\.?\d*(e[-+]?\d+)?$/ val.to_f else - fail(ArgumentError, - Kernel.format('invalid value for Number:"%s"', val.to_s)) + fail(ArgumentError, "invalid value for Number:'#{val}'") end end def string(val) @@ -316,6 +412,15 @@ module TkComm val end end + def num_or_str(val) + begin + number(val) + rescue ArgumentError + string(val) + end + end +=end + def list(val) tk_split_list(val) end @@ -331,6 +436,13 @@ module TkComm nil end end + def image_obj(val) + if val =~ /^i\d+$/ + TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val + else + val + end + end def procedure(val) if val =~ /^rb_out (c\d+)/ #Tk_CMDTBL[$1] @@ -342,19 +454,34 @@ module TkComm end end private :bool, :number, :string, :list, :simplelist, :window, :procedure - module_function :bool, :number, :string, :list, :simplelist - module_function :window, :procedure + module_function :bool, :number, :num_or_str, :string, :list, :simplelist + module_function :window, :image_obj, :procedure - def _get_eval_string(str) + def _toUTF8(str, encoding = nil) + TkCore::INTERP._toUTF8(str, encoding) + end + def _fromUTF8(str, encoding = nil) + TkCore::INTERP._fromUTF8(str, encoding) + end + private :_toUTF8, :_fromUTF8 + module_function :_toUTF8, :_fromUTF8 + +=begin + ### --> definition is moved to TkUtil module + def _get_eval_string(str, enc_mode = nil) return nil if str == None - if str.kind_of?(String) - # do nothing + if str.kind_of?(TkObject) + str = str.path + elsif str.kind_of?(String) + str = _toUTF8(str) if enc_mode elsif str.kind_of?(Symbol) str = str.id2name + str = _toUTF8(str) if enc_mode elsif str.kind_of?(Hash) - str = hash_kv(str).join(" ") + str = hash_kv(str, enc_mode).join(" ") elsif str.kind_of?(Array) str = array2tk_list(str) + str = _toUTF8(str) if enc_mode elsif str.kind_of?(Proc) str = install_cmd(str) elsif str == nil @@ -365,28 +492,102 @@ module TkComm str = "1" elsif (str.respond_to?(:to_eval)) str = str.to_eval() + str = _toUTF8(str) if enc_mode else str = str.to_s() || '' unless str.kind_of? String fail RuntimeError, "fail to convert the object to a string" end - str + str = _toUTF8(str) if enc_mode end return str end +=end +=begin + def _get_eval_string(obj, enc_mode = nil) + case obj + when Numeric + obj.to_s + when String + (enc_mode)? _toUTF8(obj): obj + when Symbol + (enc_mode)? _toUTF8(obj.id2name): obj.id2name + when TkObject + obj.path + when Hash + hash_kv(obj, enc_mode).join(' ') + when Array + (enc_mode)? _toUTF8(array2tk_list(obj)): array2tk_list(obj) + when Proc, Method, TkCallbackEntry + install_cmd(obj) + when false + '0' + when true + '1' + when nil + '' + when None + nil + else + if (obj.respond_to?(:to_eval)) + (enc_mode)? _toUTF8(obj.to_eval): obj.to_eval + else + begin + obj = obj.to_s || '' + rescue + fail RuntimeError, "fail to convert object '#{obj}' to string" + end + (enc_mode)? _toUTF8(obj): obj + end + end + end private :_get_eval_string module_function :_get_eval_string +=end - def ruby2tcl(v) +=begin + ### --> definition is moved to TkUtil module + def _get_eval_enc_str(obj) + return obj if obj == None + _get_eval_string(obj, true) + end + private :_get_eval_enc_str + module_function :_get_eval_enc_str +=end + +=begin + ### --> obsolete + def ruby2tcl(v, enc_mode = nil) if v.kind_of?(Hash) v = hash_kv(v) v.flatten! - v.collect{|e|ruby2tcl(e)} + v.collect{|e|ruby2tcl(e, enc_mode)} else - _get_eval_string(v) + _get_eval_string(v, enc_mode) end end private :ruby2tcl +=end + +=begin + ### --> definition is moved to TkUtil module + def _conv_args(args, enc_mode, *src_args) + conv_args = [] + src_args.each{|arg| + conv_args << _get_eval_string(arg, enc_mode) unless arg == None + # if arg.kind_of?(Hash) + # arg.each{|k, v| + # args << '-' + k.to_s + # args << _get_eval_string(v, enc_mode) + # } + # elsif arg != None + # args << _get_eval_string(arg, enc_mode) + # end + } + args + conv_args + end + private :_conv_args +=end def _curr_cmd_id #id = format("c%.4d", Tk_IDs[0]) @@ -405,20 +606,26 @@ module TkComm return '' if cmd == '' id = _next_cmd_id #Tk_CMDTBL[id] = cmd - TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd) + if cmd.kind_of?(TkCallbackEntry) + TkCore::INTERP.tk_cmd_tbl[id] = cmd + else + TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd) + end @cmdtbl = [] unless defined? @cmdtbl @cmdtbl.taint unless @cmdtbl.tainted? @cmdtbl.push id - return Kernel.format("rb_out %s", id); + #return Kernel.format("rb_out %s", id); + return 'rb_out ' + id end def uninstall_cmd(id) id = $1 if /rb_out (c\d+)/ =~ id #Tk_CMDTBL.delete(id) TkCore::INTERP.tk_cmd_tbl.delete(id) end - private :install_cmd, :uninstall_cmd - module_function :install_cmd + # private :install_cmd, :uninstall_cmd + module_function :install_cmd, :uninstall_cmd +=begin def install_win(ppath,name=nil) if !name or name == '' #name = format("w%.4d", Tk_IDs[1]) @@ -436,6 +643,29 @@ module TkComm #Tk_WINDOWS[@path] = self TkCore::INTERP.tk_windows[@path] = self end +=end + def install_win(ppath,name=nil) + if name + if name == '' + raise ArgumentError, "invalid wiget-name '#{name}'" + end + if name[0] == ?. + @path = '' + name + @path.freeze + return TkCore::INTERP.tk_windows[@path] = self + end + else + name = "w" + Tk_IDs[1] + Tk_IDs[1].succ! + end + if !ppath or ppath == '.' + @path = '.' + name + else + @path = ppath + '.' + name + end + @path.freeze + TkCore::INTERP.tk_windows[@path] = self + end def uninstall_win() #Tk_WINDOWS.delete(@path) @@ -443,163 +673,22 @@ module TkComm end private :install_win, :uninstall_win - class Event - module TypeNum - KeyPress = 2 - KeyRelease = 3 - ButtonPress = 4 - ButtonRelease = 5 - MotionNotify = 6 - EnterNotify = 7 - LeaveNotify = 8 - FocusIn = 9 - FocusOut = 10 - KeymapNotify = 11 - Expose = 12 - GraphicsExpose = 13 - NoExpose = 14 - VisibilityNotify = 15 - CreateNotify = 16 - DestroyNotify = 17 - UnmapNotify = 18 - MapNotify = 19 - MapRequest = 20 - ReparentNotify = 21 - ConfigureNotify = 22 - ConfigureRequest = 23 - GravityNotify = 24 - ResizeRequest = 25 - CirculateNotify = 26 - CirculateRequest = 27 - PropertyNotify = 28 - SelectionClear = 29 - SelectionRequest = 30 - SelectionNotify = 31 - ColormapNotify = 32 - ClientMessage = 33 - MappingNotify = 34 - end - - EV_KEY = '#abcdfhikmopstwxyABDEKNRSTWXY' - EV_TYPE = 'nsnnsbnsnsbsxnnnnsnnbsnssnwnn' - - def self.scan_args(arg_str, arg_val) - arg_cnv = [] - arg_str.strip.split(/\s+/).each_with_index{|kwd,idx| - if kwd =~ /^%(.)$/ - if num = EV_KEY.index($1) - case EV_TYPE[num] - when ?n - begin - val = TkComm::number(arg_val[idx]) - rescue ArgumentError - # ignore --> no convert - val = TkComm::string(arg_val[idx]) - end - arg_cnv << val - when ?s - arg_cnv << TkComm::string(arg_val[idx]) - when ?b - arg_cnv << TkComm::bool(arg_val[idx]) - when ?w - arg_cnv << TkComm::window(arg_val[idx]) - when ?x - begin - arg_cnv << TkComm::number(arg_val[idx]) - rescue ArgumentError - arg_cnv << arg_val[idx] - end - else - arg_cnv << arg_val[idx] - end - else - arg_cnv << arg_val[idx] - end - else - arg_cnv << arg_val[idx] - end - } - arg_cnv - end - - def initialize(seq,a,b,c,d,f,h,i,k,m,o,p,s,t,w,x,y, - aa,bb,dd,ee,kk,nn,rr,ss,tt,ww,xx,yy) - @serial = seq - @above = a - @num = b - @count = c - @detail = d - @focus = f - @height = h - @win_hex = i - @keycode = k - @mode = m - @override = o - @place = p - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @borderwidth = bb - @wheel_delta = dd - @send_event = ee - @keysym = kk - @keysym_num = nn - @rootwin_id = rr - @subwindow = ss - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :above - attr :num - attr :count - attr :detail - attr :focus - attr :height - attr :win_hex - attr :keycode - attr :mode - attr :override - attr :place - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :borderwidth - attr :wheel_delta - attr :send_event - attr :keysym - attr :keysym_num - attr :rootwin_id - attr :subwindow - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|*arg| - TkUtil.eval_cmd(cmd, *Event.scan_args(args, arg)) - }) - id + " " + args + def _epath(win) + if win.kind_of?(TkObject) + win.epath + elsif win.respond_to?(:epath) + win.epath else - args = ' %# %a %b %c %d %f %h %i %k %m %o %p %s %t %w %x %y' + - ' %A %B %D %E %K %N %R %S %T %W %X %Y' - id = install_cmd(proc{|*arg| - TkUtil.eval_cmd(cmd, Event.new(*Event.scan_args(args, arg))) - }) - id + args + win end end + private :_epath +end + +# define TkComm module (step 2: event binding) +module TkComm + include TkEvent + extend TkEvent def tk_event_sequence(context) if context.kind_of? TkVirtualEvent @@ -624,7 +713,8 @@ module TkComm def _bind_core(mode, what, context, cmd, args=nil) id = install_bind(cmd, args) if cmd begin - tk_call(*(what + ["<#{tk_event_sequence(context)}>", mode + id])) + tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", + mode + id])) rescue uninstall_cmd(id) if cmd fail @@ -640,12 +730,12 @@ module TkComm end def _bind_remove(what, context) - tk_call(*(what + ["<#{tk_event_sequence(context)}>", ''])) + tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", ''])) end def _bindinfo(what, context=nil) if context - tk_call(*what+["<#{tk_event_sequence(context)}>"]).collect {|cmdline| + tk_call_without_enc(*what+["<#{tk_event_sequence(context)}>"]) .collect {|cmdline| if cmdline =~ /^rb_out (c\d+)\s+(.*)$/ #[Tk_CMDTBL[$1], $2] [TkCore::INTERP.tk_cmd_tbl[$1], $2] @@ -654,7 +744,7 @@ module TkComm end } else - tk_split_simplelist(tk_call(*what)).collect!{|seq| + tk_split_simplelist(tk_call_without_enc(*what)).collect!{|seq| l = seq.scan(/<*[^<>]+>*/).collect!{|subseq| case (subseq) when /^<<[^<>]+>>$/ @@ -709,25 +799,9 @@ module TkComm def bindinfo_all(context=nil) _bindinfo(['bind', 'all'], context) end - - def pack(*args) - TkPack.configure(*args) - end - - def grid(*args) - TkGrid.configure(*args) - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - end + module TkCore include TkComm extend TkComm @@ -764,7 +838,14 @@ module TkCore @init_ip_env = [].taint # table of Procs @add_tk_procs = [].taint # table of [name, args, body] - @cb_entry_class = Class.new{|c| + @cb_entry_class = Class.new(TkCallbackEntry){|c| + class << c + def inspect + sprintf("#", self.__id__) + end + alias to_s inspect + end + def initialize(ip, cmd) @ip = ip @cmd = cmd @@ -773,9 +854,16 @@ module TkCore def call(*args) @ip.cb_eval(@cmd, *args) end - } + def inspect + sprintf("#", self.__id__) + end + alias to_s inspect + }.freeze } + def INTERP.cb_entry_class + @cb_entry_class + end def INTERP.tk_cmd_tbl @tk_cmd_tbl end @@ -783,6 +871,15 @@ module TkCore @tk_windows end + class Tk_OBJECT_TABLE + def initialize(id) + @id = id + end + def method_missing(m, *args, &b) + TkCore::INTERP.tk_object_table(@id).send(m, *args, &b) + end + end + def INTERP.tk_object_table(id) @tk_table_list[id] end @@ -790,20 +887,21 @@ module TkCore id = @tk_table_list.size (tbl = {}).tainted? || tbl.taint @tk_table_list << tbl - obj = Object.new - obj.instance_eval <<-EOD - def self.method_missing(m, *args) - TkCore::INTERP.tk_object_table(#{id}).send(m, *args) - end - EOD - return obj +# obj = Object.new +# obj.instance_eval <<-EOD +# def self.method_missing(m, *args) +# TkCore::INTERP.tk_object_table(#{id}).send(m, *args) +# end +# EOD +# return obj + Tk_OBJECT_TABLE.new(id) end def INTERP.get_cb_entry(cmd) @cb_entry_class.new(__getip, cmd).freeze end def INTERP.cb_eval(cmd, *args) - TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) + TkUtil._get_eval_string(TkUtil.eval_cmd(cmd, *args)) end def INTERP.init_ip_env(script = Proc.new) @@ -821,16 +919,64 @@ module TkCore end end + WIDGET_DESTROY_HOOK = '' + INTERP._invoke_without_enc('event', 'add', + "<#{WIDGET_DESTROY_HOOK}>", 'Destroy') + INTERP._invoke_without_enc('bind', 'all', "<#{WIDGET_DESTROY_HOOK}>", + install_bind(proc{|xpath| + path = xpath[1..-1] + unless TkCore::INTERP.deleted? + if (widget = TkCore::INTERP.tk_windows[path]) + if widget.respond_to?(:__destroy_hook__) + begin + widget.__destroy_hook__ + rescue Exception + end + end + end + end + }, 'x%W')) + INTERP.add_tk_procs(TclTkLib::FINALIZE_PROC_NAME, '', + "bind all <#{WIDGET_DESTROY_HOOK}> {}") + INTERP.add_tk_procs('rb_out', 'args', <<-'EOL') - regsub -all {\\} $args {\\\\} args - regsub -all {!} $args {\\!} args - regsub -all "{" $args "\\{" args - if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} { - return -code $st $ret - } { + if {[set st [catch {eval {ruby_cmd TkCore callback} $args} ret]] != 0} { + #return -code $st $ret + set idx [string first "\n\n" $ret] + if {$idx > 0} { + return -code $st \ + -errorinfo [string range $ret [expr $idx + 2] \ + [string length $ret]] \ + [string range $ret 0 [expr $idx - 1]] + } else { + return -code $st $ret + } + } else { return $ret } EOL +=begin + INTERP.add_tk_procs('rb_out', 'args', <<-'EOL') + #regsub -all {\\} $args {\\\\} args + #regsub -all {!} $args {\\!} args + #regsub -all "{" $args "\\{" args + regsub -all {(\\|!|\{|\})} $args {\\\1} args + if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} { + #return -code $st $ret + set idx [string first "\n\n" $ret] + if {$idx > 0} { + return -code $st \ + -errorinfo [string range $ret [expr $idx + 2] \ + [string length $ret]] \ + [string range $ret 0 [expr $idx - 1]] + } else { + return -code $st $ret + } + } else { + return $ret + } + EOL +=end EventFlag = TclTkLib::EventFlag @@ -842,31 +988,64 @@ module TkCore fail TkCallbackContinue, "Tk callback returns 'continue' status" end - def TkCore.callback(arg) - # arg = tk_split_list(arg) - arg = tk_split_simplelist(arg) + def TkCore.callback(*arg) + begin + TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) + rescue Exception => e + begin + msg = _toUTF8(e.class.inspect) + ': ' + + _toUTF8(e.message) + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + _toUTF8(e.backtrace.join("\n")) + + "\n---< backtrace of Tk side >-------" + msg.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + msg = e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------" + end + fail(e, msg) + end + end +=begin + def TkCore.callback(arg_str) + # arg = tk_split_list(arg_str) + arg = tk_split_simplelist(arg_str) #_get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg)) #_get_eval_string(TkUtil.eval_cmd(TkCore::INTERP.tk_cmd_tbl[arg.shift], # *arg)) - cb_obj = TkCore::INTERP.tk_cmd_tbl[arg.shift] - unless $DEBUG - cb_obj.call(*arg) - else - begin - raise 'check backtrace' - rescue - # ignore backtrace before 'callback' - pos = -($!.backtrace.size) - end - begin - cb_obj.call(*arg) - rescue - trace = $!.backtrace - raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" + - "\tfrom #{trace[1..pos].join("\n\tfrom ")}" - end + # TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) + begin + TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) + rescue Exception => e + raise(e, e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------") end +#=begin +# cb_obj = TkCore::INTERP.tk_cmd_tbl[arg.shift] +# unless $DEBUG +# cb_obj.call(*arg) +# else +# begin +# raise 'check backtrace' +# rescue +# # ignore backtrace before 'callback' +# pos = -($!.backtrace.size) +# end +# begin +# cb_obj.call(*arg) +# rescue +# trace = $!.backtrace +# raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" + +# "\tfrom #{trace[1..pos].join("\n\tfrom ")}" +# end +# end +#=end end +=end def load_cmd_on_ip(tk_cmd) bool(tk_call('auto_load', tk_cmd)) @@ -875,7 +1054,7 @@ module TkCore def after(ms, cmd=Proc.new) myid = _curr_cmd_id cmdid = install_cmd(cmd) - tk_call("after",ms,cmdid) + tk_call_without_enc("after",ms,cmdid) # return id # return # if false #defined? Thread # Thread.start do @@ -893,69 +1072,25 @@ module TkCore def after_idle(cmd=Proc.new) myid = _curr_cmd_id cmdid = install_cmd(cmd) - tk_call('after','idle',cmdid) - end - - def clock_clicks(ms=nil) - if ms - tk_call('clock','clicks','-milliseconds').to_i - else - tk_call('clock','clicks').to_i - end - end - - def clock_format(clk, form=nil) - if form - tk_call('clock','format',clk,'-format',form).to_i - else - tk_call('clock','format',clk).to_i - end - end - - def clock_formatGMT(clk, form=nil) - if form - tk_call('clock','format',clk,'-format',form,'-gmt','1').to_i - else - tk_call('clock','format',clk,'-gmt','1').to_i - end - end - - def clock_scan(str, base=nil) - if base - tk_call('clock','scan',str,'-base',base).to_i - else - tk_call('clock','scan',str).to_i - end - end - - def clock_scanGMT(str, base=nil) - if base - tk_call('clock','scan',str,'-base',base,'-gmt','1').to_i - else - tk_call('clock','scan',str,'-gmt','1').to_i - end - end - - def clock_seconds - tk_call('clock','seconds').to_i + tk_call_without_enc('after','idle',cmdid) end def windowingsystem - tk_call('tk', 'windowingsystem') + tk_call_without_enc('tk', 'windowingsystem') end def scaling(scale=nil) if scale - tk_call('tk', 'scaling', scale) + tk_call_without_enc('tk', 'scaling', scale) else - Float(number(tk_call('tk', 'scaling'))) + Float(number(tk_call_without_enc('tk', 'scaling'))) end end def scaling_displayof(win, scale=nil) if scale - tk_call('tk', 'scaling', '-displayof', win, scale) + tk_call_without_enc('tk', 'scaling', '-displayof', win, scale) else - Float(number(tk_call('tk', '-displayof', win, 'scaling'))) + Float(number(tk_call_without_enc('tk', '-displayof', win, 'scaling'))) end end @@ -1049,147 +1184,154 @@ module TkCore end def event_generate(window, context, keys=nil) - window = window.path if window.kind_of? TkObject + #window = window.path if window.kind_of?(TkObject) if keys - tk_call('event', 'generate', window, - "<#{tk_event_sequence(context)}>", *hash_kv(keys)) + tk_call_without_enc('event', 'generate', window, + "<#{tk_event_sequence(context)}>", + *hash_kv(keys, true)) else - tk_call('event', 'generate', window, "<#{tk_event_sequence(context)}>") + tk_call_without_enc('event', 'generate', window, + "<#{tk_event_sequence(context)}>") end + nil end def messageBox(keys) - tk_call 'tk_messageBox', *hash_kv(keys) + tk_call('tk_messageBox', *hash_kv(keys)) end def getOpenFile(keys = nil) - tk_call 'tk_getOpenFile', *hash_kv(keys) + tk_call('tk_getOpenFile', *hash_kv(keys)) end def getSaveFile(keys = nil) - tk_call 'tk_getSaveFile', *hash_kv(keys) + tk_call('tk_getSaveFile', *hash_kv(keys)) end def chooseColor(keys = nil) - tk_call 'tk_chooseColor', *hash_kv(keys) + tk_call('tk_chooseColor', *hash_kv(keys)) end def chooseDirectory(keys = nil) - tk_call 'tk_chooseDirectory', *hash_kv(keys) + tk_call('tk_chooseDirectory', *hash_kv(keys)) end + def _ip_eval_core(enc_mode, cmd_string) + case enc_mode + when nil + res = INTERP._eval(cmd_string) + when false + res = INTERP._eval_without_enc(cmd_string) + when true + res = INTERP._eval_with_enc(cmd_string) + end + if INTERP._return_value() != 0 + fail RuntimeError, res, error_at + end + return res + end + private :_ip_eval_core + def ip_eval(cmd_string) - res = INTERP._eval(cmd_string) + _ip_eval_core(nil, cmd_string) + end + + def ip_eval_without_enc(cmd_string) + _ip_eval_core(false, cmd_string) + end + + def ip_eval_with_enc(cmd_string) + _ip_eval_core(true, cmd_string) + end + + def _ip_invoke_core(enc_mode, *args) + case enc_mode + when false + res = INTERP._invoke_without_enc(*args) + when nil + res = INTERP._invoke(*args) + when true + res = INTERP._invoke_with_enc(*args) + end if INTERP._return_value() != 0 fail RuntimeError, res, error_at end return res end + private :_ip_invoke_core def ip_invoke(*args) - res = INTERP._invoke(*args) - if INTERP._return_value() != 0 - fail RuntimeError, res, error_at - end - return res + _ip_invoke_core(nil, *args) end - def tk_call(*args) - puts args.inspect if $DEBUG - args.collect! {|x|ruby2tcl(x)} - args.compact! - args.flatten! - print "=> ", args.join(" ").inspect, "\n" if $DEBUG + def ip_invoke_without_enc(*args) + _ip_invoke_core(false, *args) + end + + def ip_invoke_with_enc(*args) + _ip_invoke_core(true, *args) + end + + def _tk_call_core(enc_mode, *args) + ### puts args.inspect if $DEBUG + #args.collect! {|x|ruby2tcl(x, enc_mode)} + #args.compact! + #args.flatten! + args = _conv_args([], enc_mode, *args) + puts 'invoke args => ' + args.inspect if $DEBUG + ### print "=> ", args.join(" ").inspect, "\n" if $DEBUG begin # res = INTERP._invoke(*args).taint - res = INTERP._invoke(*args) # _invoke returns a TAINTED string + # res = INTERP._invoke(enc_mode, *args) + res = _ip_invoke_core(enc_mode, *args) + # >>>>> _invoke returns a TAINTED string <<<<< rescue NameError => err -# err = $! + # err = $! begin args.unshift "unknown" #res = INTERP._invoke(*args).taint - res = INTERP._invoke(*args) # _invoke returns a TAINTED string + #res = INTERP._invoke(enc_mode, *args) + res = _ip_invoke_core(enc_mode, *args) + # >>>>> _invoke returns a TAINTED string <<<<< rescue StandardError => err2 - fail err2 unless /^invalid command/ =~ err2 + fail err2 unless /^invalid command/ =~ err2.message fail err end end if INTERP._return_value() != 0 fail RuntimeError, res, error_at end - print "==> ", res.inspect, "\n" if $DEBUG + ### print "==> ", res.inspect, "\n" if $DEBUG return res end -end + private :_tk_call_core -module TkPackage - include TkCore - extend TkPackage - - TkCommandNames = ['package'.freeze].freeze - - def add_path(path) - Tk::AUTO_PATH.value = Tk::AUTO_PATH.to_a << path + def tk_call(*args) + _tk_call_core(nil, *args) end - def forget(package) - tk_call('package', 'forget', package) - nil + def tk_call_without_enc(*args) + _tk_call_core(false, *args) end - def names - tk_split_simplelist(tk_call('package', 'names')) - end - - def provide(package, version=nil) - if version - tk_call('package', 'provide', package, version) - nil - else - tk_call('package', 'provide', package) - end - end - - def present(package, version=None) - tk_call('package', 'present', package, version) - end - - def present_exact(package, version) - tk_call('package', 'present', '-exact', package, version) - end - - def require(package, version=None) - tk_call('package', 'require', package, version) - end - - def require_exact(package, version) - tk_call('package', 'require', '-exact', package, version) - end - - def versions(package) - tk_split_simplelist(tk_call('package', 'versions', package)) - end - - def vcompare(version1, version2) - Integer(tk_call('package', 'vcompare', version1, version2)) - end - - def vsatisfies(version1, version2) - bool(tk_call('package', 'vsatisfies', version1, version2)) + def tk_call_with_enc(*args) + _tk_call_core(true, *args) end end + module Tk include TkCore extend Tk - TCL_VERSION = INTERP._invoke("info", "tclversion").freeze - TCL_PATCHLEVEL = INTERP._invoke("info", "patchlevel").freeze + TCL_VERSION = INTERP._invoke_without_enc("info", "tclversion").freeze + TCL_PATCHLEVEL = INTERP._invoke_without_enc("info", "patchlevel").freeze - TK_VERSION = INTERP._invoke("set", "tk_version").freeze - TK_PATCHLEVEL = INTERP._invoke("set", "tk_patchLevel").freeze + TK_VERSION = INTERP._invoke_without_enc("set", "tk_version").freeze + TK_PATCHLEVEL = INTERP._invoke_without_enc("set", "tk_patchLevel").freeze - JAPANIZED_TK = (INTERP._invoke("info", "commands", "kanji") != "").freeze + JAPANIZED_TK = (INTERP._invoke_without_enc("info", "commands", + "kanji") != "").freeze def Tk.const_missing(sym) case(sym) @@ -1209,8 +1351,11 @@ module Tk # tk_split_simplelist(INTERP._invoke('set', 'tcl_libPath')) when :PLATFORM, :TCL_PLATFORM - Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', - 'tcl_platform'))] + if $SAFE >= 4 + fail SecurityError, "can't get #{sym} when $SAFE >= 4" + end + Hash[*tk_split_simplelist(INTERP._invoke_without_enc('array', 'get', + 'tcl_platform'))] when :ENV Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'env'))] @@ -1226,7 +1371,7 @@ module Tk when :PRIV, :PRIVATE, :TK_PRIV priv = {} - if INTERP._invoke('info', 'vars', 'tk::Priv') != "" + if INTERP._invoke_without_enc('info', 'vars', 'tk::Priv') != "" var_nam = 'tk::Priv' else var_nam = 'tkPriv' @@ -1254,44 +1399,116 @@ module Tk TkRoot.new end + def Tk.load_tclscript(file, enc=nil) + if enc + # TCL_VERSION >= 8.5 + tk_call('source', '-encoding', enc, file) + else + tk_call('source', file) + end + end + + def Tk.load_tcllibrary(file, pkg_name=None, interp=None) + tk_call('load', file, pkg_name, interp) + end + + def Tk.unload_tcllibrary(*args) + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + nocomp = (keys['nocomplain'])? '-nocomplain': None + keeplib = (keys['keeplibrary'])? '-keeplibrary': None + tk_call('unload', nocomp, keeplib, '--', *args) + else + tk_call('unload', *args) + end + end + def Tk.bell(nice = false) if nice - tk_call 'bell', '-nice' + tk_call_without_enc('bell', '-nice') else - tk_call 'bell' + tk_call_without_enc('bell') end + nil end def Tk.bell_on_display(win, nice = false) if nice - tk_call('bell', '-displayof', win, '-nice') + tk_call_without_enc('bell', '-displayof', win, '-nice') else - tk_call('bell', '-displayof', win) + tk_call_without_enc('bell', '-displayof', win) end + nil end def Tk.destroy(*wins) - tk_call('destroy', *wins) + tk_call_without_enc('destroy', *wins) end def Tk.exit - tk_call('destroy', '.') + tk_call_without_enc('destroy', '.') end - def Tk.current_grabs - tk_split_list(tk_call('grab', 'current')) + def Tk.pack(*args) + #TkPack.configure(*args) + TkPack(*args) + end + + def Tk.grid(*args) + TkGrid.configure(*args) + end + + def Tk.update(idle=nil) + if idle + tk_call_without_enc('update', 'idletasks') + else + tk_call_without_enc('update') + end + end + def Tk.update_idletasks + update(true) + end + +=begin + # See tcltklib.c for the reason of why the following methods are disabled. + def Tk.thread_update(idle=nil) + if idle + tk_call_without_enc('thread_update', 'idletasks') + else + tk_call_without_enc('thread_update') + end + end + def Tk.thread_update_idletasks + thread_update(true) + end +=end + + def Tk.current_grabs(win = nil) + if win + window(tk_call_without_enc('grab', 'current', win)) + else + tk_split_list(tk_call_without_enc('grab', 'current')) + end end def Tk.focus(display=nil) if display == nil - window(tk_call('focus')) + window(tk_call_without_enc('focus')) else - window(tk_call('focus', '-displayof', display)) + window(tk_call_without_enc('focus', '-displayof', display)) + end + end + + def Tk.focus_to(win, force=false) + if force + tk_call_without_enc('focus', '-force', win) + else + tk_call_without_enc('focus', win) end end def Tk.focus_lastfor(win) - window(tk_call('focus', '-lastfor', win)) + window(tk_call_without_enc('focus', '-lastfor', win)) end def Tk.focus_next(win) @@ -1303,7 +1520,7 @@ module Tk end def Tk.strictMotif(bool=None) - bool(tk_call('set', 'tk_strictMotif', bool)) + bool(tk_call_without_enc('set', 'tk_strictMotif', bool)) end def Tk.show_kinsoku(mode='both') @@ -1336,286 +1553,12 @@ module Tk end end - def Tk.toUTF8(str,encoding) - INTERP._toUTF8(str,encoding) + def Tk.toUTF8(str, encoding = nil) + _toUTF8(str, encoding) end - def Tk.fromUTF8(str,encoding) - INTERP._fromUTF8(str,encoding) - end - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - def xview(*index) - v = tk_send('xview', *index) - list(v) if index.size == 0 - end - def yview(*index) - v = tk_send('yview', *index) - list(v) if index.size == 0 - end - def xscrollbar(bar=nil) - if bar - @xscrollbar = bar - @xscrollbar.orient 'horizontal' - self.xscrollcommand {|*arg| @xscrollbar.set(*arg)} - @xscrollbar.command {|*arg| self.xview(*arg)} - end - @xscrollbar - end - def yscrollbar(bar=nil) - if bar - @yscrollbar = bar - @yscrollbar.orient 'vertical' - self.yscrollcommand {|*arg| @yscrollbar.set(*arg)} - @yscrollbar.command {|*arg| self.yview(*arg)} - end - @yscrollbar - end - end - - module Wm - include TkComm - - TkCommandNames = ['wm'.freeze].freeze - - def aspect(*args) - w = tk_call('wm', 'aspect', path, *args) - if args.length == 0 - list(w) - else - self - end - end - def attributes(slot=nil,value=None) - if slot == nil - lst = tk_split_list(tk_call('wm', 'attributes', path)) - info = {} - while key = lst.shift - info[key[1..-1]] = lst.shift - end - info - elsif slot.kind_of? Hash - tk_call('wm', 'attributes', path, *hash_kv(slot)) - self - elsif value == None - tk_call('wm', 'attributes', path, "-#{slot}") - else - tk_call('wm', 'attributes', path, "-#{slot}", value) - self - end - end - def client(name=None) - if name == None - tk_call 'wm', 'client', path - else - name = '' if name == nil - tk_call 'wm', 'client', path, name - self - end - end - def colormapwindows(*args) - r = tk_call('wm', 'colormapwindows', path, *args) - if args.size == 0 - list(r) - else - self - end - end - def wm_command(value=nil) - if value - tk_call('wm', 'command', path, value) - self - else - procedure(tk_call('wm', 'command', path)) - end - end - def deiconify(ex = true) - tk_call('wm', 'deiconify', path) if ex - self - end - def focusmodel(mode = nil) - if mode - tk_call 'wm', 'focusmodel', path, mode - self - else - tk_call 'wm', 'focusmodel', path - end - end - def frame - tk_call('wm', 'frame', path) - end - def geometry(geom=nil) - if geom - tk_call('wm', 'geometry', path, geom) - self - else - tk_call('wm', 'geometry', path) - end - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - if args.size == 0 - list(w) - else - self - end - end - def group(*args) - w = tk_call('wm', 'group', path, *args) - if args.size == 0 - window(w) - else - self - end - end - def iconbitmap(bmp=nil) - if bmp - tk_call 'wm', 'iconbitmap', path, bmp - self - else - tk_call 'wm', 'iconbitmap', path - end - end - def iconify(ex = true) - tk_call('wm', 'iconify', path) if ex - self - end - def iconmask(bmp=nil) - if bmp - tk_call 'wm', 'iconmask', path, bmp - self - else - tk_call 'wm', 'iconmask', path - end - end - def iconname(name=nil) - if name - tk_call 'wm', 'iconname', path, name - self - else - tk_call 'wm', 'iconname', path - end - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - if args.size == 0 - list(w) - else - self - end - end - def iconwindow(*args) - w = tk_call('wm', 'iconwindow', path, *args) - if args.size == 0 - window(w) - else - self - end - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - if args.size == 0 - list(w) - else - self - end - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - if args.size == 0 - list(w) - else - self - end - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - self - end - end - def positionfrom(who=None) - if who == None - r = tk_call('wm', 'positionfrom', path) - (r == "")? nil: r - else - tk_call('wm', 'positionfrom', path, who) - self - end - end - def protocol(name=nil, cmd=nil) - if cmd - tk_call('wm', 'protocol', path, name, cmd) - self - elsif name - result = tk_call('wm', 'protocol', path, name) - (result == "")? nil : tk_tcl2ruby(result) - else - tk_split_simplelist(tk_call('wm', 'protocol', path)) - end - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - else - self - end - end - def sizefrom(who=None) - if who == None - r = tk_call('wm', 'sizefrom', path) - (r == "")? nil: r - else - tk_call('wm', 'sizefrom', path, who) - self - end - end - def stackorder - list(tk_call('wm', 'stackorder', path)) - end - def stackorder_isabove(win) - bool(tk_call('wm', 'stackorder', path, 'isabove', win)) - end - def stackorder_isbelow(win) - bool(tk_call('wm', 'stackorder', path, 'isbelow', win)) - end - def state(state=nil) - if state - tk_call 'wm', 'state', path, state - self - else - tk_call 'wm', 'state', path - end - end - def title(str=nil) - if str - tk_call('wm', 'title', path, str) - self - else - tk_call('wm', 'title', path) - end - end - def transient(master=nil) - if master - tk_call('wm', 'transient', path, master) - self - else - window(tk_call('wm', 'transient', path, master)) - end - end - def withdraw(ex = true) - tk_call('wm', 'withdraw', path) if ex - self - end + def Tk.fromUTF8(str, encoding = nil) + _fromUTF8(str, encoding) end end @@ -1623,46 +1566,20 @@ end # string with Tcl's encoding ########################################### module Tk - class EncodedString < String - @@enc_buf = '__rb_encoding_buffer__' - - def self.tk_escape(str) - s = '"' + str.gsub(/[\[\]$"]/, '\\\\\&') + '"' - #s = '"' + str.gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - TkCore::INTERP.__eval(Kernel.format('global %s; set %s %s', - @@enc_buf, @@enc_buf, s)) - end - - def self.new(str, enc = Tk.encoding_system) - obj = super(self.tk_escape(str)) - obj.instance_eval{@enc = enc} - obj - end - - def self.new_without_escape(str, enc = Tk.encoding_system) - obj = super(str) - obj.instance_eval{@enc = enc} - obj - end - - def encoding - @enc - end + def Tk.subst_utf_backslash(str) + Tk::EncodedString.subst_utf_backslash(str) end - def Tk.EncodedString(str, enc = Tk.encoding_system) - Tk::EncodedString.new(str, enc) + def Tk.subst_tk_backslash(str) + Tk::EncodedString.subst_tk_backslash(str) end - - class UTF8_String < EncodedString - def self.new(str) - super(str, 'utf-8') - end - def self.new_without_escape(str) - super(str, 'utf-8') - end + def Tk.utf_to_backslash_sequence(str) + Tk::EncodedString.utf_to_backslash_sequence(str) end - def Tk.UTF8_String(str) - Tk::UTF8_String.new(str) + def Tk.utf_to_backslash(str) + Tk::EncodedString.utf_to_backslash_sequence(str) + end + def Tk.to_backslash_sequence(str) + Tk::EncodedString.to_backslash_sequence(str) end end @@ -1670,20 +1587,96 @@ end ########################################### # convert kanji string to/from utf-8 ########################################### -if /^8\.[1-9]/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK +if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) class TclTkIp # from tkencoding.rb by ttate@jaist.ac.jp + attr_accessor :encoding + alias __eval _eval alias __invoke _invoke - - attr_accessor :encoding - - def _eval(cmd) - if defined? @encoding - if cmd.kind_of?(Tk::EncodedString) - _fromUTF8(__eval(_toUTF8(cmd, cmd.encoding)), @encoding) + + alias __toUTF8 _toUTF8 + alias __fromUTF8 _fromUTF8 + +=begin + #### --> definition is moved to TclTkIp module + + def _toUTF8(str, encoding = nil) + # decide encoding + if encoding + encoding = encoding.to_s + elsif str.kind_of?(Tk::EncodedString) && str.encoding != nil + encoding = str.encoding.to_s + elsif str.instance_variable_get(:@encoding) + encoding = str.instance_variable_get(:@encoding).to_s + elsif defined?(@encoding) && @encoding != nil + encoding = @encoding.to_s + else + encoding = __invoke('encoding', 'system') + end + + # convert + case encoding + when 'utf-8', 'binary' + str + else + __toUTF8(str, encoding) + end + end + + def _fromUTF8(str, encoding = nil) + unless encoding + if defined?(@encoding) && @encoding != nil + encoding = @encoding.to_s else - _fromUTF8(__eval(_toUTF8(cmd, @encoding)), @encoding) + encoding = __invoke('encoding', 'system') + end + end + + if str.kind_of?(Tk::EncodedString) + if str.encoding == 'binary' + str + else + __fromUTF8(str, encoding) + end + elsif str.instance_variable_get(:@encoding).to_s == 'binary' + str + else + __fromUTF8(str, encoding) + end + end +=end + + def _eval(cmd) + _fromUTF8(__eval(_toUTF8(cmd))) + end + + def _invoke(*cmds) + _fromUTF8(__invoke(*(cmds.collect{|cmd| _toUTF8(cmd)}))) + end + + alias _eval_with_enc _eval + alias _invoke_with_enc _invoke + +=begin + def _eval(cmd) + if defined?(@encoding) && @encoding != 'utf-8' + ret = if cmd.kind_of?(Tk::EncodedString) + case cmd.encoding + when 'utf-8', 'binary' + __eval(cmd) + else + __eval(_toUTF8(cmd, cmd.encoding)) + end + elsif cmd.instance_variable_get(:@encoding) == 'binary' + __eval(cmd) + else + __eval(_toUTF8(cmd, @encoding)) + end + if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary' + ret + else + _fromUTF8(ret, @encoding) end else __eval(cmd) @@ -1691,19 +1684,32 @@ if /^8\.[1-9]/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK end def _invoke(*cmds) - if defined? @encoding + if defined?(@encoding) && @encoding != 'utf-8' cmds = cmds.collect{|cmd| if cmd.kind_of?(Tk::EncodedString) - _toUTF8(cmd, cmd.encoding) + case cmd.encoding + when 'utf-8', 'binary' + cmd + else + _toUTF8(cmd, cmd.encoding) + end + elsif cmd.instance_variable_get(:@encoding) == 'binary' + cmd else _toUTF8(cmd, @encoding) end } - _fromUTF8(__invoke(*cmds), @encoding) + ret = __invoke(*cmds) + if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary' + ret + else + _fromUTF8(ret, @encoding) + end else __invoke(*cmds) end end +=end end module Tk @@ -1767,6 +1773,9 @@ else class TclTkIp alias __eval _eval alias __invoke _invoke + + alias _eval_with_enc _eval + alias _invoke_with_enc _invoke end module Tk @@ -1799,1723 +1808,9 @@ else end alias encoding_convert_to encoding_convertto end - - extend Encoding end end -module TkBindCore - def bind(context, cmd=Proc.new, args=nil) - Tk.bind(self, context, cmd, args) - end - - def bind_append(context, cmd=Proc.new, args=nil) - Tk.bind_append(self, context, cmd, args) - end - - def bind_remove(context) - Tk.bind_remove(self, context) - end - - def bindinfo(context=nil) - Tk.bindinfo(self, context) - end -end - -class TkBindTag - include TkBindCore - - #BTagID_TBL = {} - BTagID_TBL = TkCore::INTERP.create_table - Tk_BINDTAG_ID = ["btag".freeze, "00000".taint].freeze - - TkCore::INTERP.init_ip_env{ BTagID_TBL.clear } - - def TkBindTag.id2obj(id) - BTagID_TBL[id]? BTagID_TBL[id]: id - end - - def TkBindTag.new_by_name(name, *args, &b) - return BTagID_TBL[name] if BTagID_TBL[name] - self.new(*args, &b).instance_eval{ - BTagID_TBL.delete @id - @id = name - BTagID_TBL[@id] = self - } - end - - def initialize(*args, &b) - @id = Tk_BINDTAG_ID.join - Tk_BINDTAG_ID[1].succ! - BTagID_TBL[@id] = self - bind(*args, &b) if args != [] - end - - ALL = self.new_by_name('all') - - def name - @id - end - - def to_eval - @id - end - - def inspect - Kernel.format "#", @id - end -end - -class TkBindTagAll", @id - end -end - -class TkVariable - include Tk - extend TkCore - - include Comparable - - #TkCommandNames = ['tkwait'.freeze].freeze - TkCommandNames = ['vwait'.freeze].freeze - - #TkVar_CB_TBL = {} - #TkVar_ID_TBL = {} - TkVar_CB_TBL = TkCore::INTERP.create_table - TkVar_ID_TBL = TkCore::INTERP.create_table - Tk_VARIABLE_ID = ["v".freeze, "00000".taint].freeze - - TkCore::INTERP.add_tk_procs('rb_var', 'args', - "ruby [format \"TkVariable.callback %%Q!%s!\" $args]") - - def TkVariable.callback(args) - #name1,name2,op = tk_split_list(args) - name1,name2,op = tk_split_simplelist(args) - if TkVar_CB_TBL[name1] - _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) - else - '' - end - end - - def initialize(val="") - @id = Tk_VARIABLE_ID.join - Tk_VARIABLE_ID[1].succ! - TkVar_ID_TBL[@id] = self - - @trace_var = nil - @trace_elem = nil - @trace_opts = nil - -=begin - if val == [] - # INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)', - # @id, @id, @id)) - elsif val.kind_of?(Array) - a = [] - # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} - # s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' - val.each_with_index{|e,i| a.push(i); a.push(e)} - #s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + array2tk_list(a).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) - elsif val.kind_of?(Hash) - #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ - # .gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ - .gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) - else - #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(format('global %s; set %s %s', @id, @id, s)) - end -=end - if val.kind_of?(Hash) - #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ - # .gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ - .gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s)) - else - #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) - end - end - - def wait(on_thread = false, check_root = false) - if $SAFE >= 4 - fail SecurityError, "can't wait variable at $SAFE >= 4" - end - if on_thread - if check_root - INTERP._thread_tkwait('variable', @id) - else - INTERP._thread_vwait(@id) - end - else - if check_root - INTERP._invoke('tkwait', 'variable', @id) - else - INTERP._invoke('vwait', @id) - end - end - end - def eventloop_wait(check_root = false) - wait(false, check_root) - end - def thread_wait(check_root = false) - wait(true, check_root) - end - def tkwait(on_thread = true) - wait(on_thread, true) - end - def eventloop_tkwait - wait(false, true) - end - def thread_tkwait - wait(true, true) - end - - def id - @id - end - - def value - begin - INTERP._eval(Kernel.format('global %s; set %s', @id, @id)) - rescue - if INTERP._eval(Kernel.format('global %s; array exists %s', - @id, @id)) != "1" - fail - else - Hash[*tk_split_simplelist(INTERP._eval(Kernel.format('global %s; array get %s', @id, @id)))] - end - end - end - - def value=(val) - begin - #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) - rescue - if INTERP._eval(Kernel.format('global %s; array exists %s', - @id, @id)) != "1" - fail - else - if val == [] - INTERP._eval(Kernel.format('global %s; unset %s; set %s(0) 0; unset %s(0)', @id, @id, @id, @id)) - elsif val.kind_of?(Array) - a = [] - val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} - #s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + a.join(" ").gsub(/[\[\]$"\\]/, '\\\\\&') + '"' - INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', - @id, @id, @id, s)) - elsif val.kind_of?(Hash) - #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ - # .gsub(/[\[\]$"]/, '\\\\\&') + '"' - s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ - .gsub(/[\[\]$\\"]/, '\\\\\&') + '"' - INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', - @id, @id, @id, s)) - else - fail - end - end - end - end - - def [](index) - INTERP._eval(Kernel.format('global %s; set %s(%s)', - @id, @id, _get_eval_string(index))) - end - - def []=(index,val) - INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, - _get_eval_string(index), _get_eval_string(val))) - end - - def numeric - number(value) - end - def numeric=(val) - case val - when Numeric - self.value=(val) - when TkVariable - self.value=(val.numeric) - else - raise ArgumentError, "Numeric is expected" - end - end - - def to_i - number(value).to_i - end - - def to_f - number(value).to_f - end - - def to_s - #string(value).to_s - value - end - - def to_sym - value.intern - end - - def list - tk_split_list(value) - end - alias to_a list - - def list=(val) - case val - when Array - self.value=(val) - when TkVariable - self.value=(val.list) - else - raise ArgumentError, "Array is expected" - end - end - - def inspect - Kernel.format "#", @id - end - - def coerce(other) - case other - when TkVariable - [other.value, self.value] - when String - [other, self.to_s] - when Symbol - [other, self.to_sym] - when Integer - [other, self.to_i] - when Float - [other, self.to_f] - when Array - [other, self.to_a] - else - [other, self.value] - end - end - - def &(other) - if other.kind_of?(Array) - self.to_a & other.to_a - else - self.to_i & other.to_i - end - end - def |(other) - if other.kind_of?(Array) - self.to_a | other.to_a - else - self.to_i | other.to_i - end - end - def +(other) - case other - when Array - self.to_a + other - when String - self.value + other - else - begin - number(self.value) + other - rescue - self.value + other.to_s - end - end - end - def -(other) - if other.kind_of?(Array) - self.to_a - other - else - number(self.value) - other - end - end - def *(other) - begin - number(self.value) * other - rescue - self.value * other - end - end - def /(other) - number(self.value) / other - end - def %(other) - begin - number(self.value) % other - rescue - self.value % other - end - end - def **(other) - number(self.value) ** other - end - def =~(other) - self.value =~ other - end - - def ==(other) - case other - when TkVariable - self.equal?(other) - when String - self.to_s == other - when Symbol - self.to_sym == other - when Integer - self.to_i == other - when Float - self.to_f == other - when Array - self.to_a == other - when Hash - self.value == other - else - false - end - end - - def zero? - numeric.zero? - end - def nonzero? - !(numeric.zero?) - end - - def <=>(other) - if other.kind_of?(TkVariable) - begin - val = other.numeric - other = val - rescue - other = other.value - end - end - if other.kind_of?(Numeric) - begin - return self.numeric <=> other - rescue - return self.value <=> other.to_s - end - else - return self.value <=> other - end - end - - def to_eval - @id - end - - def unset(elem=nil) - if elem - INTERP._eval(Kernel.format('global %s; unset %s(%s)', - @id, @id, tk_tcl2ruby(elem))) - else - INTERP._eval(Kernel.format('global %s; unset %s', @id, @id)) - end - end - alias remove unset - - def trace_callback(elem, op) - if @trace_var.kind_of? Array - @trace_var.each{|m,e| e.call(self,elem,op) if m.index(op)} - end - if elem.kind_of? String - if @trace_elem[elem].kind_of? Array - @trace_elem[elem].each{|m,e| e.call(self,elem,op) if m.index(op)} - end - end - end - - def trace(opts, cmd) - @trace_var = [] if @trace_var == nil - opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') - @trace_var.unshift([opts,cmd]) - if @trace_opts == nil - TkVar_CB_TBL[@id] = self - @trace_opts = opts - Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var') - else - newopts = @trace_opts.dup - opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} - if newopts != @trace_opts - Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var') - @trace_opts.replace(newopts) - Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var') - end - end - end - - def trace_element(elem, opts, cmd) - @trace_elem = {} if @trace_elem == nil - @trace_elem[elem] = [] if @trace_elem[elem] == nil - opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') - @trace_elem[elem].unshift([opts,cmd]) - if @trace_opts == nil - TkVar_CB_TBL[@id] = self - @trace_opts = opts - Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var') - else - newopts = @trace_opts.dup - opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} - if newopts != @trace_opts - Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var') - @trace_opts.replace(newopts) - Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var') - end - end - end - - def trace_vinfo - return [] unless @trace_var - @trace_var.dup - end - def trace_vinfo_for_element(elem) - return [] unless @trace_elem - return [] unless @trace_elem[elem] - @trace_elem[elem].dup - end - - def trace_vdelete(opts,cmd) - return unless @trace_var.kind_of? Array - opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') - idx = -1 - newopts = '' - @trace_var.each_with_index{|e,i| - if idx < 0 && e[0] == opts && e[1] == cmd - idx = i - next - end - e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} - } - if idx >= 0 - @trace_var.delete_at(idx) - else - return - end - - @trace_elem.each{|elem| - @trace_elem[elem].each{|e| - e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} - } - } - - newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') - if newopts != @trace_opts - Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var') - @trace_opts.replace(newopts) - if @trace_opts != '' - Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var') - end - end - end - - def trace_vdelete_for_element(elem,opts,cmd) - return unless @trace_elem.kind_of? Hash - return unless @trace_elem[elem].kind_of? Array - opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') - idx = -1 - @trace_elem[elem].each_with_index{|e,i| - if idx < 0 && e[0] == opts && e[1] == cmd - idx = i - next - end - } - if idx >= 0 - @trace_elem[elem].delete_at(idx) - else - return - end - - newopts = '' - @trace_var.each{|e| - e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} - } - @trace_elem.each{|elem| - @trace_elem[elem].each{|e| - e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} - } - } - - newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') - if newopts != @trace_opts - Tk.tk_call('trace', 'vdelete', @id, @trace_opts, 'rb_var') - @trace_opts.replace(newopts) - if @trace_opts != '' - Tk.tk_call('trace', 'variable', @id, @trace_opts, 'rb_var') - end - end - end -end - -class TkVarAccess= Tk8.4a2 ? - if slot - conf = tk_split_list(tk_call('place', 'configure', - win.epath, "-#{slot}") ) - conf[0] = conf[0][1..-1] - conf - else - tk_split_simplelist(tk_call('place', 'configure', - win.epath)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - conf - } - end - end - - def forget(win) - tk_call 'place', 'forget', win - end - - def info(win) - ilist = list(tk_call('place', 'info', win.epath)) - info = {} - while key = ilist.shift - info[key[1..-1]] = ilist.shift - end - return info - end - - def slaves(master) - list(tk_call('place', 'slaves', master.epath)) - end - - module_function :configure, :configinfo, :forget, :info, :slaves -end - -module TkOptionDB - include Tk - extend Tk - - TkCommandNames = ['option'.freeze].freeze - - module Priority - WidgetDefault = 20 - StartupFile = 40 - UserDefault = 60 - Interactive = 80 - end - - def add(pat, value, pri=None) - if $SAFE >= 4 - fail SecurityError, "can't call 'TkOptionDB.add' at $SAFE >= 4" - end - tk_call 'option', 'add', pat, value, pri - end - def clear - if $SAFE >= 4 - fail SecurityError, "can't call 'TkOptionDB.crear' at $SAFE >= 4" - end - tk_call 'option', 'clear' - end - def get(win, name, klass) - tk_call('option', 'get', win ,name, klass) - end - def readfile(file, pri=None) - tk_call 'option', 'readfile', file, pri - end - module_function :add, :clear, :get, :readfile - - def read_entries(file, f_enc=nil) - if TkCore::INTERP.safe? - fail SecurityError, - "can't call 'TkOptionDB.read_entries' on a safe interpreter" - end - - i_enc = Tk.encoding() - - unless f_enc - f_enc = i_enc - end - - ent = [] - cline = '' - open(file, 'r') {|f| - while line = f.gets - cline += line.chomp! - case cline - when /\\$/ # continue - cline.chop! - next - when /^!/ # coment - cline = '' - next - when /^([^:]+):\s(.*)$/ - pat = $1 - val = $2 - p "ResourceDB: #{[pat, val].inspect}" if $DEBUG - pat = TkCore::INTERP._toUTF8(pat, f_enc) - pat = TkCore::INTERP._fromUTF8(pat, i_enc) - val = TkCore::INTERP._toUTF8(val, f_enc) - val = TkCore::INTERP._fromUTF8(val, i_enc) - ent << [pat, val] - cline = '' - else # unknown --> ignore - cline = '' - next - end - end - } - ent - end - module_function :read_entries - - def read_with_encoding(file, f_enc=nil, pri=None) - # try to read the file as an OptionDB file - readfile(file, pri).each{|pat, val| - add(pat, val, pri) - } - -=begin - i_enc = Tk.encoding() - - unless f_enc - f_enc = i_enc - end - - cline = '' - open(file, 'r') {|f| - while line = f.gets - cline += line.chomp! - case cline - when /\\$/ # continue - cline.chop! - next - when /^!/ # coment - cline = '' - next - when /^([^:]+):\s(.*)$/ - pat = $1 - val = $2 - p "ResourceDB: #{[pat, val].inspect}" if $DEBUG - pat = TkCore::INTERP._toUTF8(pat, f_enc) - pat = TkCore::INTERP._fromUTF8(pat, i_enc) - val = TkCore::INTERP._toUTF8(val, f_enc) - val = TkCore::INTERP._fromUTF8(val, i_enc) - add(pat, val, pri) - cline = '' - else # unknown --> ignore - cline = '' - next - end - end - } -=end - end - module_function :read_with_encoding - - # support procs on the resource database - @@resource_proc_class = Class.new - class << @@resource_proc_class - private :new - - CARRIER = '.'.freeze - METHOD_TBL = TkCore::INTERP.create_table - ADD_METHOD = false - SAFE_MODE = 4 - - def __closed_block_check__(str) - depth = 0 - str.scan(/[{}]/){|x| - if x == "{" - depth += 1 - elsif x == "}" - depth -= 1 - end - if depth <= 0 && !($' =~ /\A\s*\Z/) - fail RuntimeError, "bad string for procedure : #{str.inspect}" - end - } - str - end - - def __check_proc_string__(str) - # If you want to check the proc_string, do it in this method. - # Please define this in the block given to 'new_proc_class' method. - str - end - - def method_missing(id, *args) - res_proc = self::METHOD_TBL[id] - unless res_proc.kind_of? Proc - if id == :new || !(self::METHOD_TBL.has_key?(id) || self::ADD_METHOD) - raise NoMethodError, - "not support resource-proc '#{id.id2name}' for #{self.name}" - end - proc_str = TkOptionDB.get(self::CARRIER, id.id2name, '').strip - proc_str = '{' + proc_str + '}' unless /\A\{.*\}\Z/ =~ proc_str - proc_str = __closed_block_check__(proc_str) - proc_str = __check_proc_string__(proc_str) - res_proc = eval('Proc.new' + proc_str) - self::METHOD_TBL[id] = res_proc - end - proc{ - $SAFE = self::SAFE_MODE - res_proc.call(*args) - }.call - end - - private :__closed_block_check__, :__check_proc_string__, :method_missing - end - @@resource_proc_class.freeze - - def __create_new_class(klass, func, safe = 4, add = false, parent = nil) - klass = klass.to_s if klass.kind_of? Symbol - unless (?A..?Z) === klass[0] - fail ArgumentError, "bad string '#{klass}' for class name" - end - unless func.kind_of? Array - fail ArgumentError, "method-list must be Array" - end - func_str = func.join(' ') - if parent == nil - install_win(parent) - elsif parent <= @@resource_proc_class - install_win(parent::CARRIER) - else - fail ArgumentError, "parent must be Resource-Proc class" - end - carrier = Tk.tk_call('frame', @path, '-class', klass) - - body = <<-"EOD" - class #{klass} < TkOptionDB.module_eval('@@resource_proc_class') - CARRIER = '#{carrier}'.freeze - METHOD_TBL = TkCore::INTERP.create_table - ADD_METHOD = #{add} - SAFE_MODE = #{safe} - %w(#{func_str}).each{|f| METHOD_TBL[f.intern] = nil } - end - EOD - - if parent.kind_of?(Class) && parent <= @@resource_proc_class - parent.class_eval(body) - eval(parent.name + '::' + klass) - else - eval(body) - eval('TkOptionDB::' + klass) - end - end - module_function :__create_new_class - private_class_method :__create_new_class - - def __remove_methods_of_proc_class(klass) - # for security, make these methods invalid - class << klass - attr_reader :class_eval, :name, :superclass, - :ancestors, :const_defined?, :const_get, :const_set, - :constants, :included_modules, :instance_methods, - :method_defined?, :module_eval, :private_instance_methods, - :protected_instance_methods, :public_instance_methods, - :remove_const, :remove_method, :undef_method, - :to_s, :inspect, :display, :method, :methods, - :instance_eval, :instance_variables, :kind_of?, :is_a?, - :private_methods, :protected_methods, :public_methods - end - end - module_function :__remove_methods_of_proc_class - private_class_method :__remove_methods_of_proc_class - - RAND_BASE_CNT = [0] - RAND_BASE_HEAD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - RAND_BASE_CHAR = RAND_BASE_HEAD + 'abcdefghijklmnopqrstuvwxyz0123456789_' - def __get_random_basename - name = '%s%03d' % [RAND_BASE_HEAD[rand(RAND_BASE_HEAD.size),1], - RAND_BASE_CNT[0]] - len = RAND_BASE_CHAR.size - (6+rand(10)).times{ - name << RAND_BASE_CHAR[rand(len),1] - } - RAND_BASE_CNT[0] = RAND_BASE_CNT[0] + 1 - name - end - module_function :__get_random_basename - private_class_method :__get_random_basename - - # define new proc class : - # If you want to modify the new class or create a new subclass, - # you must do such operation in the block parameter. - # Because the created class is flozen after evaluating the block. - def new_proc_class(klass, func, safe = 4, add = false, parent = nil, &b) - new_klass = __create_new_class(klass, func, safe, add, parent) - new_klass.class_eval(&b) if block_given? - __remove_methods_of_proc_class(new_klass) - new_klass.freeze - new_klass - end - module_function :new_proc_class - - def eval_under_random_base(parent = nil, &b) - new_klass = __create_new_class(__get_random_basename(), - [], 4, false, parent) - ret = new_klass.class_eval(&b) if block_given? - __remove_methods_of_proc_class(new_klass) - new_klass.freeze - ret - end - module_function :eval_under_random_base - - def new_proc_class_random(klass, func, safe = 4, add = false, &b) - eval_under_random_base(){ - TkOption.new_proc_class(klass, func, safe, add, self, &b) - } - end - module_function :new_proc_class_random -end -TkOption = TkOptionDB -TkResourceDB = TkOptionDB module TkTreatFont def font_configinfo(name = nil) @@ -3666,198 +1961,37 @@ module TkTreatFont end end -module TkTreatItemFont - def __conf_cmd(idx) - raise NotImplementedError, "need to define `__conf_cmd'" - end - def __item_pathname(tagOrId) - raise NotImplementedError, "need to define `__item_pathname'" - end - private :__conf_cmd, :__item_pathname - def tagfont_configinfo(tagOrId, name = nil) - pathname = __item_pathname(tagOrId) - ret = TkFont.used_on(pathname) - if ret == nil -=begin - if name - ret = name - else - ret = TkFont.init_widget_font(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), tagOrId) - end -=end - ret = TkFont.init_widget_font(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), tagOrId) - end - ret - end - alias tagfontobj tagfont_configinfo - - def tagfont_configure(tagOrId, slot) - pathname = __item_pathname(tagOrId) - slot = _symbolkey2str(slot) - - if slot.key?('font') - fnt = slot.delete('font') - if fnt.kind_of? TkFont - return fnt.call_font_configure(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), - tagOrId, slot) - else - if fnt - if (slot.key?('kanjifont') || - slot.key?('latinfont') || - slot.key?('asciifont')) - fnt = TkFont.new(fnt) - - lfnt = slot.delete('latinfont') - lfnt = slot.delete('asciifont') if slot.key?('asciifont') - kfnt = slot.delete('kanjifont') - - fnt.latin_replace(lfnt) if lfnt - fnt.kanji_replace(kfnt) if kfnt - end - - slot['font'] = fnt - tk_call(self.path, __conf_cmd(0), __conf_cmd(1), - tagOrId, *hash_kv(slot)) - end - return self - end - end - - lfnt = slot.delete('latinfont') - lfnt = slot.delete('asciifont') if slot.key?('asciifont') - kfnt = slot.delete('kanjifont') - - if lfnt && kfnt - return TkFont.new(lfnt, kfnt).call_font_configure(pathname, self.path, - __conf_cmd(0), - __conf_cmd(1), - tagOrId, slot) - end - - latintagfont_configure(tagOrId, lfnt) if lfnt - kanjitagfont_configure(tagOrId, kfnt) if kfnt - - tk_call(self.path, __conf_cmd(0), __conf_cmd(1), - tagOrId, *hash_kv(slot)) if slot != {} - self +module TkBindCore + def bind(context, cmd=Proc.new, args=nil) + Tk.bind(self, context, cmd, args) end - def latintagfont_configure(tagOrId, ltn, keys=nil) - pathname = __item_pathname(tagOrId) - if (fobj = TkFont.used_on(pathname)) - fobj = TkFont.new(fobj) # create a new TkFont object - elsif Tk::JAPANIZED_TK - fobj = tagfontobj(tagOrId) # create a new TkFont object - else - tk_call(self.path, __conf_cmd(0), __conf_cmd(1), tagOrId, '-font', ltn) - return self - end - - if fobj.kind_of?(TkFont) - if ltn.kind_of? TkFont - conf = {} - ltn.latin_configinfo.each{|key,val| conf[key] = val} - if keys - fobj.latin_configure(conf.update(keys)) - else - fobj.latin_configure(conf) - end - else - fobj.latin_replace(ltn) - end - end - - return fobj.call_font_configure(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), tagOrId, {}) - end - alias asciitagfont_configure latintagfont_configure - - def kanjitagfont_configure(tagOrId, knj, keys=nil) - pathname = __item_pathname(tagOrId) - if (fobj = TkFont.used_on(pathname)) - fobj = TkFont.new(fobj) # create a new TkFont object - elsif Tk::JAPANIZED_TK - fobj = tagfontobj(tagOrId) # create a new TkFont object - else - tk_call(self.path, __conf_cmd(0), __conf_cmd(1), tagOrId, '-font', knj) - return self - end - - if fobj.kind_of?(TkFont) - if knj.kind_of? TkFont - conf = {} - knj.kanji_configinfo.each{|key,val| conf[key] = val} - if keys - fobj.kanji_configure(conf.update(keys)) - else - fobj.kanji_configure(conf) - end - else - fobj.kanji_replace(knj) - end - end - - return fobj.call_font_configure(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), tagOrId, {}) + def bind_append(context, cmd=Proc.new, args=nil) + Tk.bind_append(self, context, cmd, args) end - def tagfont_copy(tagOrId, window, wintag=nil) - pathname = __item_pathname(tagOrId) - if wintag - fnt = window.tagfontobj(wintag).dup - else - fnt = window.fontobj.dup - end - fnt.call_font_configure(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), tagOrId, {}) - return self + def bind_remove(context) + Tk.bind_remove(self, context) end - def latintagfont_copy(tagOrId, window, wintag=nil) - pathname = __item_pathname(tagOrId) - tagfontobj(tagOrId).dup.call_font_configure(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), - tagOrId, {}) - if wintag - tagfontobj(tagOrId). - latin_replace(window.tagfontobj(wintag).latin_font_id) - else - tagfontobj(tagOrId).latin_replace(window.fontobj.latin_font_id) - end - self - end - alias asciitagfont_copy latintagfont_copy - - def kanjitagfont_copy(tagOrId, window, wintag=nil) - pathname = __item_pathname(tagOrId) - tagfontobj(tagOrId).dup.call_font_configure(pathname, self.path, - __conf_cmd(0), __conf_cmd(1), - tagOrId, {}) - if wintag - tagfontobj(tagOrId). - kanji_replace(window.tagfontobj(wintag).kanji_font_id) - else - tagfontobj(tagOrId).kanji_replace(window.fontobj.kanji_font_id) - end - self + def bindinfo(context=nil) + Tk.bindinfo(self, context) end end + class TkObject 0 - tk_call path, 'configure', *hash_kv(slot) + tk_call(path, 'configure', *hash_kv(slot)) end else @@ -3938,93 +2085,177 @@ class TkObjectvalue}) end else - tk_call path, 'configure', "-#{slot}", value + tk_call(path, 'configure', "-#{slot}", value) end end self end def configure_cmd(slot, value) - configure slot, install_cmd(value) + configure(slot, install_cmd(value)) end def configinfo(slot = nil) - if slot == 'font' || slot == :font || - slot == 'kanjifont' || slot == :kanjifont - conf = tk_split_simplelist(tk_send('configure', "-#{slot}") ) - conf[0] = conf[0][1..-1] - conf[4] = fontobj(conf[4]) - conf - else - if slot - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - conf = tk_split_simplelist(tk_send('configure', "-#{slot}") ) - else - conf = tk_split_list(tk_send('configure', "-#{slot}") ) - end + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot == 'font' || slot == :font || + slot == 'kanjifont' || slot == :kanjifont + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('configure', "-#{slot}"))) conf[0] = conf[0][1..-1] + conf[4] = fontobj(conf[4]) conf else - ret = tk_split_simplelist(tk_send('configure') ).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] + if slot + case slot.to_s when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('configure', "-#{slot}"))) else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end + conf = tk_split_list(_fromUTF8(tk_send_without_enc('configure', "-#{slot}"))) end + conf[0] = conf[0][1..-1] conf - } - fontconf = ret.assoc('font') - if fontconf - ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} - fontconf[4] = fontobj(fontconf[4]) - ret.push(fontconf) else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('configure'))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = fontobj(fontconf[4]) + ret.push(fontconf) + else + ret + end + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot == 'font' || slot == :font || + slot == 'kanjifont' || slot == :kanjifont + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('configure', "-#{slot}"))) + key = conf.shift[1..-1] + conf[3] = fontobj(conf[3]) + { key => conf } + else + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('configure', "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('configure', "-#{slot}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('configure'))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = fontobj(fontconf[3]) + ret['font'] = fontconf + end ret end end end end + def current_configinfo(slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = configinfo(slot) + {conf[0] => conf[4]} + else + ret = {} + configinfo().each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + configinfo(slot).each{|key, conf| + ret[key] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + def event_generate(context, keys=nil) if keys - tk_call('event', 'generate', path, - "<#{tk_event_sequence(context)}>", *hash_kv(keys)) + #tk_call('event', 'generate', path, + # "<#{tk_event_sequence(context)}>", *hash_kv(keys)) + tk_call_without_enc('event', 'generate', path, + "<#{tk_event_sequence(context)}>", + *hash_kv(keys, true)) else - tk_call('event', 'generate', path, "<#{tk_event_sequence(context)}>") + #tk_call('event', 'generate', path, "<#{tk_event_sequence(context)}>") + tk_call_without_enc('event', 'generate', path, + "<#{tk_event_sequence(context)}>") end end def tk_trace_variable(v) unless v.kind_of?(TkVariable) - fail(ArgumentError, - Kernel.format("type error (%s); must be TkVariable object", - v.class)) + fail(ArgumentError, "type error (#{v.class}); must be TkVariable object") end v end private :tk_trace_variable def destroy - # tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id + tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id end end + class TkWindowtarget} end - tk_call 'pack', epath, *hash_kv(keys) + #tk_call 'pack', epath, *hash_kv(keys) + TkPack.configure(self, keys) self end - def unpack - tk_call 'pack', 'forget', epath + def pack_forget + #tk_call_without_enc('pack', 'forget', epath) + TkPack.forget(self) self end - alias pack_forget unpack + alias unpack pack_forget def pack_config(slot, value=None) + #if slot.kind_of? Hash + # tk_call 'pack', 'configure', epath, *hash_kv(slot) + #else + # tk_call 'pack', 'configure', epath, "-#{slot}", value + #end if slot.kind_of? Hash - tk_call 'pack', 'configure', epath, *hash_kv(slot) + TkPack.configure(self, slot) else - tk_call 'pack', 'configure', epath, "-#{slot}", value + TkPack.configure(self, slot=>value) end end def pack_info() - ilist = list(tk_call('pack', 'info', epath)) - info = {} - while key = ilist.shift - info[key[1..-1]] = ilist.shift - end - return info + #ilist = list(tk_call('pack', 'info', epath)) + #info = {} + #while key = ilist.shift + # info[key[1..-1]] = ilist.shift + #end + #return info + TkPack.info(self) end def pack_propagate(mode=None) + #if mode == None + # bool(tk_call('pack', 'propagate', epath)) + #else + # tk_call('pack', 'propagate', epath, mode) + # self + #end if mode == None - bool(tk_call('pack', 'propagate', epath)) + TkPack.propagate(self) else - tk_call('pack', 'propagate', epath, mode) + TkPack.propagate(self, mode) self end end def pack_slaves() - list(tk_call('pack', 'slaves', epath)) + #list(tk_call('pack', 'slaves', epath)) + TkPack.slaves(self) end def grid(keys = nil) - tk_call 'grid', epath, *hash_kv(keys) + #tk_call 'grid', epath, *hash_kv(keys) + if keys + TkGrid.configure(self, keys) + else + TkGrid.configure(self) + end self end @@ -4172,94 +2432,120 @@ class TkWindowtarget} end - tk_call 'grid', epath, *hash_kv(keys) + #tk_call 'grid', epath, *hash_kv(keys) + TkGrid.configure(self, keys) self end - def ungrid - tk_call 'grid', 'forget', epath + def grid_forget + #tk_call('grid', 'forget', epath) + TkGrid.forget(self) self end - alias grid_forget ungrid + alias ungrid grid_forget def grid_bbox(*args) - list(tk_call('grid', 'bbox', epath, *args)) + #list(tk_call('grid', 'bbox', epath, *args)) + TkGrid.bbox(self, *args) end def grid_config(slot, value=None) + #if slot.kind_of? Hash + # tk_call 'grid', 'configure', epath, *hash_kv(slot) + #else + # tk_call 'grid', 'configure', epath, "-#{slot}", value + #end if slot.kind_of? Hash - tk_call 'grid', 'configure', epath, *hash_kv(slot) + TkGrid.configure(self, slot) else - tk_call 'grid', 'configure', epath, "-#{slot}", value + TkGrid.configure(self, slot=>value) end end def grid_columnconfig(index, keys) - tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys)) + #tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys)) + TkGrid.columnconfigure(self, index, keys) end + alias grid_columnconfigure grid_columnconfig def grid_rowconfig(index, keys) - tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys)) + #tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys)) + TkGrid.rowconfigure(self, index, keys) end + alias grid_rowconfigure grid_rowconfig def grid_columnconfiginfo(index, slot=nil) - if slot - tk_call('grid', 'columnconfigure', epath, index, "-#{slot}").to_i - else - ilist = list(tk_call('grid', 'columnconfigure', epath, index)) - info = {} - while key = ilist.shift - info[key[1..-1]] = ilist.shift - end - info - end + #if slot + # tk_call('grid', 'columnconfigure', epath, index, "-#{slot}").to_i + #else + # ilist = list(tk_call('grid', 'columnconfigure', epath, index)) + # info = {} + # while key = ilist.shift + # info[key[1..-1]] = ilist.shift + # end + # info + #end + TkGrid.columnconfiginfo(self, index, slot) end def grid_rowconfiginfo(index, slot=nil) - if slot - tk_call('grid', 'rowconfigure', epath, index, "-#{slot}").to_i - else - ilist = list(tk_call('grid', 'rowconfigure', epath, index)) - info = {} - while key = ilist.shift - info[key[1..-1]] = ilist.shift - end - info - end + #if slot + # tk_call('grid', 'rowconfigure', epath, index, "-#{slot}").to_i + #else + # ilist = list(tk_call('grid', 'rowconfigure', epath, index)) + # info = {} + # while key = ilist.shift + # info[key[1..-1]] = ilist.shift + # end + # info + #end + TkGrid.rowconfiginfo(self, index, slot) end def grid_info() - list(tk_call('grid', 'info', epath)) + #list(tk_call('grid', 'info', epath)) + TkGrid.info(self) end def grid_location(x, y) - list(tk_call('grid', 'location', epath, x, y)) + #list(tk_call('grid', 'location', epath, x, y)) + TkGrid.location(self, x, y) end def grid_propagate(mode=None) + #if mode == None + # bool(tk_call('grid', 'propagate', epath)) + #else + # tk_call('grid', 'propagate', epath, mode) + # self + #end if mode == None - bool(tk_call('grid', 'propagate', epath)) + TkGrid.propagete(self) else - tk_call('grid', 'propagate', epath, mode) + TkGrid.propagete(self, mode) self end end def grid_remove() - tk_call 'grid', 'remove', epath + #tk_call 'grid', 'remove', epath + TkGrid.remove(self) self end def grid_size() - list(tk_call('grid', 'size', epath)) + #list(tk_call('grid', 'size', epath)) + TkGrid.size(self) end def grid_slaves(args) - list(tk_call('grid', 'slaves', epath, *hash_kv(args))) + #list(tk_call('grid', 'slaves', epath, *hash_kv(args))) + TkGrid.slaves(self, args) end - def place(keys = nil) - tk_call 'place', epath, *hash_kv(keys) + def place(keys) + #tk_call 'place', epath, *hash_kv(keys) + TkPlace.configure(self, keys) self end @@ -4270,88 +2556,90 @@ class TkWindowtarget} end - tk_call 'place', epath, *hash_kv(keys) + #tk_call 'place', epath, *hash_kv(keys) + TkPlace.configure(self, keys) self end - def unplace - tk_call 'place', 'forget', epath + def place_forget + #tk_call 'place', 'forget', epath + TkPlace.forget(self) self end - alias place_forget unplace + alias unplace place_forget def place_config(slot, value=None) - if slot.kind_of? Hash - tk_call 'place', 'configure', epath, *hash_kv(slot) - else - tk_call 'place', 'configure', epath, "-#{slot}", value - end + #if slot.kind_of? Hash + # tk_call 'place', 'configure', epath, *hash_kv(slot) + #else + # tk_call 'place', 'configure', epath, "-#{slot}", value + #end + TkPlace.configure(self, slot, value) end def place_configinfo(slot = nil) # for >= Tk8.4a2 ? - if slot - conf = tk_split_list(tk_call('place', 'configure', epath, "-#{slot}") ) - conf[0] = conf[0][1..-1] - conf - else - tk_split_simplelist(tk_call('place', - 'configure', epath)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - conf - } - end + #if slot + # conf = tk_split_list(tk_call('place', 'configure', epath, "-#{slot}") ) + # conf[0] = conf[0][1..-1] + # conf + #else + # tk_split_simplelist(tk_call('place', + # 'configure', epath)).collect{|conflist| + # conf = tk_split_simplelist(conflist) + # conf[0] = conf[0][1..-1] + # conf + # } + #end + TkPlace.configinfo(slot) end def place_info() - ilist = list(tk_call('place', 'info', epath)) - info = {} - while key = ilist.shift - info[key[1..-1]] = ilist.shift - end - return info + #ilist = list(tk_call('place', 'info', epath)) + #info = {} + #while key = ilist.shift + # info[key[1..-1]] = ilist.shift + #end + #return info + TkPlace.info(self) end def place_slaves() - list(tk_call('place', 'slaves', epath)) + #list(tk_call('place', 'slaves', epath)) + TkPlace.slaves(self) end - def focus(force=false) + def set_focus(force=false) if force - tk_call 'focus', '-force', path + tk_call_without_enc('focus', '-force', path) else - tk_call 'focus', path + tk_call_without_enc('focus', path) end self end + alias focus set_focus - def grab(*args) - if !args or args.length == 0 - tk_call 'grab', 'set', path - self - elsif args.length == 1 - case args[0] - when 'global', :global - #return(tk_call('grab', 'set', '-global', path)) - tk_call('grab', 'set', '-global', path) - return self - when 'release', :release - #return tk_call('grab', 'release', path) - tk_call('grab', 'release', path) - return self - else - val = tk_call('grab', args[0], path) - end - case args[0] - when 'current', :current - return window(val) - when 'status', :status - return val - end - self + def grab(opt = nil) + unless opt + tk_call_without_enc('grab', 'set', path) + return self + end + + case opt + when 'global', :global + #return(tk_call('grab', 'set', '-global', path)) + tk_call_without_enc('grab', 'set', '-global', path) + return self + when 'release', :release + #return tk_call('grab', 'release', path) + tk_call_without_enc('grab', 'release', path) + return self + when 'current', :current + return window(tk_call_without_enc('grab', 'current', path)) + when 'status', :status + return tk_call_without_enc('grab', 'status', path) else - fail ArgumentError, 'wrong # of args' + return tk_call_without_enc('grab', args[0], path) end end @@ -4372,20 +2660,30 @@ class TkWindow= 4 fail SecurityError, "can't wait visibility at $SAFE >= 4" end + on_thread &= (Thread.list.size != 1) if on_thread INTERP._thread_tkwait('visibility', path) else @@ -4451,6 +2750,7 @@ class TkWindow= 4 fail SecurityError, "can't wait destroy at $SAFE >= 4" end + on_thread &= (Thread.list.size != 1) if on_thread INTERP._thread_tkwait('window', epath) else @@ -4491,6 +2791,7 @@ class TkWindowtrue, :widgetname=>'.') - if keys # wm commands - keys.each{|k,v| - if v.kind_of? Array - new.send(k,*v) - else - new.send(k,v) - end - } - end - ROOT[0] = new - Tk_WINDOWS["."] = new - end -=end - def TkRoot.new(keys=nil, &b) - unless TkCore::INTERP.tk_windows['.'] - TkCore::INTERP.tk_windows['.'] = - super(:without_creating=>true, :widgetname=>'.') - end - root = TkCore::INTERP.tk_windows['.'] - if keys # wm commands - keys.each{|k,v| - if v.kind_of? Array - root.send(k,*v) - else - root.send(k,v) - end - } - end - root.instance_eval(&b) if block_given? - root - end - - WidgetClassName = 'Tk'.freeze - WidgetClassNames[WidgetClassName] = self - - def create_self - @path = '.' - end - private :create_self - - def path - "." - end - - def TkRoot.destroy - TkCore::INTERP._invoke('destroy', '.') - end -end - -class TkToplevelparent} - end - end - if keys.key?('classname') - keys['class'] = keys.delete('classname') - end - @classname = keys['class'] - @colormap = keys['colormap'] - @container = keys['container'] - @visual = keys['visual'] - if !@classname && my_class_name - keys['class'] = @classname = my_class_name - end - if @classname.kind_of? TkBindTag - @db_class = @classname - @classname = @classname.id - elsif @classname - @db_class = TkDatabaseClass.new(@classname) - else - @db_class = self.class - @classname = @db_class::WidgetClassName - end - super(keys) - end - - def create_self(keys) - if keys and keys != None - tk_call 'frame', @path, *hash_kv(keys) - else - tk_call 'frame', @path - end - end - private :create_self - - def database_classname - @classname - end - - def self.database_class - if self == WidgetClassNames[WidgetClassName] || self.name == '' - self - else - TkDatabaseClass.new(self.name) - end - end - def self.database_classname - self.database_class.name - end - - def self.bind(*args) - if self == WidgetClassNames[WidgetClassName] || self.name == '' - super(*args) - else - TkDatabaseClass.new(self.name).bind(*args) - end - end - def self.bind_append(*args) - if self == WidgetClassNames[WidgetClassName] || self.name == '' - super(*args) - else - TkDatabaseClass.new(self.name).bind_append(*args) - end - end - def self.bind_remove(*args) - if self == WidgetClassNames[WidgetClassName] || self.name == '' - super(*args) - else - TkDatabaseClass.new(self.name).bind_remove(*args) - end - end - def self.bindinfo(*args) - if self == WidgetClassNames[WidgetClassName] || self.name == '' - super(*args) - else - TkDatabaseClass.new(self.name).bindinfo(*args) - end - end -end - -class TkLabelFramevalue) - 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 - - def coords(val=None) - tk_split_list(tk_send('coords', val)) - end - - def identify(x, y) - tk_send('identify', x, y) - end - - def set(val) - tk_send("set", val) - end - - def value - get - end - - def value= (val) - set(val) - end -end - -class TkScrollbarval}) - end - else - tk_call 'itemconfigure', index, "-#{key}", val - end - end - self - end - - def itemconfiginfo(index, key=nil) - if key - case key.to_s - when 'text', 'label', 'show' - conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}")) - when 'font', 'kanjifont' - conf = tk_split_simplelist(tk_send('itemconfigure',index,"-#{key}") ) - conf[4] = tagfont_configinfo(index, conf[4]) - else - conf = tk_split_list(tk_send('itemconfigure',index,"-#{key}")) - end - conf[0] = conf[0][1..-1] - conf - else - ret = tk_split_simplelist(tk_send('itemconfigure', - index)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show' - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - fontconf = ret.assoc('font') - if fontconf - ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} - fontconf[4] = tagfont_configinfo(index, fontconf[4]) - ret.push(fontconf) - else - ret - end - end - end -end - -module TkTreatMenuEntryFont - include TkTreatItemFont - - ItemCMD = ['entryconfigure'.freeze, TkComm::None].freeze - def __conf_cmd(idx) - ItemCMD[idx] - end - - def __item_pathname(tagOrId) - self.path + ';' + tagOrId.to_s - end - - private :__conf_cmd, :__item_pathname -end - -class TkMenuval}) - end - else - tk_call 'entryconfigure', index, "-#{key}", val - end - end - self - end - - def entryconfiginfo(index, key=nil) - if key - case key.to_s - when 'text', 'label', 'show' - conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}")) - when 'font', 'kanjifont' - conf = tk_split_simplelist(tk_send('entryconfigure',index,"-#{key}")) - conf[4] = tagfont_configinfo(index, conf[4]) - else - conf = tk_split_list(tk_send('entryconfigure',index,"-#{key}")) - end - conf[0] = conf[0][1..-1] - conf - else - ret = tk_split_simplelist(tk_send('entryconfigure', - index)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show' - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - if fontconf - ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} - fontconf[4] = tagfont_configinfo(index, fontconf[4]) - ret.push(fontconf) - else - ret - end - end - end -end - -class TkMenuClone return value of tk_optionMenu - @path = path - #TkComm::Tk_WINDOWS[@path] = self - TkCore::INTERP.tk_windows[@path] = self - end - end - - def initialize(parent=nil, var=TkVariable.new, firstval=nil, *vals) - if parent.kind_of? Hash - keys = _symbolkey2str(parent) - parent = keys['parent'] - var = keys['variable'] if keys['variable'] - firstval, *vals = keys['values'] - end - fail 'variable option must be TkVariable' unless var.kind_of? TkVariable - @variable = var - firstval = @variable.value unless firstval - @variable.value = firstval - install_win(if parent then parent.path end) - @menu = OptionMenu.new(tk_call('tk_optionMenu', @path, @variable.id, - firstval, *vals)) - end - - def value - @variable.value - end - - def activate(index) - @menu.activate(index) - self - end - def add(value) - @menu.add('radiobutton', 'variable'=>@variable, - 'label'=>value, 'value'=>value) - self - end - def index(index) - @menu.index(index) - end - def invoke(index) - @menu.invoke(index) - end - def insert(index, value) - @menu.add(index, 'radiobutton', 'variable'=>@variable, - 'label'=>value, 'value'=>value) - self - end - def delete(index, last=None) - @menu.delete(index, last) - self - end - def yposition(index) - @menu.yposition(index) - end - def menu - @menu - end - def menucget(key) - @menu.cget(key) - end - def menuconfigure(key, val=None) - @menu.configure(key, val) - self - end - def menuconfiginfo(key=nil) - @menu.configinfo(key) - end - def entrycget(index, key) - @menu.entrycget(index, key) - end - def entryconfigure(index, key, val=None) - @menu.entryconfigure(index, key, val) - self - end - def entryconfiginfo(index, key=nil) - @menu.entryconfiginfo(index, key) - end -end - -module TkComposite - include Tk - extend Tk - - def initialize(parent=nil, *args) - @delegates = {} - - if parent.kind_of? Hash - keys = _symbolkey2str(parent) - parent = keys.delete('parent') - @frame = TkFrame.new(parent) - @delegates['DEFAULT'] = @frame - @path = @epath = @frame.path - initialize_composite(keys) - else - @frame = TkFrame.new(parent) - @delegates['DEFAULT'] = @frame - @path = @epath = @frame.path - initialize_composite(*args) - end - end - - def epath - @epath - end - - def initialize_composite(*args) end - private :initialize_composite - - def delegate(option, *wins) - if @delegates[option].kind_of?(Array) - for i in wins - @delegates[option].push(i) - end - else - @delegates[option] = wins - end - end - - def configure(slot, value=None) - if slot.kind_of? Hash - slot.each{|slot,value| configure slot, value} - else - if @delegates and @delegates[slot] - for i in @delegates[slot] - if not i - i = @delegates['DEFALUT'] - redo - else - last = i.configure(slot, value) - end - end - last - else - super - end - end - end -end - -module TkClipboard - include Tk - extend Tk - - TkCommandNames = ['clipboard'.freeze].freeze - - def self.clear(win=nil) - if win - tk_call 'clipboard', 'clear', '-displayof', win - else - tk_call 'clipboard', 'clear' - end - end - def self.clear_on_display(win) - tk_call 'clipboard', 'clear', '-displayof', win - end - - def self.get(type=nil) - if type - tk_call 'clipboard', 'get', '-type', type - else - tk_call 'clipboard', 'get' - end - end - def self.get_on_display(win, type=nil) - if type - tk_call 'clipboard', 'get', '-displayof', win, '-type', type - else - tk_call 'clipboard', 'get', '-displayof', win - end - end - - def self.set(data, keys=nil) - clear - append(data, keys) - end - def self.set_on_display(win, data, keys=nil) - clear(win) - append_on_display(win, data, keys) - end - - def self.append(data, keys=nil) - args = ['clipboard', 'append'] - args += hash_kv(keys) - args += ['--', data] - tk_call(*args) - end - def self.append_on_display(win, data, keys=nil) - args = ['clipboard', 'append', '-displayof', win] - args += hash_kv(keys) - args += ['--', data] - tk_call(*args) - end - - def clear - TkClipboard.clear_on_display(self) - self - end - def get(type=nil) - TkClipboard.get_on_display(self, type) - end - def set(data, keys=nil) - TkClipboard.set_on_display(self, data, keys) - self - end - def append(data, keys=nil) - TkClipboard.append_on_display(self, data, keys) - self - end -end - -# widget_destroy_hook -require 'tkvirtevent' -TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|xpath| - path = xpath[1..-1] - if (widget = TkCore::INTERP.tk_windows[path]) - if widget.respond_to?(:__destroy_hook__) - begin - widget.__destroy_hook__ - rescue Exception - end - end - end - }, 'x%W') # freeze core modules #TclTkLib.freeze @@ -6009,27 +2817,11 @@ TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|xpath| #TkCore.freeze #Tk.freeze -# autoload -autoload :TkCanvas, 'tkcanvas' -autoload :TkImage, 'tkcanvas' -autoload :TkBitmapImage, 'tkcanvas' -autoload :TkPhotoImage, 'tkcanvas' -autoload :TkEntry, 'tkentry' -autoload :TkSpinbox, 'tkentry' -autoload :TkText, 'tktext' -autoload :TkDialog, 'tkdialog' -autoload :TkDialog2, 'tkdialog' -autoload :TkWarning, 'tkdialog' -autoload :TkWarning2, 'tkdialog' -autoload :TkMenubar, 'tkmenubar' -autoload :TkAfter, 'tkafter' -autoload :TkTimer, 'tkafter' -autoload :TkPalette, 'tkpalette' -autoload :TkFont, 'tkfont' -autoload :TkBgError, 'tkbgerror' -autoload :TkManageFocus, 'tkmngfocus' -autoload :TkPalette, 'tkpalette' -autoload :TkWinDDE, 'tkwinpkg' -autoload :TkWinRegistry, 'tkwinpkg' -autoload :TkMacResource, 'tkmacpkg' -autoload :TkConsole, 'tkconsole' +module Tk + autoload :AUTO_PATH, 'tk/variable' + autoload :TCL_PACKAGE_PATH, 'tk/variable' + autoload :PACKAGE_PATH, 'tk/variable' + autoload :TCL_LIBRARY_PATH, 'tk/variable' + autoload :LIBRARY_PATH, 'tk/variable' + autoload :TCL_PRECISION, 'tk/variable' +end diff --git a/ext/tk/lib/tk/after.rb b/ext/tk/lib/tk/after.rb new file mode 100644 index 0000000000..8c58210331 --- /dev/null +++ b/ext/tk/lib/tk/after.rb @@ -0,0 +1,6 @@ +# +# tk/after.rb : methods for Tcl/Tk after command +# +# $Id$ +# +require 'tk/timer' diff --git a/ext/tk/lib/tk/autoload.rb b/ext/tk/lib/tk/autoload.rb new file mode 100644 index 0000000000..0a8251af8b --- /dev/null +++ b/ext/tk/lib/tk/autoload.rb @@ -0,0 +1,181 @@ +# +# autoload +# + +####################### +# geometry manager +autoload :TkGrid, 'tk/grid' +def TkGrid(*args); TkGrid.configure(*args); end + +autoload :TkPack, 'tk/pack' +def TkPack(*args); TkPack.configure(*args); end + +autoload :TkPlace, 'tk/place' +def TkPlace(*args); TkPlace.configure(*args); end + + +####################### +# others +autoload :TkBgError, 'tk/bgerror' + +autoload :TkBindTag, 'tk/bindtag' +autoload :TkBindTagAll, 'tk/bindtag' +autoload :TkDatabaseClass, 'tk/bindtag' + +autoload :TkButton, 'tk/button' + +autoload :TkConsole, 'tk/console' + +autoload :TkCanvas, 'tk/canvas' + +autoload :TkcTagAccess, 'tk/canvastag' +autoload :TkcTag, 'tk/canvastag' +autoload :TkcTagString, 'tk/canvastag' +autoload :TkcNamedTag, 'tk/canvastag' +autoload :TkcTagAll, 'tk/canvastag' +autoload :TkcTagCurrent, 'tk/canvastag' +autoload :TkcTagGroup, 'tk/canvastag' + +autoload :TkCheckButton, 'tk/checkbutton' +autoload :TkCheckbutton, 'tk/checkbutton' + +autoload :TkClipboard, 'tk/clipboard' + +autoload :TkComposite, 'tk/composite' + +autoload :TkConsole, 'tk/console' + +autoload :TkDialog, 'tk/dialog' +autoload :TkDialog2, 'tk/dialog' +autoload :TkWarning, 'tk/dialog' +autoload :TkWarning2, 'tk/dialog' + +autoload :TkEntry, 'tk/entry' + +autoload :TkEvent, 'tk/event' + +autoload :TkFont, 'tk/font' +autoload :TkTreatTagFont, 'tk/font' + +autoload :TkFrame, 'tk/frame' + +autoload :TkImage, 'tk/image' +autoload :TkBitmapImage, 'tk/image' +autoload :TkPhotoImage, 'tk/image' + +autoload :TkTreatItemFont, 'tk/itemfont' + +autoload :TkKinput, 'tk/kinput' + +autoload :TkLabel, 'tk/label' + +autoload :TkLabelFrame, 'tk/labelframe' +autoload :TkLabelframe, 'tk/labelframe' + +autoload :TkListbox, 'tk/listbox' + +autoload :TkMacResource, 'tk/macpkg' + +autoload :TkMenu, 'tk/menu' +autoload :TkMenuClone, 'tk/menu' +autoload :TkSystemMenu, 'tk/menu' +autoload :TkSysMenu_Help, 'tk/menu' +autoload :TkSysMenu_System, 'tk/menu' +autoload :TkSysMenu_Apple, 'tk/menu' +autoload :TkMenubutton, 'tk/menu' +autoload :TkOptionMenubutton, 'tk/menu' + +autoload :TkMenubar, 'tk/menubar' + +autoload :TkMessage, 'tk/message' + +autoload :TkManageFocus, 'tk/mngfocus' + +autoload :TkMsgCatalog, 'tk/msgcat' +autoload :TkMsgCat, 'tk/msgcat' + +autoload :TkNamespace, 'tk/namespace' + +autoload :TkOptionDB, 'tk/optiondb' +autoload :TkOption, 'tk/optiondb' +autoload :TkResourceDB, 'tk/optiondb' + +autoload :TkPackage, 'tk/package' + +autoload :TkPalette, 'tk/palette' + +autoload :TkPanedWindow, 'tk/panedwindow' +autoload :TkPanedwindow, 'tk/panedwindow' + +autoload :TkRadioButton, 'tk/radiobutton' +autoload :TkRadiobutton, 'tk/radiobutton' + +autoload :TkRoot, 'tk/root' + +autoload :TkScale, 'tk/scale' + +autoload :TkScrollbar, 'tk/scrollbar' +autoload :TkXScrollbar, 'tk/scrollbar' +autoload :TkYScrollbar, 'tk/scrollbar' + +autoload :TkScrollbox, 'tk/scrollbox' + +autoload :TkSelection, 'tk/selection' + +autoload :TkSpinbox, 'tk/spinbox' + +autoload :TkTreatTagFont, 'tk/tagfont' + +autoload :TkText, 'tk/text' + +autoload :TkTextImage, 'tk/textimage' + +autoload :TkTextMark, 'tk/textmark' +autoload :TkTextNamedMark, 'tk/textmark' +autoload :TkTextMarkInsert, 'tk/textmark' +autoload :TkTextMarkCurrent, 'tk/textmark' +autoload :TkTextMarkAnchor, 'tk/textmark' + +autoload :TkTextTag, 'tk/texttag' +autoload :TkTextNamedTag, 'tk/texttag' +autoload :TkTextTagSel, 'tk/texttag' + +autoload :TkTextWindow, 'tk/textwindow' + +autoload :TkAfter, 'tk/timer' +autoload :TkTimer, 'tk/timer' + +autoload :TkToplevel, 'tk/toplevel' + +autoload :TkTextWin, 'tk/txtwin_abst' + +autoload :TkValidation, 'tk/validation' +autoload :TkVariable, 'tk/variable' +autoload :TkVarAccess, 'tk/variable' + +autoload :TkVirtualEvent, 'tk/virtevent' + +autoload :TkWinfo, 'tk/winfo' + +autoload :TkWinDDE, 'tk/winpkg' +autoload :TkWinRegistry, 'tk/winpkg' + +autoload :TkXIM, 'tk/xim' + + +####################### +# sub-module of Tk +module Tk + autoload :Clock, 'tk/clock' + autoload :Scrollable, 'tk/scrollable' + autoload :Wm, 'tk/wm' + + autoload :EncodedString, 'tk/encodedstr' + def Tk.EncodedString(str, enc = nil); Tk::EncodedString.new(str, enc); end + + autoload :BinaryString, 'tk/encodedstr' + def Tk.BinaryString(str); Tk::BinaryString.new(str); end + + autoload :UTF8_String, 'tk/encodedstr' + def Tk.UTF8_String(str); Tk::UTF8_String.new(str); end +end diff --git a/ext/tk/lib/tk/bgerror.rb b/ext/tk/lib/tk/bgerror.rb new file mode 100644 index 0000000000..c82a8e046b --- /dev/null +++ b/ext/tk/lib/tk/bgerror.rb @@ -0,0 +1,29 @@ +# +# tkbgerror -- bgerror ( tkerror ) module +# 1998/07/16 by Hidetoshi Nagai +# +require 'tk' + +module TkBgError + extend Tk + + TkCommandNames = ['bgerror'.freeze].freeze + + def bgerror(message) + tk_call('bgerror', message) + end + alias tkerror bgerror + alias show bgerror + module_function :bgerror, :tkerror, :show + + def set_handler(hdlr = Proc.new) #==> handler :: proc{|msg| ...body... } + tk_call('proc', 'bgerror', 'msg', install_cmd(hdlr) + ' $msg') + end + def set_default + begin + tk_call('rename', 'bgerror', '') + rescue RuntimeError + end + end + module_function :set_handler, :set_default +end diff --git a/ext/tk/lib/tk/bindtag.rb b/ext/tk/lib/tk/bindtag.rb new file mode 100644 index 0000000000..d309ea6423 --- /dev/null +++ b/ext/tk/lib/tk/bindtag.rb @@ -0,0 +1,78 @@ +# +# tk/bind.rb : control event binding +# +require 'tk' + +class TkBindTag + include TkBindCore + + #BTagID_TBL = {} + BTagID_TBL = TkCore::INTERP.create_table + Tk_BINDTAG_ID = ["btag".freeze, "00000".taint].freeze + + TkCore::INTERP.init_ip_env{ BTagID_TBL.clear } + + def TkBindTag.id2obj(id) + BTagID_TBL[id]? BTagID_TBL[id]: id + end + + def TkBindTag.new_by_name(name, *args, &b) + return BTagID_TBL[name] if BTagID_TBL[name] + self.new(*args, &b).instance_eval{ + BTagID_TBL.delete @id + @id = name + BTagID_TBL[@id] = self + } + end + + def initialize(*args, &b) + @id = Tk_BINDTAG_ID.join('') + Tk_BINDTAG_ID[1].succ! + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + end + + ALL = self.new_by_name('all') + + def name + @id + end + + def to_eval + @id + end + + def inspect + #Kernel.format "#", @id + '#' + end +end + + +class TkBindTagAll", @id + '#' + end +end diff --git a/ext/tk/lib/tk/button.rb b/ext/tk/lib/tk/button.rb new file mode 100644 index 0000000000..15e87c300d --- /dev/null +++ b/ext/tk/lib/tk/button.rb @@ -0,0 +1,27 @@ +# +# tk/button.rb : treat button widget +# +require 'tk' +require 'tk/label' + +class TkButton +# $Date$ +# by Hidetoshi Nagai +# +require 'tk' +require 'tk/canvastag' +require 'tk/itemfont' +require 'tk/scrollable' + +module TkTreatCItemFont + include TkTreatItemFont + + ItemCMD = ['itemconfigure'.freeze, TkComm::None].freeze + def __conf_cmd(idx) + ItemCMD[idx] + end + + def __item_pathname(tagOrId) + if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag) + self.path + ';' + tagOrId.id.to_s + else + self.path + ';' + tagOrId.to_s + end + end + + private :__conf_cmd, :__item_pathname +end + +class TkCanvasvalue}) + end + else + _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), + "-#{key}", _get_eval_enc_str(value))) + end + end + self + end +# def itemconfigure(tagOrId, key, value=None) +# if key.kind_of? Hash +# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key) +# else +# tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value +# end +# end +# def itemconfigure(tagOrId, keys) +# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys) +# end + + def itemconfiginfo(tagOrId, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'dash', 'activedash', 'disableddash' + conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}")) + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + if conf[4] && conf[4] =~ /^[0-9]/ + conf[4] = list(conf[4]) + end + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),"-#{key}"))) + conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + when 'dash', 'activedash', 'disableddash' + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + if conf[4] && conf[4] =~ /^[0-9]/ + conf[4] = list(conf[4]) + end + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'dash', 'activedash', 'disableddash' + conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', + tagid(tagOrId), + "-#{key}")) + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + if conf[4] && conf[4] =~ /^[0-9]/ + conf[4] = list(conf[4]) + end + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),"-#{key}"))) + conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), "-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + when 'dash', 'activedash', 'disableddash' + if conf[2] && conf[2] =~ /^[0-9]/ + conf[2] = list(conf[2]) + end + if conf[3] && conf[3] =~ /^[0-9]/ + conf[3] = list(conf[3]) + end + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(tagid(tagOrId), fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_itemconfiginfo(tagOrId, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = itemconfiginfo(tagOrId, key) + {conf[0] => conf[4]} + else + ret = {} + itemconfiginfo(tagOrId).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + itemconfiginfo(tagOrId, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + def lower(tag, below=nil) + if below + tk_send_without_enc('lower', tagid(tag), tagid(below)) + else + tk_send_without_enc('lower', tagid(tag)) + end + self + end + + def move(tag, x, y) + tk_send_without_enc('move', tagid(tag), x, y) + self + end + + def postscript(keys) + tk_send("postscript", *hash_kv(keys)) + end + + def raise(tag, above=nil) + if above + tk_send_without_enc('raise', tagid(tag), tagid(above)) + else + tk_send_without_enc('raise', tagid(tag)) + end + self + end + + def scale(tag, x, y, xs, ys) + tk_send_without_enc('scale', tagid(tag), x, y, xs, ys) + self + end + + def scan_mark(x, y) + tk_send_without_enc('scan', 'mark', x, y) + self + end + def scan_dragto(x, y) + tk_send_without_enc('scan', 'dragto', x, y) + self + end + + def select(mode, *args) + r = tk_send_without_enc('select', mode, *args) + (mode == 'item')? TkcItem.id2obj(self, r): self + end + def select_adjust(tagOrId, index) + select('adjust', tagid(tagOrId), index) + end + def select_clear + select('clear') + end + def select_from(tagOrId, index) + select('from', tagid(tagOrId), index) + end + def select_item + select('item') + end + def select_to(tagOrId, index) + select('to', tagid(tagOrId), index) + end + + def itemtype(tag) + TkcItem.type2class(tk_send('type', tagid(tag))) + end +end + +class TkcItem "(t1)&&(t2)" + # ltag = tag1 | tag2; ltag.path => "(t1)||(t2)" + # ltag = tag1 ^ tag2; ltag.path => "(t1)^(t2)" + # ltag = - tag1; ltag.path => "!(t1)" + def & (tag) + if tag.kind_of? TkObject + TkcTagString.new(@c, '(' + @id + ')&&(' + tag.path + ')') + else + TkcTagString.new(@c, '(' + @id + ')&&(' + tag.to_s + ')') + end + end + + def | (tag) + if tag.kind_of? TkObject + TkcTagString.new(@c, '(' + @id + ')||(' + tag.path + ')') + else + TkcTagString.new(@c, '(' + @id + ')||(' + tag.to_s + ')') + end + end + + def ^ (tag) + if tag.kind_of? TkObject + TkcTagString.new(@c, '(' + @id + ')^(' + tag.path + ')') + else + TkcTagString.new(@c, '(' + @id + ')^(' + tag.to_s + ')') + end + end + + def -@ + TkcTagString.new(@c, '!(' + @id + ')') + end +end + +class TkcTagvalue, ...} for the message text + return nil + end + def msgframe_config + # returns a Hash {option=>value, ...} for the message text frame + return nil + end + def bitmap + # returns a bitmap name or a bitmap file path + # (@ + path ; e.g. '@/usr/share/bitmap/sample.xbm') + return "info" + end + def bitmap_config + # returns nil or a Hash {option=>value, ...} for the bitmap + return nil + end + def default_button + # returns a default button's number or name + # if nil or null string, set no-default + return 0 + end + def buttons + #return "BUTTON1 BUTTON2" + return ["BUTTON1", "BUTTON2"] + end + def button_configs(num) + # returns nil / Proc / Array or Hash (see _set_button_config) + return nil + end + def btnframe_config + # returns nil or a Hash {option=>value, ...} for the button frame + return nil + end +end + + +# +# TkDialog : with showing at initialize +# +class TkDialog < TkDialog2 + def self.show(*args) + self.new(*args) + end + + def initialize(*args) + super(*args) + show + end +end + + +# +# dialog for warning +# +class TkWarning2 < TkDialog2 + def initialize(parent = nil, mes = nil) + if !mes + if parent.kind_of? TkWindow + mes = "" + else + mes = parent.to_s + parent = nil + end + end + super(parent, :message=>mes) + end + + def show(mes = nil) + mes_bup = @message + @message = mes if mes + ret = super() + @message = mes_bup + ret + end + + ####### + private + + def title + return "WARNING"; + end + def bitmap + return "warning"; + end + def default_button + return 0; + end + def buttons + return "OK"; + end +end + +class TkWarning < TkWarning2 + def self.show(*args) + self.new(*args) + end + def initialize(*args) + super(*args) + show + end +end diff --git a/ext/tk/lib/tk/encodedstr.rb b/ext/tk/lib/tk/encodedstr.rb new file mode 100644 index 0000000000..5eb989f420 --- /dev/null +++ b/ext/tk/lib/tk/encodedstr.rb @@ -0,0 +1,107 @@ +# +# tk/encodedstr.rb : Tk::EncodedString class +# +require 'tk' + +########################################### +# string with Tcl's encoding +########################################### +module Tk + class EncodedString < String + Encoding = nil + + def self.subst_utf_backslash(str) + # str.gsub(/\\u([0-9A-Fa-f]{1,4})/){[$1.hex].pack('U')} + TclTkLib._subst_UTF_backslash(str) + end + def self.utf_backslash(str) + self.subst_utf_backslash(str) + end + + def self.subst_tk_backslash(str) + TclTkLib._subst_Tcl_backslash(str) + end + + def self.utf_to_backslash_sequence(str) + str.unpack('U*').collect{|c| + if c <= 0xFF # ascii character + c.chr + else + format('\u%X', c) + end + }.join('') + end + def self.utf_to_backslash(str) + self.utf_to_backslash_sequence(str) + end + + def self.to_backslash_sequence(str) + str.unpack('U*').collect{|c| + if c <= 0x1F # control character + case c + when 0x07; '\a' + when 0x08; '\b' + when 0x09; '\t' + when 0x0a; '\n' + when 0x0b; '\v' + when 0x0c; '\f' + when 0x0d; '\r' + else + format('\x%02X', c) + end + elsif c <= 0xFF # ascii character + c.chr + else + format('\u%X', c) + end + }.join('') + end + + def self.new_with_utf_backslash(str, enc = nil) + self.new('', enc).replace(self.subst_utf_backslash(str)) + end + + def self.new_without_utf_backslash(str, enc = nil) + self.new('', enc).replace(str) + end + + def initialize(str, enc = nil) + super(str) + @encoding = ( enc || + ((self.class::Encoding)? + self.class::Encoding : Tk.encoding_system) ) + end + + attr_reader :encoding + end + # def Tk.EncodedString(str, enc = nil) + # Tk::EncodedString.new(str, enc) + # end + + ################################## + + class BinaryString < EncodedString + Encoding = 'binary'.freeze + end + # def Tk.BinaryString(str) + # Tk::BinaryString.new(str) + # end + + ################################## + + class UTF8_String < EncodedString + Encoding = 'utf-8'.freeze + def self.new(str) + super(self.subst_utf_backslash(str)) + end + + def to_backslash_sequence + Tk::EncodedString.utf_to_backslash_sequence(self) + end + alias to_backslash to_backslash_sequence + end + # def Tk.UTF8_String(str) + # Tk::UTF8_String.new(str) + # end + +end diff --git a/ext/tk/lib/tk/entry.rb b/ext/tk/lib/tk/entry.rb new file mode 100644 index 0000000000..2077c1e9e4 --- /dev/null +++ b/ext/tk/lib/tk/entry.rb @@ -0,0 +1,114 @@ +# +# tk/entry.rb - Tk entry classes +# $Date$ +# by Yukihiro Matsumoto + +require 'tk' +require 'tk/label' +require 'tk/scrollable' +require 'tk/validation' + +class TkEntry, , ] + key_tbl = [ + [ ?#, ?n, :serial ], + [ ?a, ?s, :above ], + [ ?b, ?n, :num ], + [ ?c, ?n, :count ], + [ ?d, ?s, :detail ], + [ ?f, ?b, :focus ], + [ ?h, ?n, :height ], + [ ?i, ?s, :win_hex ], + [ ?k, ?n, :keycode ], + [ ?m, ?s, :mode ], + [ ?o, ?b, :override ], + [ ?p, ?s, :place ], + [ ?s, ?x, :state ], + [ ?t, ?n, :time ], + [ ?w, ?n, :width ], + [ ?x, ?n, :x ], + [ ?y, ?n, :y ], + [ ?A, ?s, :char ], + [ ?B, ?n, :borderwidth ], + [ ?D, ?n, :wheel_delta ], + [ ?E, ?b, :send_event ], + [ ?K, ?s, :keysym ], + [ ?N, ?n, :keysym_num ], + [ ?R, ?s, :rootwin_id ], + [ ?S, ?s, :subwindow ], + [ ?T, ?n, :type ], + [ ?W, ?w, :widget ], + [ ?X, ?n, :x_root ], + [ ?Y, ?n, :y_root ], + nil + ] + + # [ , ] + proc_tbl = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?b, TkComm.method(:bool) ], + [ ?w, TkComm.method(:window) ], + + [ ?x, proc{|val| + begin + TkComm::number(val) + rescue ArgumentError + val + end + } + ], + + nil + ] + + # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys + # + # _get_subst_key() and _get_all_subst_keys() generates key-string + # which describe how to convert callback arguments to ruby objects. + # When binding parameters are given, use _get_subst_key(). + # But when no parameters are given, use _get_all_subst_keys() to + # create a Event class object as a callback parameter. + # + # scan_args() is used when doing callback. It convert arguments + # ( which are Tcl strings ) to ruby objects based on the key string + # that is generated by _get_subst_key() or _get_all_subst_keys(). + # + _setup_subst_table(key_tbl, proc_tbl); + end + + def install_bind(cmd, *args) + if args.compact.size > 0 + args = args.join(' ') + keys = Event._get_subst_key(args) + + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + id = install_cmd(cmd) + else + id = install_cmd(proc{|*arg| + TkUtil.eval_cmd(cmd, *Event.scan_args(keys, arg)) + }) + end + id + ' ' + args + else + keys, args = Event._get_all_subst_keys + + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + id = install_cmd(cmd) + else + id = install_cmd(proc{|*arg| + TkUtil.eval_cmd(cmd, Event.new(*Event.scan_args(keys, arg))) + }) + end + id + ' ' + args + end + end +end diff --git a/ext/tk/lib/tk/font.rb b/ext/tk/lib/tk/font.rb new file mode 100644 index 0000000000..b8f7f1b991 --- /dev/null +++ b/ext/tk/lib/tk/font.rb @@ -0,0 +1,1407 @@ +# +# tk/font.rb - the class to treat fonts on Ruby/Tk +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +class TkFont + include Tk + extend TkCore + + TkCommandNames = ['font'.freeze].freeze + + Tk_FontID = ["@font".freeze, "00000".taint].freeze + Tk_FontNameTBL = TkCore::INTERP.create_table + Tk_FontUseTBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ + Tk_FontNameTBL.clear + Tk_FontUseTBL.clear + } + + # set default font + case Tk::TK_VERSION + when /^4\.*/ + DEFAULT_LATIN_FONT_NAME = 'a14'.freeze + DEFAULT_KANJI_FONT_NAME = 'k14'.freeze + + when /^8\.*/ + if JAPANIZED_TK + begin + fontnames = tk_call('font', 'names') + case fontnames + when /defaultgui/ + # Tcl/Tk-JP for Windows + ltn = 'defaultgui' + knj = 'defaultgui' + when /Mincho:Helvetica-Bold-12/ + # Tcl/Tk-JP for UNIX/X + ltn, knj = tk_split_simplelist(tk_call('font', 'configure', + 'Mincho:Helvetica-Bold-12', + '-compound')) + else + # unknown Tcl/Tk-JP + platform = tk_call('set', 'tcl_platform(platform)') + case platform + when 'unix' + ltn = {'family'=>'Helvetica'.freeze, + 'size'=>-12, 'weight'=>'bold'.freeze} + #knj = 'k14' + #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0' + knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0' + when 'windows' + ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} + knj = 'mincho' + when 'macintosh' + ltn = 'system' + knj = 'mincho' + else # unknown + ltn = 'Helvetica' + knj = 'mincho' + end + end + rescue + ltn = 'Helvetica' + knj = 'mincho' + end + + else # not JAPANIZED_TK + begin + platform = tk_call('set', 'tcl_platform(platform)') + case platform + when 'unix' + ltn = {'family'=>'Helvetica'.freeze, + 'size'=>-12, 'weight'=>'bold'.freeze} + #knj = 'k14' + #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0' + knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0' + when 'windows' + ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} + knj = 'mincho' + when 'macintosh' + ltn = 'system' + knj = 'mincho' + else # unknown + ltn = 'Helvetica' + knj = 'mincho' + end + rescue + ltn = 'Helvetica' + knj = 'mincho' + end + + knj = ltn + end + + DEFAULT_LATIN_FONT_NAME = ltn.freeze + DEFAULT_KANJI_FONT_NAME = knj.freeze + + else # unknown version + DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze + DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze + + end + + if $DEBUG + print "default latin font = "; p DEFAULT_LATIN_FONT_NAME + print "default kanji font = "; p DEFAULT_KANJI_FONT_NAME + end + + + ################################### + class DescendantFont + def initialize(compound, type) + unless compound.kind_of?(TkFont) + fail ArgumentError, "a TkFont object is expected for the 1st argument" + end + @compound = compound + case type + when 'kanji', 'latin', 'ascii' + @type = type + else + fail ArgumentError, "unknown type '#{type}'" + end + end + + def dup + fail RuntimeError, "cannot dupulicate a descendant font" + end + def clone + fail RuntimeError, "cannot clone a descendant font" + end + + def to_eval + @compound.__send__(@type + '_font_id') + end + def font + @compound.__send__(@type + '_font_id') + end + + def [](slot) + @compound.__send__(@type + '_configinfo', slot) + end + def []=(slot, value) + @compound.__send__(@type + '_configure', slot, value) + value + end + + def method_missing(id, *args) + @compound.__send__(@type + '_' + id.id2name, *args) + end + end + + + ################################### + # class methods + ################################### + def TkFont.families(window=nil) + case (Tk::TK_VERSION) + when /^4\.*/ + ['fixed'] + + when /^8\.*/ + if window + tk_split_simplelist(tk_call('font', 'families', '-displayof', window)) + else + tk_split_simplelist(tk_call('font', 'families')) + end + end + end + + def TkFont.names + case (Tk::TK_VERSION) + when /^4\.*/ + r = ['fixed'] + r += ['a14', 'k14'] if JAPANIZED_TK + Tk_FontNameTBL.each_value{|obj| r.push(obj)} + r | [] + + when /^8\.*/ + tk_split_simplelist(tk_call('font', 'names')) + + end + end + + def TkFont.create_copy(font) + fail 'source-font must be a TkFont object' unless font.kind_of? TkFont + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + keys = {} + font.configinfo.each{|key,value| keys[key] = value } + TkFont.new(font.latin_font_id, font.kanji_font_id, keys) + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + TkFont.new(font.latin_font_id, font.kanji_font_id, font.configinfo) + end + end + + def TkFont.get_obj(name) + if name =~ /^(@font[0-9]+)(|c|l|k)$/ + Tk_FontNameTBL[$1] + else + nil + end + end + + def TkFont.init_widget_font(path, *args) + case (Tk::TK_VERSION) + when /^4\.*/ + conf = tk_split_simplelist(tk_call(*args)). + find_all{|prop| prop[0..5]=='-font ' || prop[0..10]=='-kanjifont '}. + collect{|prop| tk_split_simplelist(prop)} + if font_inf = conf.assoc('-font') + ltn = font_inf[4] + ltn = nil if ltn == [] + else + #ltn = nil + raise RuntimeError, "unknown option '-font'" + end + if font_inf = conf.assoc('-kanjifont') + knj = font_inf[4] + knj = nil if knj == [] + else + knj = nil + end + TkFont.new(ltn, knj).call_font_configure(path, *(args + [{}])) + + when /^8\.*/ + font_prop = tk_split_simplelist(tk_call(*args)).find{|prop| + prop[0..5] == '-font ' + } + unless font_prop + raise RuntimeError, "unknown option '-font'" + end + fnt = tk_split_simplelist(font_prop)[4] + if fnt == "" + TkFont.new(nil, nil).call_font_configure(path, *(args + [{}])) + else + begin + compound = tk_split_simplelist( + Hash[*tk_split_simplelist(tk_call('font', 'configure', + fnt))].collect{|key,value| + [key[1..-1], value] + }.assoc('compound')[1]) + rescue + compound = [] + end + if compound == [] + #TkFont.new(fnt, DEFAULT_KANJI_FONT_NAME) \ + #.call_font_configure(path, *(args + [{}])) + TkFont.new(fnt).call_font_configure(path, *(args + [{}])) + else + TkFont.new(compound[0], compound[1]) \ + .call_font_configure(path, *(args + [{}])) + end + end + end + end + + def TkFont.used_on(path=nil) + if path + Tk_FontUseTBL[path] + else + Tk_FontUseTBL.values | [] + end + end + + def TkFont.failsafe(font) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + tk_call('font', 'failsafe', font) + end + rescue + end + end + + ################################### + # instance methods + ################################### + private + ################################### + def initialize(ltn=nil, knj=nil, keys=nil) + @id = Tk_FontID.join('') + Tk_FontID[1].succ! + Tk_FontNameTBL[@id] = self + + @latin_desscendant = nil + @kanji_desscendant = nil + + if knj.kind_of?(Hash) && !keys + keys = knj + knj = nil + end + + # compound font check + if Tk::TK_VERSION == '8.0' && JAPANIZED_TK + begin + compound = tk_split_simplelist(tk_call('font', 'configure', + ltn, '-compound')) + if knj == nil + if compound != [] + ltn, knj = compound + end + else + if compound != [] + ltn = compound[0] + end + compound = tk_split_simplelist(tk_call('font', 'configure', + knj, '-compound')) + if compound != [] + knj = compound[1] + end + end + rescue + end + end + + if ltn + if JAPANIZED_TK && !knj + if Tk::TK_VERSION =~ /^4.*/ + knj = DEFAULT_KANJI_FONT_NAME + else + knj = ltn + end + end + else + ltn = DEFAULT_LATIN_FONT_NAME + knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj + end + + create_compoundfont(ltn, knj, keys) + end + + def _get_font_info_from_hash(font) + font = _symbolkey2str(font) + foundry = (info = font['foundry'] .to_s)? info: '*' + family = (info = font['family'] .to_s)? info: '*' + weight = (info = font['weight'] .to_s)? info: '*' + slant = (info = font['slant'] .to_s)? info: '*' + swidth = (info = font['swidth'] .to_s)? info: '*' + adstyle = (info = font['adstyle'] .to_s)? info: '*' + pixels = (info = font['pixels'] .to_s)? info: '*' + points = (info = font['points'] .to_s)? info: '*' + resx = (info = font['resx'] .to_s)? info: '*' + resy = (info = font['resy'] .to_s)? info: '*' + space = (info = font['space'] .to_s)? info: '*' + avgWidth = (info = font['avgWidth'].to_s)? info: '*' + charset = (info = font['charset'] .to_s)? info: '*' + encoding = (info = font['encoding'].to_s)? info: '*' + + [foundry, family, weight, slant, swidth, adstyle, + pixels, points, resx, resy, space, avgWidth, charset, encoding] + end + + def create_latinfont_tk4x(font) + if font.kind_of? Hash + @latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-' + + elsif font.kind_of? Array + finfo = {} + finfo['family'] = font[0].to_s + if font[1] + fsize = font[1].to_s + if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ + if $1 == '-' + finfo['pixels'] = $2 + else + finfo['points'] = $2 + end + else + finfo['points'] = '13' + end + end + font[2..-1].each{|style| + case (style) + when 'normal' + finfo['weight'] = style + when 'bold' + finfo['weight'] = style + when 'roman' + finfo['slant'] = 'r' + when 'italic' + finfo['slant'] = 'i' + end + } + + @latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' + + elsif font.kind_of? TkFont + @latinfont = font.latin_font + + else + if font + @latinfont = font + else + @latinfont = DEFAULT_LATIN_FONT_NAME + end + + end + end + + def create_kanjifont_tk4x(font) + unless JAPANIZED_TK + @kanjifont = "" + return + end + + if font.kind_of? Hash + @kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-' + + elsif font.kind_of? Array + finfo = {} + finfo['family'] = font[0].to_s + if font[1] + fsize = font[1].to_s + if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ + if $1 == '-' + finfo['pixels'] = $2 + else + finfo['points'] = $2 + end + else + finfo['points'] = '13' + end + end + font[2..-1].each{|style| + case (style) + when 'normal' + finfo['weight'] = style + when 'bold' + finfo['weight'] = style + when 'roman' + finfo['slant'] = 'r' + when 'italic' + finfo['slant'] = 'i' + end + } + + @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' + elsif font.kind_of? TkFont + @kanjifont = font.kanji_font_id + else + if font + @kanjifont = font + else + @kanjifont = DEFAULT_KANJI_FONT_NAME + end + end + end + + def create_compoundfont_tk4x(ltn, knj, keys) + create_latinfont(ltn) + create_kanjifont(knj) + + if JAPANIZED_TK + @compoundfont = [[@latinfont], [@kanjifont]] + @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} + else + @compoundfont = @latinfont + @fontslot = {'font'=>@latinfont} + end + end + + def create_latinfont_tk8x(font) + @latinfont = @id + 'l' + + if JAPANIZED_TK + if font.kind_of? Hash + if font[:charset] || font['charset'] + tk_call('font', 'create', @latinfont, *hash_kv(font)) + else + tk_call('font', 'create', @latinfont, + '-charset', 'iso8859', *hash_kv(font)) + end + elsif font.kind_of? Array + tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font)) + tk_call('font', 'configure', @latinfont, '-charset', 'iso8859') + elsif font.kind_of? TkFont + tk_call('font', 'create', @latinfont, '-copy', font.latin_font) + elsif font + tk_call('font', 'create', @latinfont, '-copy', font, + '-charset', 'iso8859') + else + tk_call('font', 'create', @latinfont, '-charset', 'iso8859') + end + else + if font.kind_of? Hash + tk_call('font', 'create', @latinfont, *hash_kv(font)) + else + keys = {} + if font.kind_of? Array + actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} + elsif font.kind_of? TkFont + actual_core(font.latin_font).each{|key,val| keys[key] = val} + elsif font + actual_core(font).each{|key,val| keys[key] = val} + end + tk_call('font', 'create', @latinfont, *hash_kv(keys)) + end + + if font && @compoundfont + keys = {} + actual_core(@latinfont).each{|key,val| keys[key] = val} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + end + + def create_kanjifont_tk8x(font) + @kanjifont = @id + 'k' + + if JAPANIZED_TK + if font.kind_of? Hash + if font[:charset] || font['charset'] + tk_call('font', 'create', @kanjifont, *hash_kv(font)) + else + tk_call('font', 'create', @kanjifont, + '-charset', 'jisx0208.1983', *hash_kv(font)) + end + elsif font.kind_of? Array + tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font)) + tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983') + elsif font.kind_of? TkFont + tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font_id) + elsif font + tk_call('font', 'create', @kanjifont, '-copy', font, + '-charset', 'jisx0208.1983') + else + tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') + end + # end of JAPANIZED_TK + + else + if font.kind_of? Hash + tk_call('font', 'create', @kanjifont, *hash_kv(font)) + else + keys = {} + if font.kind_of? Array + actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} + elsif font.kind_of? TkFont + actual_core(font.kanji_font_id).each{|key,val| keys[key] = val} + elsif font + actual_core(font).each{|key,val| keys[key] = val} + end + tk_call('font', 'create', @kanjifont, *hash_kv(keys)) + end + + if font && @compoundfont + keys = {} + actual_core(@kanjifont).each{|key,val| keys[key] = val} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + end + + def create_compoundfont_tk8x(ltn, knj, keys) + create_latinfont(ltn) + create_kanjifont(knj) + + @compoundfont = @id + 'c' + if JAPANIZED_TK + unless keys + keys = {} + else + keys = keys.dup + end + if (tk_call('font', 'configure', @latinfont, '-underline') == '1' && + tk_call('font', 'configure', @kanjifont, '-underline') == '1' && + !keys.key?('underline')) + keys['underline'] = true + end + if (tk_call('font', 'configure', @latinfont, '-overstrike') == '1' && + tk_call('font', 'configure', @kanjifont, '-overstrike') == '1' && + !keys.key?('overstrike')) + keys['overstrike'] = true + end + + @fontslot = {'font'=>@compoundfont} + begin + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + rescue RuntimeError => e + if ltn == knj + if e.message =~ /kanji font .* specified/ + tk_call('font', 'delete', @latinfont) + create_latinfont(DEFAULT_LATIN_FONT_NAME) + opts = [] + Hash[*(tk_split_simplelist(tk_call('font', 'configure', + @kanjifont)))].each{|k,v| + case k + when '-size', '-weight', '-slant', '-underline', '-overstrike' + opts << k << v + end + } + tk_call('font', 'configure', @latinfont, *opts) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + + elsif e.message =~ /ascii font .* specified/ + tk_call('font', 'delete', @kanjifont) + create_kanjifont(DEFAULT_KANJI_FONT_NAME) + opts = [] + Hash[*(tk_split_simplelist(tk_call('font', 'configure', + @latinfont)))].each{|k,v| + case k + when '-size', '-weight', '-slant', '-underline', '-overstrike' + opts << k << v + end + } + tk_call('font', 'configure', @kanjifont, *opts) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + + else + raise e + end + else + raise e + end + end + else + tk_call('font', 'create', @compoundfont) + + latinkeys = {} + begin + actual_core(@latinfont).each{|key,val| latinkeys[key] = val} + rescue + latinkeys {} + end + if latinkeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) + end + + if knj + kanjikeys = {} + begin + actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val} + rescue + kanjikeys {} + end + if kanjikeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys)) + end + end + + @fontslot = {'font'=>@compoundfont} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + + def actual_core_tk4x(font, window=nil, option=nil) + # dummy + if option + "" + else + [['family',[]], ['size',[]], ['weight',[]], ['slant',[]], + ['underline',[]], ['overstrike',[]], ['charset',[]], + ['pointadjust',[]]] + end + end + + def actual_core_tk8x(font, window=nil, option=nil) + if option == 'compound' + "" + elsif option + if window + tk_call('font', 'actual', font, "-displayof", window, "-#{option}") + else + tk_call('font', 'actual', font, "-#{option}") + end + else + l = tk_split_simplelist(if window + tk_call('font', 'actual', font, + "-displayof", window) + else + tk_call('font', 'actual', font) + end) + r = [] + while key=l.shift + if key == '-compound' + l.shift + else + r.push [key[1..-1], l.shift] + end + end + r + end + end + + def configure_core_tk4x(font, slot, value=None) + #"" + self + end + + def configinfo_core_tk4x(font, option=nil) + # dummy + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + if option + "" + else + [['family',[]], ['size',[]], ['weight',[]], ['slant',[]], + ['underline',[]], ['overstrike',[]], ['charset',[]], + ['pointadjust',[]]] + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + current_configinfo_core_tk4x(font, option) + end + end + + def current_configinfo_core_tk4x(font, option=nil) + if option + "" + else + {'family'=>'', 'size'=>'', 'weight'=>'', 'slant'=>'', + 'underline'=>'', 'overstrike'=>'', 'charset'=>'', 'pointadjust'=>''} + end + end + + def configure_core_tk8x(font, slot, value=None) + if JAPANIZED_TK + begin + padjust = tk_call('font', 'configure', font, '-pointadjust') + rescue + padjust = nil + end + else + padjust = nil + end + if slot.kind_of? Hash + if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family)) + slot = _symbolkey2str(slot) + configure_core_tk8x(font, 'family', slot.delete('family')) + end + + if ((slot.key?('size') || slot.key?(:size)) && + padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust)) + tk_call('font', 'configure', font, + '-pointadjust', padjust, *hash_kv(slot)) + else + tk_call('font', 'configure', font, *hash_kv(slot)) + end + elsif (slot == 'size' || slot == :size) && padjust != nil + tk_call('font', 'configure', font, + "-#{slot}", value, '-pointadjust', padjust) + elsif JAPANIZED_TK && (slot == 'family' || slot == :family) + # coumpund font? + begin + compound = tk_split_simplelist(tk_call('font', 'configure', + font, '-compound')) + rescue + tk_call('font', 'configure', font, '-family', value) + return self + end + if compound == [] + tk_call('font', 'configure', font, '-family', value) + return self + end + ltn, knj = compound + + lfnt = tk_call('font', 'create', '-copy', ltn) + begin + tk_call('font', 'configure', lfnt, '-family', value) + latin_replace_core_tk8x(lfnt) + rescue RuntimeError => e + fail e if $DEBUG + ensure + tk_call('font', 'delete', lfnt) if lfnt != '' + end + + kfnt = tk_call('font', 'create', '-copy', knj) + begin + tk_call('font', 'configure', kfnt, '-family', value) + kanji_replace_core_tk8x(lfnt) + rescue RuntimeError => e + fail e if $DEBUG + ensure + tk_call('font', 'delete', kfnt) if kfnt != '' + end + + else + tk_call('font', 'configure', font, "-#{slot}", value) + end + self + end + + def configinfo_core_tk8x(font, option=nil) + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + if option == 'compound' + "" + elsif option + tk_call('font', 'configure', font, "-#{option}") + else + l = tk_split_simplelist(tk_call('font', 'configure', font)) + r = [] + while key=l.shift + if key == '-compound' + l.shift + else + r.push [key[1..-1], l.shift] + end + end + r + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + current_configinfo_core_tk8x(font, option) + end + end + + def current_configinfo_core_tk8x(font, option=nil) + if option == 'compound' + "" + elsif option + tk_call('font', 'configure', font, "-#{option}") + else + l = tk_split_simplelist(tk_call('font', 'configure', font)) + r = {} + while key=l.shift + if key == '-compound' + l.shift + else + r[key[1..-1]] = l.shift + end + end + r + end + end + + def delete_core_tk4x + Tk_FontNameTBL.delete(@id) + Tk_FontUseTBL.delete_if{|key,value| value == self} + end + + def delete_core_tk8x + begin + tk_call('font', 'delete', @latinfont) + rescue + end + begin + tk_call('font', 'delete', @kanjifont) + rescue + end + begin + tk_call('font', 'delete', @compoundfont) + rescue + end + Tk_FontNameTBL.delete(@id) + Tk_FontUseTBL.delete_if{|key,value| value == self} + end + + def latin_replace_core_tk4x(ltn) + create_latinfont_tk4x(ltn) + @compoundfont[0] = [@latinfont] if JAPANIZED_TK + @fontslot['font'] = @latinfont + Tk_FontUseTBL.dup.each{|w, fobj| + if self == fobj + begin + if w.include?(';') + win, tag = w.split(';') + winobj = tk_tcl2ruby(win) +# winobj.tagfont_configure(tag, {'font'=>@latinfont}) + if winobj.kind_of? TkText + tk_call(win, 'tag', 'configure', tag, '-font', @latinfont) + elsif winobj.kind_of? TkCanvas + tk_call(win, 'itemconfigure', tag, '-font', @latinfont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, '-font', @latinfont) + else + raise RuntimeError, "unknown widget type" + end + else +# tk_tcl2ruby(w).font_configure('font'=>@latinfont) + tk_call(w, 'configure', '-font', @latinfont) + end + rescue + Tk_FontUseTBL.delete(w) + end + end + } + self + end + + def kanji_replace_core_tk4x(knj) + return self unless JAPANIZED_TK + + create_kanjifont_tk4x(knj) + @compoundfont[1] = [@kanjifont] + @fontslot['kanjifont'] = @kanjifont + Tk_FontUseTBL.dup.each{|w, fobj| + if self == fobj + begin + if w.include?(';') + win, tag = w.split(';') + winobj = tk_tcl2ruby(win) +# winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont}) + if winobj.kind_of? TkText + tk_call(win, 'tag', 'configure', tag, '-kanjifont', @kanjifont) + elsif winobj.kind_of? TkCanvas + tk_call(win, 'itemconfigure', tag, '-kanjifont', @kanjifont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, '-kanjifont', @latinfont) + else + raise RuntimeError, "unknown widget type" + end + else +# tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont) + tk_call(w, 'configure', '-kanjifont', @kanjifont) + end + rescue + Tk_FontUseTBL.delete(w) + end + end + } + self + end + + def latin_replace_core_tk8x(ltn) + if JAPANIZED_TK + begin + tk_call('font', 'delete', '@font_tmp') + rescue + end + begin + fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont) + rescue + #fnt_bup = '' + fnt_bup = DEFAULT_LATIN_FONT_NAME + end + end + + begin + tk_call('font', 'delete', @latinfont) + rescue + end + create_latinfont(ltn) + + if JAPANIZED_TK + keys = self.configinfo + tk_call('font', 'delete', @compoundfont) + begin + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) +=begin + latinkeys = {} + begin + actual_core(@latinfont).each{|key,val| latinkeys[key] = val} + rescue + latinkeys {} + end + if latinkeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) + end +=end + rescue RuntimeError => e + tk_call('font', 'delete', @latinfont) + if fnt_bup && fnt_bup != '' + tk_call('font', 'create', @latinfont, '-copy', fnt_bup) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + tk_call('font', 'delete', fnt_bup) + else + fail e + end + end + + else + latinkeys = {} + begin + actual_core(@latinfont).each{|key,val| latinkeys[key] = val} + rescue + latinkeys {} + end + if latinkeys != {} + tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) + end + end + self + end + + def kanji_replace_core_tk8x(knj) + if JAPANIZED_TK + begin + tk_call('font', 'delete', '@font_tmp') + rescue + end + begin + fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont) + rescue + #fnt_bup = '' + fnt_bup = DEFAULT_KANJI_FONT_NAME + end + end + + begin + tk_call('font', 'delete', @kanjifont) + rescue + end + create_kanjifont(knj) + + if JAPANIZED_TK + keys = self.configinfo + tk_call('font', 'delete', @compoundfont) + begin + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + rescue RuntimeError => e + tk_call('font', 'delete', @kanjifont) + if fnt_bup && fnt_bup != '' + tk_call('font', 'create', @kanjifont, '-copy', fnt_bup) + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) + tk_call('font', 'delete', fnt_bup) + else + fail e + end + end + end + self + end + + def measure_core_tk4x(window, text) + 0 + end + + def measure_core_tk8x(window, text) + if window + number(tk_call('font', 'measure', @compoundfont, + '-displayof', window, text)) + else + number(tk_call('font', 'measure', @compoundfont, text)) + end + end + + def metrics_core_tk4x(font, window, option=nil) + # dummy + if option + "" + else + [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]] + end + end + + def metrics_core_tk8x(font, window, option=nil) + if option + if window + number(tk_call('font', 'metrics', font, + "-displayof", window, "-#{option}")) + else + number(tk_call('font', 'metrics', font, "-#{option}")) + end + else + l = tk_split_list(if window + tk_call('font','metrics',font,"-displayof",window) + else + tk_call('font','metrics',font) + end) + r = [] + while key=l.shift + r.push [key[1..-1], l.shift.to_i] + end + r + end + end + + ################################### + # private alias + ################################### + case (Tk::TK_VERSION) + when /^4\.*/ + alias create_latinfont create_latinfont_tk4x + alias create_kanjifont create_kanjifont_tk4x + alias create_compoundfont create_compoundfont_tk4x + alias actual_core actual_core_tk4x + alias configure_core configure_core_tk4x + alias configinfo_core configinfo_core_tk4x + alias current_configinfo_core current_configinfo_core_tk4x + alias delete_core delete_core_tk4x + alias latin_replace_core latin_replace_core_tk4x + alias kanji_replace_core kanji_replace_core_tk4x + alias measure_core measure_core_tk4x + alias metrics_core metrics_core_tk4x + + when /^8\.[0-5]/ + alias create_latinfont create_latinfont_tk8x + alias create_kanjifont create_kanjifont_tk8x + alias create_compoundfont create_compoundfont_tk8x + alias actual_core actual_core_tk8x + alias configure_core configure_core_tk8x + alias configinfo_core configinfo_core_tk8x + alias current_configinfo_core current_configinfo_core_tk8x + alias delete_core delete_core_tk8x + alias latin_replace_core latin_replace_core_tk8x + alias kanji_replace_core kanji_replace_core_tk8x + alias measure_core measure_core_tk8x + alias metrics_core metrics_core_tk8x + + else + alias create_latinfont create_latinfont_tk8x + alias create_kanjifont create_kanjifont_tk8x + alias create_compoundfont create_compoundfont_tk8x + alias actual_core actual_core_tk8x + alias configure_core configure_core_tk8x + alias configinfo_core configinfo_core_tk8x + alias current_configinfo_core current_configinfo_core_tk8x + alias delete_core delete_core_tk8x + alias latin_replace_core latin_replace_core_tk8x + alias kanji_replace_core kanji_replace_core_tk8x + alias measure_core measure_core_tk8x + alias metrics_core metrics_core_tk8x + + end + + ################################### + public + ################################### + def method_missing(id, *args) + name = id.id2name + case args.length + when 1 + configure name, args[0] + when 0 + begin + configinfo name + rescue + fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at + end + else + fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + end + end + + def call_font_configure(path, *args) + keys = args.pop.update(@fontslot) + args.concat(hash_kv(keys)) + tk_call(*args) + Tk_FontUseTBL[path] = self + self + end + + def used + ret = [] + Tk_FontUseTBL.each{|key,value| + if key.include?(';') + win, tag = key.split(';') + winobj = tk_tcl2ruby(win) + if winobj.kind_of? TkText + ret.push([winobj, winobj.tagid2obj(tag)]) + elsif winobj.kind_of? TkCanvas + if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag + ret.push([winobj, tagobj]) + elsif (tagobj = TkcItem.id2obj(tag)).kind_of? TkcItem + ret.push([winobj, tagobj]) + else + ret.push([winobj, tag]) + end + elsif winobj.kind_of? TkMenu + ret.push([winobj, tag]) + else + ret.push([win, tag]) + end + else + ret.push(tk_tcl2ruby(key)) if value == self + end + } + ret + end + + def id + @id + end + + def to_eval + font + end + + def font + @compoundfont + end + alias font_id font + + def latin_font_id + @latinfont + end + + def latin_font + # @latinfont + if @latin_descendant + @latin_descendant + else + @latin_descendant = DescendantFont.new(self, 'latin') + end + end + alias latinfont latin_font + + def kanji_font_id + @kanjifont + end + + def kanji_font + # @kanjifont + if @kanji_descendant + @kanji_descendant + else + @kanji_descendant = DescendantFont.new(self, 'kanji') + end + end + alias kanjifont kanji_font + + def actual(option=nil) + actual_core(@compoundfont, nil, option) + end + + def actual_displayof(window, option=nil) + window = '.' unless window + actual_core(@compoundfont, window, option) + end + + def latin_actual(option=nil) + actual_core(@latinfont, nil, option) + end + + def latin_actual_displayof(window, option=nil) + window = '.' unless window + actual_core(@latinfont, window, option) + end + + def kanji_actual(option=nil) + #if JAPANIZED_TK + if @kanjifont != "" + actual_core(@kanjifont, nil, option) + else + actual_core_tk4x(nil, nil, option) + end + end + + def kanji_actual_displayof(window, option=nil) + #if JAPANIZED_TK + if @kanjifont != "" + window = '.' unless window + actual_core(@kanjifont, window, option) + else + actual_core_tk4x(nil, window, option) + end + end + + def [](slot) + configinfo slot + end + + def []=(slot, val) + configure slot, val + val + end + + def configure(slot, value=None) + configure_core(@compoundfont, slot, value) + self + end + + def configinfo(slot=nil) + configinfo_core(@compoundfont, slot) + end + + def current_configinfo(slot=nil) + current_configinfo_core(@compoundfont, slot) + end + + def delete + delete_core + end + + def latin_configure(slot, value=None) + if JAPANIZED_TK + configure_core(@latinfont, slot, value) + else + configure(slot, value) + end + self + end + + def latin_configinfo(slot=nil) + if JAPANIZED_TK + configinfo_core(@latinfont, slot) + else + configinfo(slot) + end + end + + def kanji_configure(slot, value=None) + #if JAPANIZED_TK + if @kanjifont != "" + configure_core(@kanjifont, slot, value) + configure('size'=>configinfo('size')) # to reflect new configuration + else + #"" + configure(slot, value) + end + self + end + + def kanji_configinfo(slot=nil) + #if JAPANIZED_TK + if @kanjifont != "" + configinfo_core(@kanjifont, slot) + else + #[] + configinfo(slot) + end + end + + def replace(ltn, knj) + latin_replace(ltn) + kanji_replace(knj) + self + end + + def latin_replace(ltn) + latin_replace_core(ltn) + reset_pointadjust + self + end + + def kanji_replace(knj) + kanji_replace_core(knj) + reset_pointadjust + self + end + + def measure(text) + measure_core(nil, text) + end + + def measure_displayof(window, text) + window = '.' unless window + measure_core(window, text) + end + + def metrics(option=nil) + metrics_core(@compoundfont, nil, option) + end + + def metrics_displayof(window, option=nil) + window = '.' unless window + metrics_core(@compoundfont, window, option) + end + + def latin_metrics(option=nil) + metrics_core(@latinfont, nil, option) + end + + def latin_metrics_displayof(window, option=nil) + window = '.' unless window + metrics_core(@latinfont, window, option) + end + + def kanji_metrics(option=nil) + if JAPANIZED_TK + metrics_core(@kanjifont, nil, option) + else + metrics_core_tk4x(nil, nil, option) + end + end + + def kanji_metrics_displayof(window, option=nil) + if JAPANIZED_TK + window = '.' unless window + metrics_core(@kanjifont, window, option) + else + metrics_core_tk4x(nil, window, option) + end + end + + def reset_pointadjust + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + configure('pointadjust' => latin_actual.assoc('size')[1].to_f / + kanji_actual.assoc('size')[1].to_f ) + end + rescue + end + self + end + + ################################### + # public alias + ################################### + alias ascii_font latin_font + alias asciifont latinfont + alias create_asciifont create_latinfont + alias ascii_actual latin_actual + alias ascii_actual_displayof latin_actual_displayof + alias ascii_configure latin_configure + alias ascii_configinfo latin_configinfo + alias ascii_replace latin_replace + alias ascii_metrics latin_metrics + + ################################### + def dup + src = self + obj = super() + obj.instance_eval{ initialize(src) } + obj + end + def clone + src = self + obj = super() + obj.instance_eval{ initialize(src) } + obj + end +end diff --git a/ext/tk/lib/tk/frame.rb b/ext/tk/lib/tk/frame.rb new file mode 100644 index 0000000000..6598ceb55c --- /dev/null +++ b/ext/tk/lib/tk/frame.rb @@ -0,0 +1,123 @@ +# +# tk/frame.rb : treat frame widget +# +require 'tk' + +class TkFrameparent} + end + end + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + @classname = keys['class'] + @colormap = keys['colormap'] + @container = keys['container'] + @visual = keys['visual'] + if !@classname && my_class_name + keys['class'] = @classname = my_class_name + end + if @classname.kind_of? TkBindTag + @db_class = @classname + @classname = @classname.id + elsif @classname + @db_class = TkDatabaseClass.new(@classname) + else + @db_class = self.class + @classname = @db_class::WidgetClassName + end + super(keys) + end + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('frame', @path, *hash_kv(keys)) + else + tk_call_without_enc( 'frame', @path) + end + end + private :create_self + + def database_classname + @classname + end + + def self.database_class + if self == WidgetClassNames[WidgetClassName] || self.name == '' + self + else + TkDatabaseClass.new(self.name) + end + end + def self.database_classname + self.database_class.name + end + + def self.bind(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bind(*args) + end + end + def self.bind_append(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bind_append(*args) + end + end + def self.bind_remove(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bind_remove(*args) + end + end + def self.bindinfo(*args) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args) + else + TkDatabaseClass.new(self.name).bindinfo(*args) + end + end +end diff --git a/ext/tk/lib/tk/grid.rb b/ext/tk/lib/tk/grid.rb new file mode 100644 index 0000000000..1516aef4bf --- /dev/null +++ b/ext/tk/lib/tk/grid.rb @@ -0,0 +1,182 @@ +# +# tk/grid.rb : control grid geometry manager +# +require 'tk' + +module TkGrid + include Tk + extend Tk + + TkCommandNames = ['grid'.freeze].freeze + + def anchor(master, anchor=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + tk_call_without_enc('grid', 'anchor', master, anchor) + end + + def bbox(master, *args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + args.unshift(master) + list(tk_call_without_enc('grid', 'bbox', *args)) + end + + def configure(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + params.push(_epath(win)) + args.each{|win| + case win + when '-', 'x', '^' # RELATIVE PLACEMENT + params.push(win) + else + params.push(_epath(win)) + end + } + opts.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc("grid", 'configure', *params) + end + + def columnconfigure(master, index, args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + tk_call_without_enc("grid", 'columnconfigure', + master, index, *hash_kv(args)) + end + + def rowconfigure(master, index, args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + tk_call_without_enc("grid", 'rowconfigure', master, index, *hash_kv(args)) + end + + def columnconfiginfo(master, index, slot=nil) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if slot + num_or_str(tk_call_without_enc('grid', 'columnconfigure', + master, index, "-#{slot}")) + else + ilist = list(tk_call_without_enc('grid','columnconfigure',master,index)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + info + end + end + + def rowconfiginfo(master, index, slot=nil) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if slot + num_or_str(tk_call_without_enc('grid', 'rowconfigure', + master, index, "-#{slot}")) + else + ilist = list(tk_call_without_enc('grid', 'rowconfigure', master, index)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + info + end + end + + def add(widget, *args) + configure(widget, *args) + end + + def forget(*args) + return '' if args.size == 0 + wins = args.collect{|win| + # (win.kind_of?(TkObject))? win.epath: win + _epath(win) + } + tk_call_without_enc('grid', 'forget', *wins) + end + + def info(slave) + # slave = slave.epath if slave.kind_of?(TkObject) + slave = _epath(slave) + ilist = list(tk_call_without_enc('grid', 'info', slave)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + return info + end + + def location(master, x, y) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('grid', 'location', master, x, y)) + end + + def propagate(master, bool=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if bool == None + bool(tk_call_without_enc('grid', 'propagate', master)) + else + tk_call_without_enc('grid', 'propagate', master, bool) + end + end + + def remove(*args) + return '' if args.size == 0 + wins = args.collect{|win| + # (win.kind_of?(TkObject))? win.epath: win + _epath(win) + } + tk_call_without_enc('grid', 'remove', *wins) + end + + def size(master) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('grid', 'size', master)) + end + + def slaves(master, args) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('grid', 'slaves', master, *hash_kv(args))) + end + + module_function :bbox, :forget, :propagate, :info + module_function :remove, :size, :slaves, :location + module_function :configure, :columnconfigure, :rowconfigure + module_function :columnconfiginfo, :rowconfiginfo +end +=begin +def TkGrid(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + params.push((win.kind_of?(TkObject))? win.epath: win) + args.each{|win| + case win + when '-', 'x', '^' # RELATIVE PLACEMENT + params.push(win) + else + params.push((win.kind_of?(TkObject))? win.epath: win) + end + } + opts.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc("grid", *params) +end +=end diff --git a/ext/tk/lib/tk/image.rb b/ext/tk/lib/tk/image.rb new file mode 100644 index 0000000000..70dd096434 --- /dev/null +++ b/ext/tk/lib/tk/image.rb @@ -0,0 +1,185 @@ +# +# tk/image.rb : treat Tk image objects +# + +require 'tk' + +class TkImageval}) + end + else + tk_call('itemconfigure', index, "-#{key}", val) + end + end + self + end + + def itemconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', index))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(index, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure',index,"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', index))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(index, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_itemconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = itemconfiginfo(index, key) + {conf[0] => conf[4]} + else + ret = {} + itemconfiginfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + itemconfiginfo(index, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +end diff --git a/ext/tk/lib/tk/macpkg.rb b/ext/tk/lib/tk/macpkg.rb new file mode 100644 index 0000000000..d67a19745b --- /dev/null +++ b/ext/tk/lib/tk/macpkg.rb @@ -0,0 +1,68 @@ +# +# tk/macpkg.rb : methods for Tcl/Tk packages for Macintosh +# 2000/11/22 by Hidetoshi Nagai +# +# ATTENTION !! +# This is NOT TESTED. Because I have no test-environment. +# +# +require 'tk' + +module Tk + def Tk.load_tclscript_rsrc(resource_name, file=None) + # Mac only + tk_call('source', '-rsrc', resource_name, file) + end + + def Tk.load_tclscript_rsrcid(resource_id, file=None) + # Mac only + tk_call('source', '-rsrcid', resource_id, file) + end +end + +module TkMacResource + extend Tk + extend TkMacResource + + TkCommandNames = ['resource'.freeze].freeze + + tk_call_without_enc('package', 'require', 'resource') + + def close(rsrcRef) + tk_call('resource', 'close', rsrcRef) + end + + def delete(rsrcType, opts=nil) + tk_call('resource', 'delete', *(hash_kv(opts) << rsrcType)) + end + + def files(rsrcRef=nil) + if rsrcRef + tk_call('resource', 'files', rsrcRef) + else + tk_split_simplelist(tk_call('resource', 'files')) + end + end + + def list(rsrcType, rsrcRef=nil) + tk_split_simplelist(tk_call('resource', 'list', rsrcType, rsrcRef)) + end + + def open(fname, access=nil) + tk_call('resource', 'open', fname, access) + end + + def read(rsrcType, rsrcID, rsrcRef=nil) + tk_call('resource', 'read', rsrcType, rsrcID, rsrcRef) + end + + def types(rsrcRef=nil) + tk_split_simplelist(tk_call('resource', 'types', rsrcRef)) + end + + def write(rsrcType, data, opts=nil) + tk_call('resource', 'write', *(hash_kv(opts) << rsrcType << data)) + end + + module_function :close, :delete, :files, :list, :open, :read, :types, :write +end diff --git a/ext/tk/lib/tk/menu.rb b/ext/tk/lib/tk/menu.rb new file mode 100644 index 0000000000..9c34741b1b --- /dev/null +++ b/ext/tk/lib/tk/menu.rb @@ -0,0 +1,460 @@ +# +# tk/menu.rb : treat menu and menubutton +# +require 'tk' + +module TkTreatMenuEntryFont + include TkTreatItemFont + + ItemCMD = ['entryconfigure'.freeze, TkComm::None].freeze + def __conf_cmd(idx) + ItemCMD[idx] + end + + def __item_pathname(tagOrId) + self.path + ';' + tagOrId.to_s + end + + private :__conf_cmd, :__item_pathname +end + +class TkMenuval}) + end + else + tk_call('entryconfigure', index, "-#{key}", val) + end + end + self + end + + def entryconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(index, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + conf[4] = tagfont_configinfo(index, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(index, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_entryconfiginfo(index, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = entryconfiginfo(index, key) + {conf[0] => conf[4]} + else + ret = {} + entryconfiginfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + entryconfiginfo(index, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +end + + +class TkMenuClone return value of tk_optionMenu + @path = path + #TkComm::Tk_WINDOWS[@path] = self + TkCore::INTERP.tk_windows[@path] = self + end + end + + def initialize(parent=nil, var=TkVariable.new, firstval=nil, *vals) + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys['parent'] + var = keys['variable'] if keys['variable'] + firstval, *vals = keys['values'] + end + fail 'variable option must be TkVariable' unless var.kind_of? TkVariable + @variable = var + firstval = @variable.value unless firstval + @variable.value = firstval + install_win(if parent then parent.path end) + @menu = OptionMenu.new(tk_call('tk_optionMenu', @path, @variable.id, + firstval, *vals)) + end + + def value + @variable.value + end + + def activate(index) + @menu.activate(index) + self + end + def add(value) + @menu.add('radiobutton', 'variable'=>@variable, + 'label'=>value, 'value'=>value) + self + end + def index(index) + @menu.index(index) + end + def invoke(index) + @menu.invoke(index) + end + def insert(index, value) + @menu.add(index, 'radiobutton', 'variable'=>@variable, + 'label'=>value, 'value'=>value) + self + end + def delete(index, last=None) + @menu.delete(index, last) + self + end + def yposition(index) + @menu.yposition(index) + end + def menu + @menu + end + def menucget(key) + @menu.cget(key) + end + def menuconfigure(key, val=None) + @menu.configure(key, val) + self + end + def menuconfiginfo(key=nil) + @menu.configinfo(key) + end + def current_menuconfiginfo(key=nil) + @menu.current_configinfo(key) + end + def entrycget(index, key) + @menu.entrycget(index, key) + end + def entryconfigure(index, key, val=None) + @menu.entryconfigure(index, key, val) + self + end + def entryconfiginfo(index, key=nil) + @menu.entryconfiginfo(index, key) + end + def current_entryconfiginfo(index, key=nil) + @menu.current_entryconfiginfo(index, key) + end +end diff --git a/ext/tk/lib/tk/menubar.rb b/ext/tk/lib/tk/menubar.rb new file mode 100644 index 0000000000..2c2846e9b6 --- /dev/null +++ b/ext/tk/lib/tk/menubar.rb @@ -0,0 +1,144 @@ +# +# tk/menubar.rb +# +# Copyright (C) 1998 maeda shugo. All rights reserved. +# This file can be distributed under the terms of the Ruby. + +# Usage: +# +# menu_spec = [ +# [['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]], +# [['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]] +# ] +# menubar = TkMenubar.new(nil, menu_spec, +# 'tearoff'=>false, +# 'foreground'=>'grey40', +# 'activeforeground'=>'red', +# 'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') +# +# +# OR +# +# +# menubar = TkMenubar.new +# menubar.add_menu([['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]]) +# menubar.add_menu([['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]]) +# menubar.configure('tearoff', false) +# menubar.configure('foreground', 'grey40') +# menubar.configure('activeforeground', 'red') +# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') + +# The format of the menu_spec is: +# [ +# [ +# [button text, underline, accelerator], +# [menu label, command, underline, accelerator], +# '---', # separator +# ... +# ], +# ... +# ] + +# underline and accelerator are optional parameters. +# Hashes are OK instead of Arrays. + +# To use add_menu, configuration must be done by calling configure after +# adding all menus by add_menu, not by the constructor arguments. + +require 'tk' +require 'tk/frame' + +class TkMenubar item_info) + end + end + + mbtn.menu(menu) + @menus.push([mbtn, menu]) + delegate('tearoff', menu) + delegate('foreground', mbtn, menu) + delegate('background', mbtn, menu) + delegate('disabledforeground', mbtn, menu) + delegate('activeforeground', mbtn, menu) + delegate('activebackground', mbtn, menu) + delegate('font', mbtn, menu) + delegate('kanjifont', mbtn, menu) + mbtn.pack('side' => 'left') + end + + def [](index) + return @menus[index] + end +end diff --git a/ext/tk/lib/tk/message.rb b/ext/tk/lib/tk/message.rb new file mode 100644 index 0000000000..b359800142 --- /dev/null +++ b/ext/tk/lib/tk/message.rb @@ -0,0 +1,19 @@ +# +# tk/message.rb : treat message widget +# +require 'tk' +require 'tk/label' + +class TkMessage +# +require 'tk' + +module TkManageFocus + extend Tk + + TkCommandNames = [ + 'tk_focusFollowMouse'.freeze, + 'tk_focusNext'.freeze, + 'tk_focusPrev'.freeze + ].freeze + + def TkManageFocus.followsMouse + tk_call_without_enc('tk_focusFollowsMouse') + end + + def TkManageFocus.next(window) + tk_tcl2ruby(tk_call('tk_focusNext', window)) + end + def focusNext + TkManageFocus.next(self) + end + + def TkManageFocus.prev(window) + tk_tcl2ruby(tk_call('tk_focusPrev', window)) + end + def focusPrev + TkManageFocus.prev(self) + end +end diff --git a/ext/tk/lib/tk/msgcat.rb b/ext/tk/lib/tk/msgcat.rb new file mode 100644 index 0000000000..6c46542faf --- /dev/null +++ b/ext/tk/lib/tk/msgcat.rb @@ -0,0 +1,268 @@ +# +# tk/msgcat.rb : methods for Tcl message catalog +# by Hidetoshi Nagai +# +require 'tk' + +#class TkMsgCatalog +class TkMsgCatalog < TkObject + include TkCore + extend Tk + #extend TkMsgCatalog + + TkCommandNames = [ + '::msgcat::mc'.freeze, + '::msgcat::mcmax'.freeze, + '::msgcat::mclocale'.freeze, + '::msgcat::mcpreferences'.freeze, + '::msgcat::mcload'.freeze, + '::msgcat::mcset'.freeze, + '::msgcat::mcmset'.freeze, + '::msgcat::mcunknown'.freeze + ].freeze + + tk_call_without_enc('package', 'require', 'Tcl', '8.2') + + if self.const_defined? :FORCE_VERSION + tk_call_without_enc('package', 'require', 'msgcat', FORCE_VERSION) + else + tk_call_without_enc('package', 'require', 'msgcat') + end + + MSGCAT_EXT = '.msg' + + UNKNOWN_CBTBL = Hash.new{|hash,key| hash[key] = {}}.taint + + TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL') + if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} { + #return -code $st $ret + set idx [string first "\n\n" $ret] + if {$idx > 0} { + return -code $st \ + -errorinfo [string range $ret [expr $idx + 2] \ + [string length $ret]] \ + [string range $ret 0 [expr $idx - 1]] + } else { + return -code $st $ret + } + } else { + return $ret + } + EOL + + def self.callback(namespace, locale, src_str) + cmd_tbl = TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip] + cmd = cmd_tbl[namespace] + cmd = cmd_tbl['::'] unless cmd # use global scope as interp default + return src_str unless cmd # no cmd -> return src-str (default action) + begin + cmd.call(locale, src_str) + rescue Exception => e + begin + msg = _toUTF8(e.class.inspect) + ': ' + + _toUTF8(e.message) + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + _toUTF8(e.backtrace.join("\n")) + + "\n---< backtrace of Tk side >-------" + msg.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + msg = e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------" + end + fail(e, msg) + end + end + + def initialize(namespace = nil) + if namespace.kind_of?(TkNamespace) + @namespace = namespace + elsif namespace == nil + @namespace = TkNamespace.new('::') # global namespace + else + @namespace = TkNamespace.new(namespace) + end + @path = @namespace.path + + @msgcat_ext = '.msg' + end + attr_accessor :msgcat_ext + + def method_missing(id, *args) + # locale(src, trans) ==> set_translation(locale, src, trans) + loc = id.id2name + case args.length + when 0 # set locale + self.locale=(loc) + + when 1 # src only, or trans_list + if args[0].kind_of?(Array) + # trans_list + #list = args[0].collect{|src, trans| + # [ Tk::UTF8_String.new(src), Tk::UTF8_String.new(trans) ] + #} + self.set_translation_list(loc, args[0]) + else + # src + #self.set_translation(loc, Tk::UTF8_String.new(args[0])) + self.set_translation(loc, args[0]) + end + + when 2 # src and trans, or, trans_list and enc + if args[0].kind_of?(Array) + else + #self.set_translation(loc, args[0], Tk::UTF8_String.new(args[1])) + self.set_translation(loc, *args) + end + + when 3 # src and trans and enc + self.set_translation(loc, *args) + + else + fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + + end + end + + # *args ::= form, arg, arg, ... + def self.translate(*args) + dst = args.collect{|src| + tk_call_without_enc('::msgcat::mc', _get_eval_string(src, true)) + } + Tk.UTF8_String(sprintf(*dst)) + end + class << self + alias mc translate + alias [] translate + end + def translate(*args) + dst = args.collect{|src| + @namespace.eval{tk_call_without_enc('::msgcat::mc', + _get_eval_string(src, true))} + } + Tk.UTF8_String(sprintf(*dst)) + end + alias mc translate + alias [] translate + + def self.maxlen(*src_strings) + tk_call('::msgcat::mcmax', *src_strings).to_i + end + def maxlen(*src_strings) + @namespace.eval{tk_call('::msgcat::mcmax', *src_strings).to_i} + end + + def self.locale + tk_call('::msgcat::mclocale') + end + def locale + @namespace.eval{tk_call('::msgcat::mclocale')} + end + + def self.locale=(locale) + tk_call('::msgcat::mclocale', locale) + end + def locale=(locale) + @namespace.eval{tk_call('::msgcat::mclocale', locale)} + end + + def self.preferences + tk_split_simplelist(tk_call('::msgcat::mcpreferences')) + end + def preferences + tk_split_simplelist(@namespace.eval{tk_call('::msgcat::mcpreferences')}) + end + + def self.load_tk(dir) + number(tk_call('::msgcat::mcload', dir)) + end + + def self.load_rb(dir) + count = 0 + preferences().each{|loc| + file = File.join(dir, loc + self::MSGCAT_EXT) + if File.readable?(file) + count += 1 + eval(open(file){|f| f.read}) + end + } + count + end + + def load_tk(dir) + number(@namespace.eval{tk_call('::msgcat::mcload', dir)}) + end + + def load_rb(dir) + count = 0 + preferences().each{|loc| + file = File.join(dir, loc + @msgcat_ext) + if File.readable?(file) + count += 1 + @namespace.eval(open(file){|f| f.read}) + end + } + count + end + + def self.load(dir) + self.load_rb(dir) + end + alias load load_rb + + def self.set_translation(locale, src_str, trans_str=None, enc='utf-8') + trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) if trans_str != None + Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true), + trans_str)) + end + def set_translation(locale, src_str, trans_str=None, enc='utf-8') + trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) if trans_str != None + Tk.UTF8_String(@namespace.eval{ + tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true), + trans_str) + }) + end + + def self.set_translation_list(locale, trans_list, enc='utf-8') + # trans_list ::= [ [src, trans], [src, trans], ... ] + list = [] + trans_list.each{|src, trans| + if trans && trans != None + list << _get_eval_string(src, true) + list << Tk.UTF8_Stirng(_toUTF8(trans, enc)) + else + list << _get_eval_string(src, true) << '' + end + } + number(tk_call_without_enc('::msgcat::mcmset', locale, list)) + end + def set_translation_list(locale, trans_list, enc='utf-8') + # trans_list ::= [ [src, trans], [src, trans], ... ] + list = [] + trans_list.each{|src, trans| + if trans && trans != None + list << _get_eval_string(src, true) + list << Tk.UTF8_String(_toUTF8(trans, enc)) + else + list << _get_eval_string(src, true) << '' + end + } + number(@namespace.eval{ + tk_call_without_enc('::msgcat::mcmset', locale, list) + }) + end + + def self.def_unknown_proc(cmd=Proc.new) + TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip]['::'] = cmd + end + def def_unknown_proc(cmd=Proc.new) + TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip][@namespace.path] = cmd + end +end + +TkMsgCat = TkMsgCatalog diff --git a/ext/tk/lib/tk/namespace.rb b/ext/tk/lib/tk/namespace.rb new file mode 100644 index 0000000000..72e9500a49 --- /dev/null +++ b/ext/tk/lib/tk/namespace.rb @@ -0,0 +1,293 @@ +# +# tk/namespace.rb : methods to manipulate Tcl/Tk namespace +# by Hidetoshi Nagai +# +require 'tk' + +class TkNamespace < TkObject + extend Tk + + TkCommandNames = [ + 'namespace'.freeze, + ].freeze + + Tk_Namespace_ID_TBL = TkCore::INTERP.create_table + Tk_Namespace_ID = ["ns".freeze, "00000".taint].freeze + + class ScopeArgs < Array + include Tk + + # alias __tk_call tk_call + # alias __tk_call_without_enc tk_call_without_enc + # alias __tk_call_with_enc tk_call_with_enc + def tk_call(*args) + #super('namespace', 'eval', @namespace, *args) + args = args.collect{|arg| (s = _get_eval_string(arg))? s: ''} + super('namespace', 'eval', @namespace, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_without_enc(*args) + #super('namespace', 'eval', @namespace, *args) + args = args.collect{|arg| (s = _get_eval_string(arg))? s: ''} + super('namespace', 'eval', @namespace, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_with_enc(*args) + #super('namespace', 'eval', @namespace, *args) + args = args.collect{|arg| (s = _get_eval_string(arg))? s: ''} + super('namespace', 'eval', @namespace, + TkCore::INTERP._merge_tklist(*args)) + end + + def initialize(namespace, *args) + @namespace = namespace + super(args.size) + self.replace(args) + end + end + + class NsCode < TkObject + def initialize(scope) + @scope = scope + ' ' + end + def path + @scope + end + def to_eval + @scope + end + def call(*args) + TkCore::INTERP._eval_without_enc(@scope + array2tk_list(args)) + end + end + + alias __tk_call tk_call + alias __tk_call_without_enc tk_call_without_enc + alias __tk_call_with_enc tk_call_with_enc + def tk_call(*args) + #super('namespace', 'eval', @fullname, *args) + args = args.collect{|arg| (s = _get_eval_string(arg))? s: ''} + super('namespace', 'eval', @fullname, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_without_enc(*args) + #super('namespace', 'eval', @fullname, *args) + args = args.collect{|arg| (s = _get_eval_string(arg))? s: ''} + super('namespace', 'eval', @fullname, + TkCore::INTERP._merge_tklist(*args)) + end + def tk_call_with_enc(*args) + #super('namespace', 'eval', @fullname, *args) + args = args.collect{|arg| (s = _get_eval_string(arg))? s: ''} + super('namespace', 'eval', @fullname, + TkCore::INTERP._merge_tklist(*args)) + end + alias ns_tk_call tk_call + alias ns_tk_call_without_enc tk_call_without_enc + alias ns_tk_call_with_enc tk_call_with_enc + + def initialize(name = nil, parent = nil) + unless name + name = Tk_Namespace_ID.join('') + Tk_Namespace_ID[1].succ! + end + name = __tk_call('namespace', 'current') if name == '' + if parent + if parent =~ /^::/ + if name =~ /^::/ + @fullname = parent + name + else + @fullname = parent +'::'+ name + end + else + ancestor = __tk_call('namespace', 'current') + ancestor = '' if ancestor == '::' + if name =~ /^::/ + @fullname = ancestor + '::' + parent + name + else + @fullname = ancestor + '::'+ parent +'::'+ name + end + end + else # parent == nil + ancestor = __tk_call('namespace', 'current') + ancestor = '' if ancestor == '::' + if name =~ /^::/ + @fullname = name + else + @fullname = ancestor + '::' + name + end + end + @path = @fullname + @parent = __tk_call('namespace', 'qualifiers', @fullname) + @name = __tk_call('namespace', 'tail', @fullname) + + # create namespace + __tk_call('namespace', 'eval', @fullname, '') + + Tk_Namespace_ID_TBL[@fullname] = self + end + + def self.children(*args) + # args ::= [] [] + # must be glob-style pattern + tk_split_simplelist(tk_call('namespace', 'children', *args)).collect{|ns| + # ns is fullname + if Tk_Namesapce_ID.key?(ns) + Tk_Namesapce_ID[ns] + else + ns + end + } + end + def children(pattern=None) + TkNamespace.children(@fullname, pattern) + end + + def self.code(script = Proc.new) + TkNamespace.new('').code(script) + end + def code(script = Proc.new) + if script.kind_of?(String) + cmd = proc{|*args| ScopeArgs.new(@fullname,*args).instance_eval(script)} + elsif script.kind_of?(Proc) + cmd = proc{|*args| ScopeArgs.new(@fullname,*args).instance_eval(&script)} + else + fail ArgumentError, "String or Proc is expected" + end + TkNamespace::NsCode.new(tk_call_without_enc('namespace', 'code', + _get_eval_string(cmd, false))) + end + + def self.current + tk_call('namespace', 'current') + end + def current_namespace + # ns_tk_call('namespace', 'current') + @fullname + end + alias current current_namespace + + def self.delete(*ns_list) + tk_call('namespace', 'delete', *ns_list) + end + def delete + TkNamespece.delete(@fullname) + end + + def self.ensemble_create(*keys) + tk_call('namespace', 'ensemble', 'create', *hash_kv(keys)) + end + def self.ensemble_configure(cmd, slot, value=None) + if slot.kind_of?(Hash) + tk_call('namespace', 'ensemble', 'configure', cmd, *hash_kv(slot)) + else + tk_call('namespace', 'ensemble', 'configure', cmd, '-'+slot.to_s, value) + end + end + def self.ensemble_configinfo(cmd, slot = nil) + if slot + tk_call('namespace', 'ensemble', 'configure', cmd, '-' + slot.to_s) + else + inf = {} + Hash(*tk_split_simplelist(tk_call('namespace', 'ensemble', 'configure', cmd))).each{|k, v| inf[k[1..-1]] = v} + inf + end + end + def self.ensemble_exist?(cmd) + bool(tk_call('namespace', 'ensemble', 'exists', cmd)) + end + + def self.eval(namespace, cmd = Proc.new, *args) + #tk_call('namespace', 'eval', namespace, cmd, *args) + TkNamespace.new(namespece).eval(cmd, *args) + end + def eval(cmd = Proc.new, *args) + #TkNamespace.eval(@fullname, cmd, *args) + #ns_tk_call(cmd, *args) + code_obj = code(cmd) + ret = code_obj.call(*args) + uninstall_cmd(TkCore::INTERP._split_tklist(code_obj.path)[-1]) + ret + end + + def self.exist?(ns) + bool(tk_call('namespace', 'exists', ns)) + end + def exist? + TkNamespece.delete(@fullname) + end + + def self.export(*patterns) + tk_call('namespace', 'export', *patterns) + end + def self.export_with_clear(*patterns) + tk_call('namespace', 'export', '-clear', *patterns) + end + def export + TkNamespace.export(@fullname) + end + def export_with_clear + TkNamespace.export_with_clear(@fullname) + end + + def self.forget(*patterns) + tk_call('namespace', 'forget', *patterns) + end + def forget + TkNamespace.forget(@fullname) + end + + def self.import(*patterns) + tk_call('namespace', 'import', *patterns) + end + def self.force_import(*patterns) + tk_call('namespace', 'import', '-force', *patterns) + end + def import + TkNamespace.import(@fullname) + end + def force_import + TkNamespace.force_import(@fullname) + end + + def self.inscope(namespace, script, *args) + tk_call('namespace', 'inscope', namespace, script, *args) + end + def inscope(script, *args) + TkNamespace(@fullname, script, *args) + end + + def self.origin(cmd) + tk_call('namespace', 'origin', cmd) + end + + def self.parent(namespace=None) + ns = tk_call('namespace', 'parent', namespace) + if Tk_Namesapce_ID.key?(ns) + Tk_Namesapce_ID[ns] + else + ns + end + end + def parent + tk_call('namespace', 'parent', @fullname) + end + + def self.qualifiers(str) + tk_call('namespace', 'qualifiers', str) + end + + def self.tail(str) + tk_call('namespace', 'tail', str) + end + + def self.which(name) + tk_call('namespace', 'which', name) + end + def self.which_command(name) + tk_call('namespace', 'which', '-command', name) + end + def self.which_variable(name) + tk_call('namespace', 'which', '-variable', name) + end +end diff --git a/ext/tk/lib/tk/optiondb.rb b/ext/tk/lib/tk/optiondb.rb new file mode 100644 index 0000000000..588c946440 --- /dev/null +++ b/ext/tk/lib/tk/optiondb.rb @@ -0,0 +1,297 @@ +# +# tk/optiondb.rb : treat option database +# +require 'tk' + +module TkOptionDB + include Tk + extend Tk + + TkCommandNames = ['option'.freeze].freeze + + module Priority + WidgetDefault = 20 + StartupFile = 40 + UserDefault = 60 + Interactive = 80 + end + + def add(pat, value, pri=None) + if $SAFE >= 4 + fail SecurityError, "can't call 'TkOptionDB.add' at $SAFE >= 4" + end + tk_call('option', 'add', pat, value, pri) + end + def clear + if $SAFE >= 4 + fail SecurityError, "can't call 'TkOptionDB.crear' at $SAFE >= 4" + end + tk_call_without_enc('option', 'clear') + end + def get(win, name, klass) + tk_call('option', 'get', win ,name, klass) + end + def readfile(file, pri=None) + tk_call('option', 'readfile', file, pri) + end + module_function :add, :clear, :get, :readfile + + def read_entries(file, f_enc=nil) + if TkCore::INTERP.safe? + fail SecurityError, + "can't call 'TkOptionDB.read_entries' on a safe interpreter" + end + + i_enc = Tk.encoding() + + unless f_enc + f_enc = i_enc + end + + ent = [] + cline = '' + open(file, 'r') {|f| + while line = f.gets + cline += line.chomp! + case cline + when /\\$/ # continue + cline.chop! + next + when /^\s*(!|#)/ # coment + cline = '' + next + when /^([^:]+):(.*)$/ + pat = $1.strip + val = $2.lstrip + p "ResourceDB: #{[pat, val].inspect}" if $DEBUG + pat = TkCore::INTERP._toUTF8(pat, f_enc) + pat = TkCore::INTERP._fromUTF8(pat, i_enc) + val = TkCore::INTERP._toUTF8(val, f_enc) + val = TkCore::INTERP._fromUTF8(val, i_enc) + ent << [pat, val] + cline = '' + else # unknown --> ignore + cline = '' + next + end + end + } + ent + end + module_function :read_entries + + def read_with_encoding(file, f_enc=nil, pri=None) + # try to read the file as an OptionDB file + read_entries(file, f_enc).each{|pat, val| + add(pat, val, pri) + } + +=begin + i_enc = Tk.encoding() + + unless f_enc + f_enc = i_enc + end + + cline = '' + open(file, 'r') {|f| + while line = f.gets + cline += line.chomp! + case cline + when /\\$/ # continue + cline.chop! + next + when /^\s*!/ # coment + cline = '' + next + when /^([^:]+):\s(.*)$/ + pat = $1 + val = $2 + p "ResourceDB: #{[pat, val].inspect}" if $DEBUG + pat = TkCore::INTERP._toUTF8(pat, f_enc) + pat = TkCore::INTERP._fromUTF8(pat, i_enc) + val = TkCore::INTERP._toUTF8(val, f_enc) + val = TkCore::INTERP._fromUTF8(val, i_enc) + add(pat, val, pri) + cline = '' + else # unknown --> ignore + cline = '' + next + end + end + } +=end + end + module_function :read_with_encoding + + # support procs on the resource database + @@resource_proc_class = Class.new + class << @@resource_proc_class + private :new + + CARRIER = '.'.freeze + METHOD_TBL = TkCore::INTERP.create_table + ADD_METHOD = false + SAFE_MODE = 4 + +=begin + def __closed_block_check__(str) + depth = 0 + str.scan(/[{}]/){|x| + if x == "{" + depth += 1 + elsif x == "}" + depth -= 1 + end + if depth <= 0 && !($' =~ /\A\s*\Z/) + fail RuntimeError, "bad string for procedure : #{str.inspect}" + end + } + str + end + private :__closed_block_check__ +=end + + def __check_proc_string__(str) + # If you want to check the proc_string, do it in this method. + # Please define this in the block given to 'new_proc_class' method. + str + end + + def method_missing(id, *args) + res_proc, proc_str = self::METHOD_TBL[id] + + proc_source = TkOptionDB.get(self::CARRIER, id.id2name, '').strip + res_proc = nil if proc_str != proc_source # resource is changed + + unless res_proc.kind_of? Proc + if id == :new || !(self::METHOD_TBL.has_key?(id) || self::ADD_METHOD) + raise NoMethodError, + "not support resource-proc '#{id.id2name}' for #{self.name}" + end + proc_str = proc_source + proc_str = '{' + proc_str + '}' unless /\A\{.*\}\Z/ =~ proc_str + #proc_str = __closed_block_check__(proc_str) + proc_str = __check_proc_string__(proc_str) + res_proc = proc{ + begin + eval("$SAFE = #{self::SAFE_MODE};\nProc.new" + proc_str) + rescue SyntaxError=>err + raise SyntaxError, + TkCore::INTERP._toUTF8(err.message.gsub(/\(eval\):\d:/, + "(#{id.id2name}):")) + end + }.call + self::METHOD_TBL[id] = [res_proc, proc_source] + end + res_proc.call(*args) + end + + private :__check_proc_string__, :method_missing + end + @@resource_proc_class.freeze + + def __create_new_class(klass, func, safe = 4, add = false, parent = nil) + klass = klass.to_s if klass.kind_of? Symbol + unless (?A..?Z) === klass[0] + fail ArgumentError, "bad string '#{klass}' for class name" + end + unless func.kind_of? Array + fail ArgumentError, "method-list must be Array" + end + func_str = func.join(' ') + if parent == nil + install_win(parent) + elsif parent <= @@resource_proc_class + install_win(parent::CARRIER) + else + fail ArgumentError, "parent must be Resource-Proc class" + end + carrier = Tk.tk_call_without_enc('frame', @path, '-class', klass) + + body = <<-"EOD" + class #{klass} < TkOptionDB.module_eval('@@resource_proc_class') + CARRIER = '#{carrier}'.freeze + METHOD_TBL = TkCore::INTERP.create_table + ADD_METHOD = #{add} + SAFE_MODE = #{safe} + %w(#{func_str}).each{|f| METHOD_TBL[f.intern] = nil } + end + EOD + + if parent.kind_of?(Class) && parent <= @@resource_proc_class + parent.class_eval(body) + eval(parent.name + '::' + klass) + else + eval(body) + eval('TkOptionDB::' + klass) + end + end + module_function :__create_new_class + private_class_method :__create_new_class + + def __remove_methods_of_proc_class(klass) + # for security, make these methods invalid + class << klass + attr_reader :class_eval, :name, :superclass, + :ancestors, :const_defined?, :const_get, :const_set, + :constants, :included_modules, :instance_methods, + :method_defined?, :module_eval, :private_instance_methods, + :protected_instance_methods, :public_instance_methods, + :remove_const, :remove_method, :undef_method, + :to_s, :inspect, :display, :method, :methods, + :instance_eval, :instance_variables, :kind_of?, :is_a?, + :private_methods, :protected_methods, :public_methods + end + end + module_function :__remove_methods_of_proc_class + private_class_method :__remove_methods_of_proc_class + + RAND_BASE_CNT = [0] + RAND_BASE_HEAD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + RAND_BASE_CHAR = RAND_BASE_HEAD + 'abcdefghijklmnopqrstuvwxyz0123456789_' + def __get_random_basename + name = '%s%03d' % [RAND_BASE_HEAD[rand(RAND_BASE_HEAD.size),1], + RAND_BASE_CNT[0]] + len = RAND_BASE_CHAR.size + (6+rand(10)).times{ + name << RAND_BASE_CHAR[rand(len),1] + } + RAND_BASE_CNT[0] = RAND_BASE_CNT[0] + 1 + name + end + module_function :__get_random_basename + private_class_method :__get_random_basename + + # define new proc class : + # If you want to modify the new class or create a new subclass, + # you must do such operation in the block parameter. + # Because the created class is flozen after evaluating the block. + def new_proc_class(klass, func, safe = 4, add = false, parent = nil, &b) + new_klass = __create_new_class(klass, func, safe, add, parent) + new_klass.class_eval(&b) if block_given? + __remove_methods_of_proc_class(new_klass) + new_klass.freeze + new_klass + end + module_function :new_proc_class + + def eval_under_random_base(parent = nil, &b) + new_klass = __create_new_class(__get_random_basename(), + [], 4, false, parent) + ret = new_klass.class_eval(&b) if block_given? + __remove_methods_of_proc_class(new_klass) + new_klass.freeze + ret + end + module_function :eval_under_random_base + + def new_proc_class_random(klass, func, safe = 4, add = false, &b) + eval_under_random_base(){ + TkOption.new_proc_class(klass, func, safe, add, self, &b) + } + end + module_function :new_proc_class_random +end +TkOption = TkOptionDB +TkResourceDB = TkOptionDB diff --git a/ext/tk/lib/tk/pack.rb b/ext/tk/lib/tk/pack.rb new file mode 100644 index 0000000000..79f4d19d82 --- /dev/null +++ b/ext/tk/lib/tk/pack.rb @@ -0,0 +1,89 @@ +# +# tk/pack.rb : control pack geometry manager +# +require 'tk' + +module TkPack + include Tk + extend Tk + + TkCommandNames = ['pack'.freeze].freeze + + def configure(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + # params.push((win.kind_of?(TkObject))? win.epath: win) + params.push(_epath(win)) + args.each{|win| + # params.push((win.kind_of?(TkObject))? win.epath: win) + params.push(_epath(win)) + } + opts.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_call_without_enc("pack", 'configure', *params) + end + + def forget(*args) + return '' if args.size == 0 + wins = args.collect{|win| + # (win.kind_of?(TkObject))? win.epath: win + _epath(win) + } + tk_call_without_enc('pack', 'forget', *wins) + end + + def info(slave) + # slave = slave.epath if slave.kind_of?(TkObject) + slave = _epath(slave) + ilist = list(tk_call_without_enc('pack', 'info', slave)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + return info + end + + def propagate(master, bool=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if bool == None + bool(tk_call_without_enc('pack', 'propagate', master)) + else + tk_call_without_enc('pack', 'propagate', master, bool) + end + end + + def slaves(master) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call_without_enc('pack', 'slaves', master)) + end + + module_function :configure, :forget, :info, :propagate, :slaves +end +=begin +def TkPack(win, *args) + if args[-1].kind_of?(Hash) + opts = args.pop + else + opts = {} + end + params = [] + params.push((win.kind_of?(TkObject))? win.epath: win) + args.each{|win| + params.push((win.kind_of?(TkObject))? win.epath: win) + } + opts.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc("pack", *params) +end +=end diff --git a/ext/tk/lib/tk/package.rb b/ext/tk/lib/tk/package.rb new file mode 100644 index 0000000000..8768bf1c79 --- /dev/null +++ b/ext/tk/lib/tk/package.rb @@ -0,0 +1,61 @@ +# +# tk/package.rb : package command +# +require 'tk' + +module TkPackage + include TkCore + extend TkPackage + + TkCommandNames = ['package'.freeze].freeze + + def add_path(path) + Tk::AUTO_PATH.value = Tk::AUTO_PATH.to_a << path + end + + def forget(package) + tk_call('package', 'forget', package) + nil + end + + def names + tk_split_simplelist(tk_call('package', 'names')) + end + + def provide(package, version=nil) + if version + tk_call('package', 'provide', package, version) + nil + else + tk_call('package', 'provide', package) + end + end + + def present(package, version=None) + tk_call('package', 'present', package, version) + end + + def present_exact(package, version) + tk_call('package', 'present', '-exact', package, version) + end + + def require(package, version=None) + tk_call('package', 'require', package, version) + end + + def require_exact(package, version) + tk_call('package', 'require', '-exact', package, version) + end + + def versions(package) + tk_split_simplelist(tk_call('package', 'versions', package)) + end + + def vcompare(version1, version2) + number(tk_call('package', 'vcompare', version1, version2)) + end + + def vsatisfies(version1, version2) + bool(tk_call('package', 'vsatisfies', version1, version2)) + end +end diff --git a/ext/tk/lib/tk/palette.rb b/ext/tk/lib/tk/palette.rb new file mode 100644 index 0000000000..abcafcfb3a --- /dev/null +++ b/ext/tk/lib/tk/palette.rb @@ -0,0 +1,54 @@ +# +# tk/palette.rb : methods for Tcl/Tk standard library 'palette.tcl' +# 1998/06/21 by Hidetoshi Nagai +# +require 'tk' + +module TkPalette + include Tk + extend Tk + + TkCommandNames = [ + 'tk_setPalette'.freeze, + 'tk_bisque'.freeze, + 'tkDarken'.freeze + ].freeze + + def TkPalette.set(*args) + args = args.to_a.flatten if args.kind_of? Hash + tk_call('tk_setPalette', *args) + end + def TkPalette.setPalette(*args) + TkPalette.set(*args) + end + + def TkPalette.bisque + tk_call('tk_bisque') + end + + def TkPalette.darken(color, percent) + tk_call('tkDarken', color, percent) + end + + def TkPalette.recolorTree(window, colors) + if not colors.kind_of?(Hash) + fail "2nd arg need to be Hash" + end + + colors.each{|key, value| + begin + if window.cget(key) == tk_call('set', "tkPalette(#{key})") + window[key] = colors[key] + end + rescue + # ignore + end + } + + TkWinfo.children(window).each{|w| TkPalette.recolorTree(w, colors)} + end + + def recolorTree(colors) + TkPalette.recolorTree(self, colors) + end +end diff --git a/ext/tk/lib/tk/panedwindow.rb b/ext/tk/lib/tk/panedwindow.rb new file mode 100644 index 0000000000..1cfc7bad7a --- /dev/null +++ b/ext/tk/lib/tk/panedwindow.rb @@ -0,0 +1,204 @@ +# +# tk/panedwindow.rb : treat panedwindow +# +require 'tk' + +class TkPanedWindow conf } + else + ret = {} + tk_split_simplelist(tk_send_without_enc('paneconfigure', + win)).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + if key + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + alias pane_configinfo paneconfiginfo + + def current_paneconfiginfo(win, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = paneconfiginfo(win, key) + {conf[0] => conf[4]} + else + ret = {} + paneconfiginfo(win).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + paneconfiginfo(win, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + alias current_pane_configinfo current_paneconfiginfo + + def panes + list(tk_send_without_enc('panes')) + end +end +TkPanedwindow = TkPanedWindow diff --git a/ext/tk/lib/tk/place.rb b/ext/tk/lib/tk/place.rb new file mode 100644 index 0000000000..5c2f890e07 --- /dev/null +++ b/ext/tk/lib/tk/place.rb @@ -0,0 +1,110 @@ +# +# tk/place.rb : control place geometry manager +# +require 'tk' + +module TkPlace + include Tk + extend Tk + + TkCommandNames = ['place'.freeze].freeze + + def configure(win, slot, value=None) + # for >= Tk8.4a2 ? + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if slot.kind_of? Hash + params = [] + slot.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_call_without_enc('place', 'configure', win, *params) + else + # value = value.epath if value.kind_of?(TkObject) + value = _epath(value) + tk_call_without_enc('place', 'configure', win, "-#{slot}", value) + end + end + + def configinfo(win, slot = nil) + # for >= Tk8.4a2 ? + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if slot + conf = tk_split_list(tk_call_without_enc('place', 'configure', + win, "-#{slot}") ) + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(tk_call_without_enc('place', 'configure', + win)).collect{|conflist| + conf = list(conflist) + conf[0] = conf[0][1..-1] + conf + } + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + current_configinfo(win, slot) + end + end + + def current_configinfo(win, slot = nil) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if slot + conf = tk_split_list(tk_call_without_enc('place', 'configure', + win, "-#{slot}") ) + { conf[0][1..-1] => conf[1] } + else + ret = {} + tk_split_list(tk_call_without_enc('place','configure',win)).each{|conf| + ret[conf[0][1..-1]] = conf[1] + } + ret + end + end + + def forget(win) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + tk_call_without_enc('place', 'forget', win) + end + + def info(win) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + ilist = list(tk_call_without_enc('place', 'info', win)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + return info + end + + def slaves(master) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + list(tk_call('place', 'slaves', master)) + end + + module_function :configure, :configinfo, :forget, :info, :slaves +end +=begin +def TkPlace(win, slot, value=None) + win = win.epath if win.kind_of?(TkObject) + if slot.kind_of? Hash + params = [] + slot.each{|k, v| + params.push("-#{k}") + params.push((v.kind_of?(TkObject))? v.epath: v) + } + tk_call_without_enc('place', win, *params) + else + value = value.epath if value.kind_of?(TkObject) + tk_call_without_enc('place', win, "-#{slot}", value) + end +end +=end diff --git a/ext/tk/lib/tk/radiobutton.rb b/ext/tk/lib/tk/radiobutton.rb new file mode 100644 index 0000000000..e00f0a03eb --- /dev/null +++ b/ext/tk/lib/tk/radiobutton.rb @@ -0,0 +1,32 @@ +# +# tk/radiobutton.rb : treat radiobutton widget +# +require 'tk' +require 'tk/button' + +class TkRadioButtontrue, :widgetname=>'.') + if keys # wm commands + keys.each{|k,v| + if v.kind_of? Array + new.send(k,*v) + else + new.send(k,v) + end + } + end + ROOT[0] = new + Tk_WINDOWS["."] = new + end +=end + def TkRoot.new(keys=nil, &b) + unless TkCore::INTERP.tk_windows['.'] + TkCore::INTERP.tk_windows['.'] = + super(:without_creating=>true, :widgetname=>'.'){} + end + root = TkCore::INTERP.tk_windows['.'] + if keys # wm commands + keys.each{|k,v| + if v.kind_of? Array + root.send(k,*v) + else + root.send(k,v) + end + } + end + root.instance_eval(&b) if block_given? + root + end + + WidgetClassName = 'Tk'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self + @path = '.' + end + private :create_self + + def path + "." + end + + def TkRoot.destroy + TkCore::INTERP._invoke('destroy', '.') + end +end diff --git a/ext/tk/lib/tk/scale.rb b/ext/tk/lib/tk/scale.rb new file mode 100644 index 0000000000..9398a6cd52 --- /dev/null +++ b/ext/tk/lib/tk/scale.rb @@ -0,0 +1,78 @@ +# +# tk/scale.rb : treat scale widget +# +require 'tk' + +class TkScalevalue) + 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_without_enc('get', x, y)) + end + + def coords(val=None) + tk_split_list(tk_send_without_enc('coords', val)) + end + + def identify(x, y) + tk_send_without_enc('identify', x, y) + end + + def set(val) + tk_send_without_enc('set', val) + end + + def value + get + end + + def value= (val) + set(val) + val + end +end diff --git a/ext/tk/lib/tk/scrollable.rb b/ext/tk/lib/tk/scrollable.rb new file mode 100644 index 0000000000..e591a299ab --- /dev/null +++ b/ext/tk/lib/tk/scrollable.rb @@ -0,0 +1,49 @@ +# +# tk/scrollable.rb : module for scrollable widget +# +require 'tk' + +module Tk + module Scrollable + def xscrollcommand(cmd=Proc.new) + configure_cmd 'xscrollcommand', cmd + end + def yscrollcommand(cmd=Proc.new) + configure_cmd 'yscrollcommand', cmd + end + def xview(*index) + if index.size == 0 + list(tk_send_without_enc('xview')) + else + tk_send_without_enc('xview', *index) + self + end + end + def yview(*index) + if index.size == 0 + list(tk_send_without_enc('yview')) + else + tk_send_without_enc('yview', *index) + self + end + end + def xscrollbar(bar=nil) + if bar + @xscrollbar = bar + @xscrollbar.orient 'horizontal' + self.xscrollcommand {|*arg| @xscrollbar.set(*arg)} + @xscrollbar.command {|*arg| self.xview(*arg)} + end + @xscrollbar + end + def yscrollbar(bar=nil) + if bar + @yscrollbar = bar + @yscrollbar.orient 'vertical' + self.yscrollcommand {|*arg| @yscrollbar.set(*arg)} + @yscrollbar.command {|*arg| self.yview(*arg)} + end + @yscrollbar + end + end +end diff --git a/ext/tk/lib/tk/scrollbar.rb b/ext/tk/lib/tk/scrollbar.rb new file mode 100644 index 0000000000..0ee4423c9a --- /dev/null +++ b/ext/tk/lib/tk/scrollbar.rb @@ -0,0 +1,105 @@ +# +# tk/scrollbar.rb : treat scrollbar widget +# +require 'tk' + +class TkScrollbar +# +require 'tk' +require 'tk/listbox' + +class TkScrollbox'left','fill'=>'both','expand'=>'yes' + scroll.configure 'command', list.path+" yview" + scroll.pack 'side'=>'right','fill'=>'y' + + delegate('DEFAULT', list) + delegate('foreground', list) + delegate('background', list, scroll) + delegate('borderwidth', @frame) + delegate('relief', @frame) + + configure keys if keys + end + private :initialize_composite +end diff --git a/ext/tk/lib/tk/selection.rb b/ext/tk/lib/tk/selection.rb new file mode 100644 index 0000000000..970c3faa80 --- /dev/null +++ b/ext/tk/lib/tk/selection.rb @@ -0,0 +1,86 @@ +# +# tk/selection.rb : control selection +# +require 'tk' + +module TkSelection + include Tk + extend Tk + + TkCommandNames = ['selection'.freeze].freeze + + def self.clear(sel=nil) + if sel + tk_call_without_enc('selection', 'clear', '-selection', sel) + else + tk_call_without_enc('selection', 'clear') + end + end + def self.clear_on_display(win, sel=nil) + if sel + tk_call_without_enc('selection', 'clear', + '-displayof', win, '-selection', sel) + else + tk_call_without_enc('selection', 'clear', '-displayof', win) + end + end + def clear(sel=nil) + TkSelection.clear_on_display(self, sel) + self + end + + def self.get(keys=nil) + #tk_call('selection', 'get', *hash_kv(keys)) + _fromUTF8(tk_call_without_enc('selection', 'get', *hash_kv(keys))) + end + def self.get_on_display(win, keys=nil) + #tk_call('selection', 'get', '-displayof', win, *hash_kv(keys)) + _fromUTF8(tk_call_without_enc('selection', 'get', '-displayof', + win, *hash_kv(keys))) + end + def get(keys=nil) + TkSelection.get_on_display(self, sel) + end + + def self.handle(win, func=Proc.new, keys=nil, &b) + if func.kind_of?(Hash) && keys == nil + keys = func + func = Proc.new(&b) + end + args = ['selection', 'handle'] + args.concat(hash_kv(keys)) + args.concat([win, func]) + tk_call_without_enc(*args) + end + def handle(func=Proc.new, keys=nil, &b) + TkSelection.handle(self, func, keys, &b) + end + + def self.get_owner(sel=nil) + if sel + window(tk_call_without_enc('selection', 'own', '-selection', sel)) + else + window(tk_call_without_enc('selection', 'own')) + end + end + def self.get_owner_on_display(win, sel=nil) + if sel + window(tk_call_without_enc('selection', 'own', + '-displayof', win, '-selection', sel)) + else + window(tk_call_without_enc('selection', 'own', '-displayof', win)) + end + end + def get_owner(sel=nil) + TkSelection.get_owner_on_display(self, sel) + self + end + + def self.set_owner(win, keys=nil) + tk_call_without_enc('selection', 'own', *(hash_kv(keys) << win)) + end + def set_owner(keys=nil) + TkSelection.set_owner(self, keys) + self + end +end diff --git a/ext/tk/lib/tk/spinbox.rb b/ext/tk/lib/tk/spinbox.rb new file mode 100644 index 0000000000..1c58f9199b --- /dev/null +++ b/ext/tk/lib/tk/spinbox.rb @@ -0,0 +1,39 @@ +# +# tk/spinbox.rb - Tk spinbox classes +# $Date$ +# by Yukihiro Matsumoto +# +require 'tk' +require 'tk/entry' + +class TkSpinbox +require 'tk' +require 'tk/itemfont' +require 'tk/scrollable' +require 'tk/txtwin_abst' + +module TkTreatTextTagFont + include TkTreatItemFont + + ItemCMD = ['tag'.freeze, 'configure'.freeze].freeze + def __conf_cmd(idx) + ItemCMD[idx] + end + + def __item_pathname(tagOrId) + if tagOrId.kind_of?(TkTextTag) + self.path + ';' + tagOrId.id + else + self.path + ';' + tagOrId + end + end + + private :__conf_cmd, :__item_pathname +end + + +class TkText conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + + def current_image_configinfo(index, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = image_configinfo(index, slot) + {conf[0] => conf[4]} + else + ret = {} + image_configinfo(index).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + image_configinfo(index, slot).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + def image_names + tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'names'))).collect{|elt| + tagid2obj(elt) + } + end + + def set_insert(index) + tk_send_without_enc('mark','set','insert', _get_eval_enc_str(index)) + self + end + + def set_current(index) + tk_send_without_enc('mark','set','current', _get_eval_enc_str(index)) + self + end + + def insert(index, chars, *tags) + if tags[0].kind_of? Array + # multiple chars-taglist argument :: str, [tag,...], str, [tag,...], ... + args = [chars] + while tags.size > 0 + args << tags.shift.collect{|x|_get_eval_string(x)}.join(' ') # taglist + args << tags.shift if tags.size > 0 # chars + end + super index, *args + else + # single chars-taglist argument :: str, tag, tag, ... + if tags.size == 0 + super index, chars + else + super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ') + end + end + end + + def destroy + @tags = {} unless @tags + @tags.each_value do |t| + t.destroy + end + super + end + + def backspace + self.delete 'insert' + end + + def bbox(index) + list(tk_send_without_enc('bbox', _get_eval_enc_str(index))) + end + + def compare(idx1, op, idx2) + bool(tk_send_without_enc('compare', _get_eval_enc_str(idx1), + op, _get_eval_enc_str(idx2))) + end + + def count(idx1, idx2, *opts) + opts = opts.collect{|opt| '-' + opt.to_s} + number(tk_send_without_enc('count', _get_eval_enc_str(idx1), + _get_eval_enc_str(idx2), *opts)) + end + + def replace(idx1, idx2, *opts) + tk_send('replace', idx1, idx2, *opts) + self + end + + def debug + bool(tk_send_without_enc('debug')) + end + def debug=(boolean) + tk_send_without_enc('debug', boolean) + #self + boolean + end + + def dlineinfo(index) + list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index))) + end + + def modified? + bool(tk_send_without_enc('edit', 'modified')) + end + def modified(mode) + tk_send_without_enc('edit', 'modified', mode) + self + end + def modified=(mode) + modified(mode) + mode + end + + def edit_redo + tk_send_without_enc('edit', 'redo') + self + end + def edit_reset + tk_send_without_enc('edit', 'reset') + self + end + def edit_separator + tk_send_without_enc('edit', 'separator') + self + end + def edit_undo + tk_send_without_enc('edit', 'undo') + self + end + + def xview_pickplace(index) + tk_send_without_enc('xview', '-pickplace', _get_eval_enc_str(index)) + self + end + + def yview_pickplace(index) + tk_send_without_enc('yview', '-pickplace', _get_eval_enc_str(index)) + self + end + + def text_copy + # Tk8.4 feature + tk_call_without_enc('tk_textCopy', @path) + self + end + + def text_cut + # Tk8.4 feature + tk_call_without_enc('tk_textCut', @path) + self + end + + def text_paste + # Tk8.4 feature + tk_call_without_enc('tk_textPaste', @path) + self + end + + def tag_add(tag, index1, index2=None) + tk_send_without_enc('tag', 'add', _get_eval_enc_str(tag), + _get_eval_enc_str(index1), + _get_eval_enc_str(index2)) + self + end + alias addtag tag_add + alias add_tag tag_add + + def tag_delete(*tags) + tk_send_without_enc('tag', 'delete', + *(tags.collect{|tag| _get_eval_enc_str(tag)})) + if TkTextTag::TTagID_TBL[@path] + tags.each{|tag| + if tag.kind_of? TkTextTag + TTagID_TBL[@path].delete(tag.id) + else + TTagID_TBL[@path].delete(tag) + end + } + end + self + end + alias deltag tag_delete + alias delete_tag tag_delete + + def tag_bind(tag, seq, cmd=Proc.new, args=nil) + _bind([@path, 'tag', 'bind', tag], seq, cmd, args) + self + end + + def tag_bind_append(tag, seq, cmd=Proc.new, args=nil) + _bind_append([@path, 'tag', 'bind', tag], seq, cmd, args) + self + end + + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'tag', 'bind', tag], seq) + self + end + + def tag_bindinfo(tag, context=nil) + _bindinfo([@path, 'tag', 'bind', tag], context) + end + + def tag_cget(tag, key) + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + tk_call_without_enc(@path, 'tag', 'cget', + _get_eval_enc_str(tag), "-#{key}") + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('tag','cget',_get_eval_enc_str(tag),'-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tag, fnt) + end + if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@path,'tag','cget',_get_eval_enc_str(tag),"-#{key}"))) + end + end + + def tag_configure(tag, key, val=None) + if key.kind_of? Hash + key = _symbolkey2str(key) + if ( key['font'] || key['kanjifont'] \ + || key['latinfont'] || key['asciifont'] ) + tagfont_configure(tag, key) + else + tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), + *hash_kv(key, true)) + end + + else + if key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont + if val == None + tagfontobj(tag) + else + tagfont_configure(tag, {key=>val}) + end + else + tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), + "-#{key}", _get_eval_enc_str(val)) + end + end + self + end + + def tag_configinfo(tag, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + conf[4] = tagfont_configinfo(tag, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + end + conf[0] = conf[0][1..-1] + conf + else + ret = tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + fontconf = ret.assoc('font') + if fontconf + ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} + fontconf[4] = tagfont_configinfo(tag, fontconf[4]) + ret.push(fontconf) + else + ret + end + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + when 'font', 'kanjifont' + conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + conf[4] = tagfont_configinfo(tag, conf[4]) + else + conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),"-#{key}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + fontconf = ret['font'] + if fontconf + ret.delete('font') + ret.delete('kanjifont') + fontconf[3] = tagfont_configinfo(tag, fontconf[3]) + ret['font'] = fontconf + end + ret + end + end + end + + def current_tag_configinfo(tag, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if key + conf = tag_configinfo(tag, key) + {conf[0] => conf[4]} + else + ret = {} + tag_configinfo(tag).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + tag_configinfo(tag, key).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + def tag_raise(tag, above=None) + tk_send_without_enc('tag', 'raise', _get_eval_enc_str(tag), + _get_eval_enc_str(above)) + self + end + + def tag_lower(tag, below=None) + tk_send_without_enc('tag', 'lower', _get_eval_enc_str(tag), + _get_eval_enc_str(below)) + self + end + + def tag_remove(tag, *indices) + tk_send_without_enc('tag', 'remove', _get_eval_enc_str(tag), + *(indces.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def tag_ranges(tag) + l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges', + _get_eval_enc_str(tag))) + r = [] + while key=l.shift + r.push [key, l.shift] + end + r + end + + def tag_nextrange(tag, first, last=None) + tk_split_list(tk_send_without_enc('tag', 'nextrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))) + end + + def tag_prevrange(tag, first, last=None) + tk_split_list(tk_send_without_enc('tag', 'prevrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))) + end + + def window_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('window', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, fnt) + end + if slot.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), "-#{slot}"))) + end + end + + def window_configure(index, slot, value=None) + if index.kind_of? TkTextWindow + index.configure(slot, value) + else + if slot.kind_of? Hash + slot = _symbolkey2str(slot) + win = slot['window'] + # slot['window'] = win.epath if win.kind_of?(TkWindow) + slot['window'] = _epath(win) if win + if slot['create'] + p_create = slot['create'] + if p_create.kind_of? Proc +=begin + slot['create'] = install_cmd(proc{ + id = p_create.call + if id.kind_of?(TkWindow) + id.epath + else + id + end + }) +=end + slot['create'] = install_cmd(proc{_epath(p_create.call)}) + end + end + tk_send_without_enc('window', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true)) + else + if slot == 'window' || slot == :window + # id = value + # value = id.epath if id.kind_of?(TkWindow) + value = _epath(value) + end + if slot == 'create' || slot == :create + p_create = value + if p_create.kind_of? Proc +=begin + value = install_cmd(proc{ + id = p_create.call + if id.kind_of?(TkWindow) + id.epath + else + id + end + }) +=end + value = install_cmd(proc{_epath(p_create.call)}) + end + end + tk_send_without_enc('window', 'configure', + _get_eval_enc_str(index), + "-#{slot}", _get_eval_enc_str(value)) + end + end + self + end + + def window_configinfo(win, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + end + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + case conf[0] + when 'text', 'label', 'show', 'data', 'file' + else + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + else + conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), "-#{slot}"))) + end + key = conf.shift[1..-1] + { key => conf } + else + ret = {} + tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + case key + when 'text', 'label', 'show', 'data', 'file' + else + if conf[2] + if conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + end + if conf.size == 1 + ret[key] = conf[0][1..-1] # alias info + else + ret[key] = conf + end + } + ret + end + end + end + + def current_window_configinfo(win, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + conf = window_configinfo(win, slot) + {conf[0] => conf[4]} + else + ret = {} + window_configinfo(win).each{|conf| + ret[conf[0]] = conf[4] if conf.size > 2 + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + window_configinfo(win, slot).each{|k, conf| + ret[k] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + def window_names + tk_split_simplelist(_fromUTF8(tk_send_without_enc('window', 'names'))).collect{|elt| + tagid2obj(elt) + } + end + + def _ktext_length(txt) + if $KCODE !~ /n/i + return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length + end + + # $KCODE == 'NONE' + if JAPANIZED_TK + tk_call_without_enc('kstring', 'length', + _get_eval_enc_str(txt)).to_i + else + begin + tk_call_without_enc('encoding', 'convertto', 'ascii', + _get_eval_enc_str(txt)).length + rescue StandardError, NameError + # sorry, I have no plan + txt.length + end + end + end + private :_ktext_length + + def tksearch(*args) + # call 'search' subcommand of text widget + # args ::= [] [] + # must be a regular expression of Tcl + all_mode = false + opts = args.shift + if opts.kind_of?(Array) + opts = opts.collect{|opt| + opt = opt.to_s + all_mode = true if opt == 'all' + opt + } + else + args.unshift(opts) + opts = [] + end + + opts << '--' + + if all_mode + tk_split_simplelist(tk_send(*(opts + args))) + else + tk_send(*(opts + args)) + end + end + + def tksearch_with_count(*args) + # call 'search' subcommand of text widget + # args ::= [] [] + # must be a regular expression of Tcl + all_mode = false + opts = args.shift + if opts.kind_of?(Array) + opts = opts.collect{|opt| + opt = opt.to_s + all_mode = true if opt == 'all' + opt + } + var = args.shift + else + var = opts + opts = [] + end + + opts << '-count' << var << '--' + + if all_mode + tk_split_simplelist(tk_send(*(opts + args))) + else + tk_send(*(opts + args)) + end + end + + def search_with_length(pat,start,stop=None) + pat = pat.chr if pat.kind_of? Integer + if stop != None + return ["", 0] if compare(start,'>=',stop) + txt = get(start,stop) + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of? String + #return [index(start + " + #{pos} chars"), pat.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index(start + " + #{pos} chars"), $&.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(match), match] + end + else + return ["", 0] + end + else + txt = get(start,'end - 1 char') + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of? String + #return [index(start + " + #{pos} chars"), pat.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index(start + " + #{pos} chars"), $&.split('').length] + return [index(start + " + #{pos} chars"), + _ktext_length(match), match] + end + else + txt = get('1.0','end - 1 char') + if (pos = txt.index(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of? String + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), + _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + end + end + end + + def search(pat,start,stop=None) + search_with_length(pat,start,stop)[0] + end + + def rsearch_with_length(pat,start,stop=None) + pat = pat.chr if pat.kind_of? Integer + if stop != None + return ["", 0] if compare(start,'<=',stop) + txt = get(stop,start) + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of? String + #return [index(stop + " + #{pos} chars"), pat.split('').length] + return [index(stop + " + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index(stop + " + #{pos} chars"), $&.split('').length] + return [index(stop + " + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + else + txt = get('1.0',start) + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of? String + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + txt = get('1.0','end - 1 char') + if (pos = txt.rindex(pat)) + match = $& + #pos = txt[0..(pos-1)].split('').length if pos > 0 + pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 + if pat.kind_of? String + #return [index("1.0 + #{pos} chars"), pat.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] + else + #return [index("1.0 + #{pos} chars"), $&.split('').length] + return [index("1.0 + #{pos} chars"), _ktext_length(match), match] + end + else + return ["", 0] + end + end + end + end + + def rsearch(pat,start,stop=None) + rsearch_with_length(pat,start,stop)[0] + end + + def dump(type_info, *index, &block) + args = type_info.collect{|inf| '-' + inf} + args << '-command' << block if block + str = tk_send('dump', *(args + index)) + result = [] + sel = nil + i = 0 + while i < str.size + # retrieve key + idx = str.index(/ /, i) + result.push str[i..(idx-1)] + i = idx + 1 + + # retrieve value + case result[-1] + when 'text' + if str[i] == ?{ + # text formed as {...} + val, i = _retrieve_braced_text(str, i) + result.push val + else + # text which may contain backslahes + val, i = _retrieve_backslashed_text(str, i) + result.push val + end + else + idx = str.index(/ /, i) + val = str[i..(idx-1)] + case result[-1] + when 'mark' + case val + when 'insert' + result.push TkTextMarkInsert.new(self) + when 'current' + result.push TkTextMarkCurrent.new(self) + when 'anchor' + result.push TkTextMarkAnchor.new(self) + else + result.push tk_tcl2ruby(val) + end + when 'tagon' + if val == 'sel' + if sel + result.push sel + else + result.push TkTextTagSel.new(self) + end + else + result.push tk_tcl2ruby(val) + end + when 'tagoff' + result.push tk_tcl2ruby(val) + when 'window' + result.push tk_tcl2ruby(val) + end + i = idx + 1 + end + + # retrieve index + idx = str.index(/ /, i) + if idx + result.push str[i..(idx-1)] + i = idx + 1 + else + result.push str[i..-1] + break + end + end + + kvis = [] + until result.empty? + kvis.push [result.shift, result.shift, result.shift] + end + kvis # result is [[key1, value1, index1], [key2, value2, index2], ...] + end + + def _retrieve_braced_text(str, i) + cnt = 0 + idx = i + while idx < str.size + case str[idx] + when ?{ + cnt += 1 + when ?} + cnt -= 1 + if cnt == 0 + break + end + end + idx += 1 + end + return str[i+1..idx-1], idx + 2 + end + private :_retrieve_braced_text + + def _retrieve_backslashed_text(str, i) + j = i + idx = nil + loop { + idx = str.index(/ /, j) + if str[idx-1] == ?\\ + j += 1 + else + break + end + } + val = str[i..(idx-1)] + val.gsub!(/\\( |\{|\})/, '\1') + return val, idx + 1 + end + private :_retrieve_backslashed_text + + def dump_all(*index, &block) + dump(['all'], *index, &block) + end + def dump_mark(*index, &block) + dump(['mark'], *index, &block) + end + def dump_tag(*index, &block) + dump(['tag'], *index, &block) + end + def dump_text(*index, &block) + dump(['text'], *index, &block) + end + def dump_window(*index, &block) + dump(['window'], *index, &block) + end + def dump_image(*index, &block) + dump(['image'], *index, &block) + end +end diff --git a/ext/tk/lib/tk/textimage.rb b/ext/tk/lib/tk/textimage.rb new file mode 100644 index 0000000000..444d91b0a5 --- /dev/null +++ b/ext/tk/lib/tk/textimage.rb @@ -0,0 +1,72 @@ +# +# tk/textimage.rb - treat Tk text image object +# +require 'tk' +require 'tk/text' + +class TkTextImage 0 + tk_call_without_enc(@t.path, 'window', 'configure', @index, + *hash_kv(slot, true)) + end + else + if slot == 'window' || slot == :window + @id = value + # value = @id.epath if @id.kind_of?(TkWindow) + value = _epath(@id) if @id + end + if slot == 'create' || slot == :create + self.create=value + else + tk_call_without_enc(@t.path, 'window', 'configure', @index, + "-#{slot}", _get_eval_enc_str(value)) + end + end + self + end + + def configinfo(slot = nil) + @t.window_configinfo(@index, slot) + end + + def current_configinfo(slot = nil) + @t.current_window_configinfo(@index, slot) + end + + def window + @id + end + + def window=(value) + @id = value + # value = @id.epath if @id.kind_of?(TkWindow) + value = _epath(@id) if @id + tk_call_without_enc(@t.path, 'window', 'configure', @index, + '-window', _get_eval_enc_str(value)) + value + end + + def create + @p_create + end + + def create=(value) + @p_create = value + if @p_create.kind_of? Proc + value = install_cmd(proc{ + @id = @p_create.call + if @id.kind_of?(TkWindow) + @id.epath + else + @id + end + }) + end + tk_call_without_enc(@t.path, 'window', 'configure', @index, + '-create', _get_eval_enc_str(value)) + value + end +end diff --git a/ext/tk/lib/tk/timer.rb b/ext/tk/lib/tk/timer.rb new file mode 100644 index 0000000000..c53e67682d --- /dev/null +++ b/ext/tk/lib/tk/timer.rb @@ -0,0 +1,441 @@ +# +# tk/timer.rb : methods for Tcl/Tk after command +# +# $Id$ +# +require 'tk' + +class TkTimer + include TkCore + extend TkCore + + TkCommandNames = ['after'.freeze].freeze + + Tk_CBID = ['a'.freeze, '00000'.taint].freeze + Tk_CBTBL = {}.taint + + TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL') + if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} { + return -code $st $ret + } { + return $ret + } + EOL + + DEFAULT_IGNORE_EXCEPTIONS = [ NameError, RuntimeError ].freeze + + ############################### + # class methods + ############################### + def self.callback(obj_id) + @after_id = nil + ex_obj = Tk_CBTBL[obj_id] + return "" if ex_obj == nil; # canceled + ex_obj.cb_call + end + + def self.info(obj = nil) + if obj + if obj.kind_of?(TkTimer) + if obj.after_id + inf = tk_split_list(tk_call_without_enc('after','info',obj.after_id)) + [Tk_CBTBL[inf[0][1]], inf[1]] + else + nil + end + else + fail ArgumentError, "TkTimer object is expected" + end + else + tk_call_without_enc('after', 'info').split(' ').collect!{|id| + ret = Tk_CBTBL.find{|key,val| val.after_id == id} + (ret == nil)? id: ret[1] + } + end + end + + ############################### + # instance methods + ############################### + def do_callback + @in_callback = true + begin + @return_value = @current_proc.call(self) + rescue Exception => e + if @cancel_on_exception && + @cancel_on_exception.find{|exc| e.kind_of?(exc)} + cancel + @return_value = e + return e + else + fail e + end + end + if @set_next + set_next_callback(@current_args) + else + @set_next = true + end + @in_callback = false + @return_value + end + + def set_callback(sleep, args=nil) + @after_script = "rb_after #{@id}" + @after_id = tk_call_without_enc('after', sleep, @after_script) + @current_args = args + @current_script = [sleep, @after_script] + self + end + + def set_next_callback(args) + if @running == false || @proc_max == 0 || @do_loop == 0 + Tk_CBTBL.delete(@id) ;# for GC + @running = false + @wait_var.value = 0 + return + end + if @current_pos >= @proc_max + if @do_loop < 0 || (@do_loop -= 1) > 0 + @current_pos = 0 + else + Tk_CBTBL.delete(@id) ;# for GC + @running = false + @wait_var.value = 0 + return + end + end + + @current_args = args + + if @sleep_time.kind_of? Proc + sleep = @sleep_time.call(self) + else + sleep = @sleep_time + end + @current_sleep = sleep + + cmd, *cmd_args = @loop_proc[@current_pos] + @current_pos += 1 + @current_proc = cmd + + set_callback(sleep, cmd_args) + end + + def initialize(*args) + @id = Tk_CBID.join('') + Tk_CBID[1].succ! + + @wait_var = TkVariable.new(0) + + @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback)) + + @set_next = true + + @init_sleep = 0 + @init_proc = nil + @init_args = [] + + @current_script = [] + @current_proc = nil + @current_args = nil + @return_value = nil + + @sleep_time = 0 + @current_sleep = 0 + @loop_exec = 0 + @do_loop = 0 + @loop_proc = [] + @proc_max = 0 + @current_pos = 0 + + @after_id = nil + @after_script = nil + + @cancel_on_exception = DEFAULT_IGNORE_EXCEPTIONS + # Unless @cancel_on_exception, Ruby/Tk shows an error dialog box when + # an excepsion is raised on TkTimer callback procedure. + # If @cancel_on_exception is an array of exception classes and the raised + # exception is included in the array, Ruby/Tk cancels executing TkTimer + # callback procedures silently (TkTimer#cancel is called and no dialog is + # shown). + + set_procs(*args) if args != [] + + @running = false + @in_callback = false + end + + attr :after_id + attr :after_script + attr :current_proc + attr :current_args + attr :current_sleep + alias :current_interval :current_sleep + attr :return_value + + attr_accessor :loop_exec + + def cb_call + @cb_cmd.call + end + + def get_procs + [@init_sleep, @init_proc, @init_args, @sleep_time, @loop_exec, @loop_proc] + end + + def current_status + [@running, @current_sleep, @current_proc, @current_args, + @do_loop, @cancel_on_exception] + end + + def cancel_on_exception? + @cancel_on_exception + end + + def cancel_on_exception=(mode) + if mode.kind_of?(Array) + @cancel_on_exception = mode + elsif mode + @cancel_on_exception = DEFAULT_IGNORE_EXCEPTIONS + else + @cancel_on_exception = false + end + #self + end + + def running? + @running + end + + def loop_rest + @do_loop + end + + def loop_rest=(rest) + @do_loop = rest + #self + end + + def set_procs(interval, loop_exec, *procs) + if !interval == 'idle' \ + && !interval.kind_of?(Integer) && !interval.kind_of?(Proc) + fail ArguemntError, "expect Integer or Proc for 1st argument" + end + @sleep_time = interval + + @loop_proc = [] + procs.each{|e| + if e.kind_of? Proc + @loop_proc.push([e]) + else + @loop_proc.push(e) + end + } + @proc_max = @loop_proc.size + @current_pos = 0 + + @do_loop = 0 + if loop_exec + if loop_exec.kind_of?(Integer) && loop_exec < 0 + @loop_exec = -1 + elsif loop_exec == nil || loop_exec == false || loop_exec == 0 + @loop_exec = 1 + else + if not loop_exec.kind_of?(Integer) + fail ArguemntError, "expect Integer for 2nd argument" + end + @loop_exec = loop_exec + end + @do_loop = @loop_exec + end + + self + end + + def add_procs(*procs) + procs.each{|e| + if e.kind_of? Proc + @loop_proc.push([e]) + else + @loop_proc.push(e) + end + } + @proc_max = @loop_proc.size + + self + end + + def delete_procs(*procs) + procs.each{|e| + if e.kind_of? Proc + @loop_proc.delete([e]) + else + @loop_proc.delete(e) + end + } + @proc_max = @loop_proc.size + + cancel if @proc_max == 0 + + self + end + + def delete_at(n) + @loop_proc.delete_at(n) + @proc_max = @loop_proc.size + cancel if @proc_max == 0 + self + end + + def set_start_proc(sleep, init_proc, *init_args) + if !sleep == 'idle' && !sleep.kind_of?(Integer) + fail ArguemntError, "expect Integer or 'idle' for 1st argument" + end + @init_sleep = sleep + @init_proc = init_proc + @init_args = init_args + self + end + + def start(*init_args) + return nil if @running + + Tk_CBTBL[@id] = self + @do_loop = @loop_exec + @current_pos = 0 + + argc = init_args.size + if argc > 0 + sleep = init_args.shift + if !sleep == 'idle' && !sleep.kind_of?(Integer) + fail ArguemntError, "expect Integer or 'idle' for 1st argument" + end + @init_sleep = sleep + end + @init_proc = init_args.shift if argc > 1 + @init_args = init_args if argc > 0 + + @current_sleep = @init_sleep + @running = true + if @init_proc + if not @init_proc.kind_of? Proc + fail ArgumentError, "Argument '#{@init_proc}' need to be Proc" + end + @current_proc = @init_proc + set_callback(@init_sleep, @init_args) + @set_next = false if @in_callback + else + set_next_callback(@init_args) + end + + self + end + + def reset(*reset_args) + restart() if @running + + if @init_proc + @return_value = @init_proc.call(self) + else + @return_value = nil + end + + @current_pos = 0 + @current_args = @init_args + @set_next = false if @in_callback + + self + end + + def restart(*restart_args) + cancel if @running + if restart_args == [] + start(@init_sleep, @init_proc, *@init_args) + else + start(*restart_args) + end + end + + def cancel + @running = false + @wait_var.value = 0 + tk_call 'after', 'cancel', @after_id if @after_id + @after_id = nil + Tk_CBTBL.delete(@id) ;# for GC + self + end + alias stop cancel + + def continue(wait=nil) + fail RuntimeError, "is already running" if @running + sleep, cmd = @current_script + fail RuntimeError, "no procedure to continue" unless cmd + if wait + unless wait.kind_of? Integer + fail ArguemntError, "expect Integer for 1st argument" + end + sleep = wait + end + Tk_CBTBL[@id] = self + @running = true + @after_id = tk_call_without_enc('after', sleep, cmd) + self + end + + def skip + fail RuntimeError, "is not running now" unless @running + cancel + Tk_CBTBL[@id] = self + @running = true + set_next_callback(@current_args) + self + end + + def info + if @after_id + inf = tk_split_list(tk_call_without_enc('after', 'info', @after_id)) + [Tk_CBTBL[inf[0][1]], inf[1]] + else + nil + end + end + + def wait(on_thread = true, check_root = false) + if $SAFE >= 4 + fail SecurityError, "can't wait timer at $SAFE >= 4" + end + + unless @running + if @return_value.kind_of?(Exception) + fail @return_value + else + return @return_value + end + end + + @wait_var.wait(on_thread, check_root) + if @return_value.kind_of?(Exception) + fail @return_value + else + @return_value + end + end + def eventloop_wait(check_root = false) + wait(false, check_root) + end + def thread_wait(check_root = false) + wait(true, check_root) + end + def tkwait(on_thread = true) + wait(on_thread, true) + end + def eventloop_tkwait + wait(false, true) + end + def thread_tkwait + wait(true, true) + end +end + +TkAfter = TkTimer diff --git a/ext/tk/lib/tk/toplevel.rb b/ext/tk/lib/tk/toplevel.rb new file mode 100644 index 0000000000..f8b0f77936 --- /dev/null +++ b/ext/tk/lib/tk/toplevel.rb @@ -0,0 +1,211 @@ +# +# tk/toplevel.rb : treat toplevel widget +# +require 'tk' +require 'tk/wm' + +class TkToplevel 0 + args = args.join(' ') + keys = ValidateArgs._get_subst_key(args) + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + @id = install_cmd(cmd) + else + @id = install_cmd(proc{|*arg| + (cmd.call(*ValidateArgs.scan_args(keys, arg)))? '1':'0' + }) + ' ' + args + end + else + keys, args = ValidateArgs._get_all_subst_keys + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + @id = install_cmd(cmd) + else + @id = install_cmd(proc{|*arg| + (cmd.call( + ValidateArgs.new(*ValidateArgs.scan_args(keys,arg))) + )? '1': '0' + }) + ' ' + args + end + end + end + + def to_eval + @id + end + end + + ##################################### + + def configure(slot, value=TkComm::None) + if slot.kind_of? Hash + slot = _symbolkey2str(slot) + if slot['vcmd'].kind_of? Array + cmd, *args = slot['vcmd'] + slot['vcmd'] = ValidateCmd.new(cmd, args.join(' ')) + elsif slot['vcmd'].kind_of? Proc + slot['vcmd'] = ValidateCmd.new(slot['vcmd']) + end + if slot['validatecommand'].kind_of? Array + cmd, *args = slot['validatecommand'] + slot['validatecommand'] = ValidateCmd.new(cmd, args.join(' ')) + elsif slot['validatecommand'].kind_of? Proc + slot['validatecommand'] = ValidateCmd.new(slot['validatecommand']) + end + if slot['invcmd'].kind_of? Array + cmd, *args = slot['invcmd'] + slot['invcmd'] = ValidateCmd.new(cmd, args.join(' ')) + elsif slot['invcmd'].kind_of? Proc + slot['invcmd'] = ValidateCmd.new(slot['invcmd']) + end + if slot['invalidcommand'].kind_of? Array + cmd, *args = slot['invalidcommand'] + slot['invalidcommand'] = ValidateCmd.new(cmd, args.join(' ')) + elsif slot['invalidcommand'].kind_of? Proc + slot['invalidcommand'] = ValidateCmd.new(slot['invalidcommand']) + end + super(slot) + else + if (slot == 'vcmd' || slot == :vcmd || + slot == 'validatecommand' || slot == :validatecommand || + slot == 'invcmd' || slot == :invcmd || + slot == 'invalidcommand' || slot == :invalidcommand) + if value.kind_of? Array + cmd, *args = value + value = ValidateCmd.new(cmd, args.join(' ')) + elsif value.kind_of? Proc + value = ValidateCmd.new(value) + end + end + super(slot, value) + end + self + end + + def validatecommand(cmd = Proc.new, args = nil) + if cmd.kind_of?(ValidateCmd) + configure('validatecommand', cmd) + elsif args + configure('validatecommand', [cmd, args]) + else + configure('validatecommand', cmd) + end + end + alias vcmd validatecommand + + def invalidcommand(cmd = Proc.new, args = nil) + if cmd.kind_of?(ValidateCmd) + configure('invalidcommand', cmd) + elsif args + configure('invalidcommand', [cmd, args]) + else + configure('invalidcommand', cmd) + end + end + alias invcmd invalidcommand +end diff --git a/ext/tk/lib/tk/variable.rb b/ext/tk/lib/tk/variable.rb new file mode 100644 index 0000000000..c4ec91741d --- /dev/null +++ b/ext/tk/lib/tk/variable.rb @@ -0,0 +1,847 @@ +# +# tk/variable.rb : treat Tk variable object +# +require 'tk' + +class TkVariable + include Tk + extend TkCore + + include Comparable + + #TkCommandNames = ['tkwait'.freeze].freeze + TkCommandNames = ['vwait'.freeze].freeze + + #TkVar_CB_TBL = {} + #TkVar_ID_TBL = {} + TkVar_CB_TBL = TkCore::INTERP.create_table + TkVar_ID_TBL = TkCore::INTERP.create_table + Tk_VARIABLE_ID = ["v".freeze, "00000".taint].freeze + + #TkCore::INTERP.add_tk_procs('rb_var', 'args', + # "ruby [format \"TkVariable.callback %%Q!%s!\" $args]") +TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') + if {[set st [catch {eval {ruby_cmd TkVariable callback} $args} ret]] != 0} { + set idx [string first "\n\n" $ret] + if {$idx > 0} { + global errorInfo + set tcl_backtrace $errorInfo + set errorInfo [string range $ret [expr $idx + 2] \ + [string length $ret]] + append errorInfo "\n" $tcl_backtrace + bgerror [string range $ret 0 [expr $idx - 1]] + } else { + bgerror $ret + } + return "" + #return -code $st $ret + } else { + return $ret + } + EOL + + #def TkVariable.callback(args) + def TkVariable.callback(name1, name2, op) + #name1,name2,op = tk_split_list(args) + #name1,name2,op = tk_split_simplelist(args) + if TkVar_CB_TBL[name1] + #_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) + begin + _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2, op)) + rescue Exception => e + begin + msg = _toUTF8(e.class.inspect) + ': ' + + _toUTF8(e.message) + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + _toUTF8(e.backtrace.join("\n")) + + "\n---< backtrace of Tk side >-------" + msg.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + msg = e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------" + end + fail(e, msg) + end +=begin + begin + raise 'check backtrace' + rescue + # ignore backtrace before 'callback' + pos = -($!.backtrace.size) + end + begin + _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) + rescue + trace = $!.backtrace + raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" + + "\tfrom #{trace[1..pos].join("\n\tfrom ")}" + end +=end + else + '' + end + end + + def initialize(val="") + @id = Tk_VARIABLE_ID.join('') + Tk_VARIABLE_ID[1].succ! + TkVar_ID_TBL[@id] = self + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + begin + INTERP._unset_global_var(@id) + rescue + end + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @id) + #INTERP._invoke('global', @id) + + self.value = val + +=begin + if val == [] + # INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)', + # @id, @id, @id)) + elsif val.kind_of?(Array) + a = [] + # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} + # s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' + val.each_with_index{|e,i| a.push(i); a.push(e)} + #s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + array2tk_list(a).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) + elsif val.kind_of?(Hash) + #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + # .gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + .gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(format('global %s; array set %s %s', @id, @id, s)) + else + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(format('global %s; set %s %s', @id, @id, s)) + end +=end +=begin + if val.kind_of?(Hash) + #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + # .gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + .gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s)) + else + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) + end +=end + end + + def wait(on_thread = false, check_root = false) + if $SAFE >= 4 + fail SecurityError, "can't wait variable at $SAFE >= 4" + end + on_thread &= (Thread.list.size != 1) + if on_thread + if check_root + INTERP._thread_tkwait('variable', @id) + else + INTERP._thread_vwait(@id) + end + else + if check_root + INTERP._invoke_without_enc('tkwait', 'variable', @id) + else + INTERP._invoke_without_enc('vwait', @id) + end + end + end + def eventloop_wait(check_root = false) + wait(false, check_root) + end + def thread_wait(check_root = false) + wait(true, check_root) + end + def tkwait(on_thread = true) + wait(on_thread, true) + end + def eventloop_tkwait + wait(false, true) + end + def thread_tkwait + wait(true, true) + end + + def id + @id + end + + def is_hash? + #ITNERP._eval("global #{@id}; array exist #{@id}") == '1' + ITNERP._invoke_without_enc('array', 'exist', @id) == '1' + end + + def is_scalar? + ! is_hash? + end + + def keys + if (is_scalar?) + fail RuntimeError, 'cannot get keys from a scalar variable' + end + #tk_split_simplelist(INTERP._eval("global #{@id}; array get #{@id}")) + tk_split_simplelist(INTERP._fromUTF8(INTERP._invoke_without_enc('array', 'get', @id))) + end + + +unless const_defined?(:USE_TCLs_SET_VARIABLE_FUNCTIONS) + USE_TCLs_SET_VARIABLE_FUNCTIONS = true +end + +if USE_TCLs_SET_VARIABLE_FUNCTIONS + ########################################################################### + # use Tcl function version of set tkvariable + ########################################################################### + + def value + #if INTERP._eval("global #{@id}; array exist #{@id}") == '1' + if INTERP._invoke('array', 'exist', @id) == '1' + #Hash[*tk_split_simplelist(INTERP._eval("global #{@id}; array get #{@id}"))] + Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', @id))] + else + _fromUTF8(INTERP._get_global_var(@id)) + end + end + + def value=(val) + if val.kind_of?(Hash) + val.each{|k, v| + #INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(k)), + # _toUTF8(_get_eval_string(v))) + INTERP._set_global_var2(@id, __get_eval_string(k, true), + _get_eval_string(v, true)) + } + self.value + elsif val.kind_of?(Array) + INTERP._set_global_var(@id, '') + val.each{|v| + #INTERP._set_variable(@id, _toUTF8(_get_eval_string(v)), + INTERP._set_variable(@id, _get_eval_string(v, true), + TclTkLib::VarAccessFlag::GLOBAL_ONLY | + TclTkLib::VarAccessFlag::LEAVE_ERR_MSG | + TclTkLib::VarAccessFlag::APPEND_VALUE | + TclTkLib::VarAccessFlag::LIST_ELEMENT) + } + self.value + else + #_fromUTF8(INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val)))) + _fromUTF8(INTERP._set_global_var(@id, _get_eval_string(val, true))) + end + end + + def [](index) + #_fromUTF8(INTERP._get_global_var2(@id, _toUTF8(_get_eval_string(index)))) + _fromUTF8(INTERP._get_global_var2(@id, _get_eval_string(index, true))) + end + + def []=(index,val) + #_fromUTF8(INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(index)), + # _toUTF8(_get_eval_string(val)))) + _fromUTF8(INTERP._set_global_var2(@id, _get_eval_string(index, true), + _get_eval_string(val, true))) + end + + def unset(elem=nil) + if elem + INTERP._unset_global_var2(@id, tk_tcl2ruby(elem)) + else + INTERP._unset_global_var(@id) + end + end + alias remove unset + +else + ########################################################################### + # use Ruby script version of set tkvariable (traditional methods) + ########################################################################### + + def value + begin + INTERP._eval(Kernel.format('global %s; set %s', @id, @id)) + #INTERP._eval(Kernel.format('set %s', @id)) + #INTERP._invoke_without_enc('set', @id) + rescue + if INTERP._eval(Kernel.format('global %s; array exists %s', + @id, @id)) != "1" + #if INTERP._eval(Kernel.format('array exists %s', @id)) != "1" + #if INTERP._invoke_without_enc('array', 'exists', @id) != "1" + fail + else + Hash[*tk_split_simplelist(INTERP._eval(Kernel.format('global %s; array get %s', @id, @id)))] + #Hash[*tk_split_simplelist(_fromUTF8(INTERP._invoke_without_enc('array', 'get', @id)))] + end + end + end + + def value=(val) + begin + #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s)) + #INTERP._eval(Kernel.format('set %s %s', @id, s)) + #_fromUTF8(INTERP._invoke_without_enc('set', @id, _toUTF8(s))) + rescue + if INTERP._eval(Kernel.format('global %s; array exists %s', + @id, @id)) != "1" + #if INTERP._eval(Kernel.format('array exists %s', @id)) != "1" + #if INTERP._invoke_without_enc('array', 'exists', @id) != "1" + fail + else + if val == [] + INTERP._eval(Kernel.format('global %s; unset %s; set %s(0) 0; unset %s(0)', @id, @id, @id, @id)) + #INTERP._eval(Kernel.format('unset %s; set %s(0) 0; unset %s(0)', + # @id, @id, @id)) + #INTERP._invoke_without_enc('unset', @id) + #INTERP._invoke_without_enc('set', @id+'(0)', 0) + #INTERP._invoke_without_enc('unset', @id+'(0)') + elsif val.kind_of?(Array) + a = [] + val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))} + #s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + a.join(" ").gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', + @id, @id, @id, s)) + #INTERP._eval(Kernel.format('unset %s; array set %s %s', + # @id, @id, s)) + #INTERP._invoke_without_enc('unset', @id) + #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s))) + elsif val.kind_of?(Hash) + #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + # .gsub(/[\[\]$"]/, '\\\\\&') + '"' + s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\ + .gsub(/[\[\]$\\"]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', + @id, @id, @id, s)) + #INTERP._eval(Kernel.format('unset %s; array set %s %s', + # @id, @id, s)) + #INTERP._invoke_without_enc('unset', @id) + #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s))) + else + fail + end + end + end + end + + def [](index) + INTERP._eval(Kernel.format('global %s; set %s(%s)', + @id, @id, _get_eval_string(index))) + #INTERP._eval(Kernel.format('set %s(%s)', @id, _get_eval_string(index))) + #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ')') + end + + def []=(index,val) + INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, + _get_eval_string(index), _get_eval_string(val))) + #INTERP._eval(Kernel.format('set %s(%s) %s', @id, + # _get_eval_string(index), _get_eval_string(val))) + #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ') ' + + # _get_eval_string(val)) + end + + def unset(elem=nil) + if elem + INTERP._eval(Kernel.format('global %s; unset %s(%s)', + @id, @id, tk_tcl2ruby(elem))) + #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem))) + #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')') + else + INTERP._eval(Kernel.format('global %s; unset %s', @id, @id)) + #INTERP._eval(Kernel.format('unset %s', @id)) + #INTERP._eval('unset ' + @id) + end + end + alias remove unset + +end + + def numeric + number(value) + end + def numeric=(val) + case val + when Numeric + self.value=(val) + when TkVariable + self.value=(val.numeric) + else + raise ArgumentError, "Numeric is expected" + end + val + end + + def to_i + number(value).to_i + end + + def to_f + number(value).to_f + end + + def to_s + #string(value).to_s + value + end + + def to_sym + value.intern + end + + def list + #tk_split_list(value) + tk_split_simplelist(value) + end + alias to_a list + + def list=(val) + case val + when Array + self.value=(val) + when TkVariable + self.value=(val.list) + else + raise ArgumentError, "Array is expected" + end + val + end + + def inspect + #Kernel.format "#", @id + '#' + end + + def coerce(other) + case other + when TkVariable + [other.value, self.value] + when String + [other, self.to_s] + when Symbol + [other, self.to_sym] + when Integer + [other, self.to_i] + when Float + [other, self.to_f] + when Array + [other, self.to_a] + else + [other, self.value] + end + end + + def &(other) + if other.kind_of?(Array) + self.to_a & other.to_a + else + self.to_i & other.to_i + end + end + def |(other) + if other.kind_of?(Array) + self.to_a | other.to_a + else + self.to_i | other.to_i + end + end + def +(other) + case other + when Array + self.to_a + other + when String + self.value + other + else + begin + number(self.value) + other + rescue + self.value + other.to_s + end + end + end + def -(other) + if other.kind_of?(Array) + self.to_a - other + else + number(self.value) - other + end + end + def *(other) + begin + number(self.value) * other + rescue + self.value * other + end + end + def /(other) + number(self.value) / other + end + def %(other) + begin + number(self.value) % other + rescue + self.value % other + end + end + def **(other) + number(self.value) ** other + end + def =~(other) + self.value =~ other + end + + def ==(other) + case other + when TkVariable + self.equal?(other) + when String + self.to_s == other + when Symbol + self.to_sym == other + when Integer + self.to_i == other + when Float + self.to_f == other + when Array + self.to_a == other + when Hash + self.value == other + else + false + end + end + + def zero? + numeric.zero? + end + def nonzero? + !(numeric.zero?) + end + + def <=>(other) + if other.kind_of?(TkVariable) + begin + val = other.numeric + other = val + rescue + other = other.value + end + end + if other.kind_of?(Numeric) + begin + return self.numeric <=> other + rescue + return self.value <=> other.to_s + end + else + return self.value <=> other + end + end + + def to_eval + @id + end + + def trace_callback(elem, op) + if @trace_var.kind_of? Array + @trace_var.each{|m,e| e.call(self,elem,op) if m.index(op)} + end + if elem.kind_of?(String) && elem != '' + if @trace_elem.kind_of?(Hash) && @trace_elem[elem].kind_of?(Array) + @trace_elem[elem].each{|m,e| e.call(self,elem,op) if m.index(op)} + end + end + end + + def trace(opts, cmd = Proc.new) + @trace_var = [] if @trace_var == nil + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + @trace_var.unshift([opts,cmd]) + if @trace_opts == nil + TkVar_CB_TBL[@id] = self + @trace_opts = opts.dup + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') + end +=end + else + newopts = @trace_opts.dup + opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + self + end + + def trace_element(elem, opts, cmd = Proc.new) + @trace_elem = {} if @trace_elem == nil + @trace_elem[elem] = [] if @trace_elem[elem] == nil + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + @trace_elem[elem].unshift([opts,cmd]) + if @trace_opts == nil + TkVar_CB_TBL[@id] = self + @trace_opts = opts.dup + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + else + newopts = @trace_opts.dup + opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + self + end + + def trace_vinfo + return [] unless @trace_var + @trace_var.dup + end + def trace_vinfo_for_element(elem) + return [] unless @trace_elem + return [] unless @trace_elem[elem] + @trace_elem[elem].dup + end + + def trace_vdelete(opts,cmd) + return self unless @trace_var.kind_of? Array + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + idx = -1 + newopts = '' + @trace_var.each_with_index{|e,i| + if idx < 0 && e[0] == opts && e[1] == cmd + idx = i + next + end + e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + } + if idx >= 0 + @trace_var.delete_at(idx) + else + return self + end + + @trace_elem.each{|elem| + @trace_elem[elem].each{|e| + e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + } + } + + newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + end +=end + @trace_opts.replace(newopts) + if @trace_opts != '' + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + + self + end + + def trace_vdelete_for_element(elem,opts,cmd) + return self unless @trace_elem.kind_of? Hash + return self unless @trace_elem[elem].kind_of? Array + opts = ['r','w','u'].find_all{|c| opts.index(c)}.join('') + idx = -1 + @trace_elem[elem].each_with_index{|e,i| + if idx < 0 && e[0] == opts && e[1] == cmd + idx = i + next + end + } + if idx >= 0 + @trace_elem[elem].delete_at(idx) + else + return self + end + + newopts = '' + @trace_var.each{|e| + e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + } + @trace_elem.each{|elem| + @trace_elem[elem].each{|e| + e[0].each_byte{|c| newopts += c.chr unless newopts.index(c)} + } + } + + newopts = ['r','w','u'].find_all{|c| newopts.index(c)}.join('') + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @id, @trace_opts, 'rb_var') + end +=end + @trace_opts.replace(newopts) + if @trace_opts != '' + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', @id, + @trace_opts, 'rb_var') + end +=end + end + end + + self + end +end + + +class TkVarAccess +# +require 'tk' + +class TkVirtualEvent".freeze].freeze + TkVirtualEventTBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear } + + class PreDefVirtEvent") + PreDefVirtEvent.new(event) + else + fail ArgumentError, "undefined virtual event '<#{event}>'" + end + end + end + + def TkVirtualEvent.info + tk_call_without_enc('event', 'info').split(/\s+/).collect!{|seq| + TkVirtualEvent.getobj(seq[1..-2]) + } + end + + def initialize(*sequences) + @path = @id = TkVirtualEventID.join('') + TkVirtualEventID[1].succ! + add(*sequences) + end + + def add(*sequences) + if sequences != [] + tk_call_without_enc('event', 'add', "<#{@id}>", + *(sequences.collect{|seq| + "<#{tk_event_sequence(seq)}>" + }) ) + TkVirtualEventTBL[@id] = self + end + self + end + + def delete(*sequences) + if sequences == [] + tk_call_without_enc('event', 'delete', "<#{@id}>") + TkVirtualEventTBL.delete(@id) + else + tk_call_without_enc('event', 'delete', "<#{@id}>", + *(sequences.collect{|seq| + "<#{tk_event_sequence(seq)}>" + }) ) + TkVirtualEventTBL.delete(@id) if info == [] + end + self + end + + def info + tk_call_without_enc('event','info',"<#{@id}>").split(/\s+/).collect!{|seq| + l = seq.scan(/<*[^<>]+>*/).collect!{|subseq| + case (subseq) + when /^<<[^<>]+>>$/ + TkVirtualEvent.getobj(subseq[1..-2]) + when /^<[^<>]+>$/ + subseq[1..-2] + else + subseq.split('') + end + }.flatten + (l.size == 1) ? l[0] : l + } + end +end diff --git a/ext/tk/lib/tk/winfo.rb b/ext/tk/lib/tk/winfo.rb new file mode 100644 index 0000000000..a3ce2b2cd2 --- /dev/null +++ b/ext/tk/lib/tk/winfo.rb @@ -0,0 +1,384 @@ +# +# tk/winfo.rb : methods for winfo command +# +require 'tk' + +module TkWinfo + include Tk + extend Tk + + TkCommandNames = ['winfo'.freeze].freeze + + def TkWinfo.atom(name, win=nil) + if win + number(tk_call_without_enc('winfo', 'atom', '-displayof', win, + _get_eval_enc_str(name))) + else + number(tk_call_without_enc('winfo', 'atom', _get_eval_enc_str(name))) + end + end + def winfo_atom(name) + TkWinfo.atom(name, self) + end + + def TkWinfo.atomname(id, win=nil) + if win + _fromUTF8(tk_call_without_enc('winfo', 'atomname', + '-displayof', win, id)) + else + _fromUTF8(tk_call_without_enc('winfo', 'atomname', id)) + end + end + def winfo_atomname(id) + TkWinfo.atomname(id, self) + end + + def TkWinfo.cells(window) + number(tk_call_without_enc('winfo', 'cells', window)) + end + def winfo_cells + TkWinfo.cells self + end + + def TkWinfo.children(window) + list(tk_call_without_enc('winfo', 'children', window)) + end + def winfo_children + TkWinfo.children self + end + + def TkWinfo.classname(window) + tk_call_without_enc('winfo', 'class', window) + end + def winfo_classname + TkWinfo.classname self + end + alias winfo_class winfo_classname + + def TkWinfo.colormapfull(window) + bool(tk_call_without_enc('winfo', 'colormapfull', window)) + end + def winfo_colormapfull + TkWinfo.colormapfull self + end + + def TkWinfo.containing(rootX, rootY, win=nil) + if win + window(tk_call_without_enc('winfo', 'containing', + '-displayof', win, rootX, rootY)) + else + window(tk_call_without_enc('winfo', 'containing', rootX, rootY)) + end + end + def winfo_containing(x, y) + TkWinfo.containing(x, y, self) + end + + def TkWinfo.depth(window) + number(tk_call_without_enc('winfo', 'depth', window)) + end + def winfo_depth + TkWinfo.depth self + end + + def TkWinfo.exist?(window) + bool(tk_call_without_enc('winfo', 'exists', window)) + end + def winfo_exist? + TkWinfo.exist? self + end + + def TkWinfo.fpixels(window, dist) + number(tk_call_without_enc('winfo', 'fpixels', window, dist)) + end + def winfo_fpixels(dist) + TkWinfo.fpixels self, dist + end + + def TkWinfo.geometry(window) + tk_call_without_enc('winfo', 'geometry', window) + end + def winfo_geometry + TkWinfo.geometry self + end + + def TkWinfo.height(window) + number(tk_call_without_enc('winfo', 'height', window)) + end + def winfo_height + TkWinfo.height self + end + + def TkWinfo.id(window) + tk_call_without_enc('winfo', 'id', window) + end + def winfo_id + TkWinfo.id self + end + + def TkWinfo.interps(window=nil) + if window + tk_split_simplelist(tk_call_without_enc('winfo', 'interps', + '-displayof', window)) + else + tk_split_simplelist(tk_call_without_enc('winfo', 'interps')) + end + end + def winfo_interps + TkWinfo.interps self + end + + def TkWinfo.mapped?(window) + bool(tk_call_without_enc('winfo', 'ismapped', window)) + end + def winfo_mapped? + TkWinfo.mapped? self + end + + def TkWinfo.manager(window) + tk_call_without_enc('winfo', 'manager', window) + end + def winfo_manager + TkWinfo.manager self + end + + def TkWinfo.appname(window) + tk_call('winfo', 'name', window) + end + def winfo_appname + TkWinfo.appname self + end + + def TkWinfo.parent(window) + window(tk_call_without_enc('winfo', 'parent', window)) + end + def winfo_parent + TkWinfo.parent self + end + + def TkWinfo.widget(id, win=nil) + if win + window(tk_call_without_enc('winfo', 'pathname', '-displayof', win, id)) + else + window(tk_call_without_enc('winfo', 'pathname', id)) + end + end + def winfo_widget(id) + TkWinfo.widget id, self + end + + def TkWinfo.pixels(window, dist) + number(tk_call_without_enc('winfo', 'pixels', window, dist)) + end + def winfo_pixels(dist) + TkWinfo.pixels self, dist + end + + def TkWinfo.reqheight(window) + number(tk_call_without_enc('winfo', 'reqheight', window)) + end + def winfo_reqheight + TkWinfo.reqheight self + end + + def TkWinfo.reqwidth(window) + number(tk_call_without_enc('winfo', 'reqwidth', window)) + end + def winfo_reqwidth + TkWinfo.reqwidth self + end + + def TkWinfo.rgb(window, color) + list(tk_call_without_enc('winfo', 'rgb', window, color)) + end + def winfo_rgb(color) + TkWinfo.rgb self, color + end + + def TkWinfo.rootx(window) + number(tk_call_without_enc('winfo', 'rootx', window)) + end + def winfo_rootx + TkWinfo.rootx self + end + + def TkWinfo.rooty(window) + number(tk_call_without_enc('winfo', 'rooty', window)) + end + def winfo_rooty + TkWinfo.rooty self + end + + def TkWinfo.screen(window) + tk_call('winfo', 'screen', window) + end + def winfo_screen + TkWinfo.screen self + end + + def TkWinfo.screencells(window) + number(tk_call_without_enc('winfo', 'screencells', window)) + end + def winfo_screencells + TkWinfo.screencells self + end + + def TkWinfo.screendepth(window) + number(tk_call_without_enc('winfo', 'screendepth', window)) + end + def winfo_screendepth + TkWinfo.screendepth self + end + + def TkWinfo.screenheight (window) + number(tk_call_without_enc('winfo', 'screenheight', window)) + end + def winfo_screenheight + TkWinfo.screenheight self + end + + def TkWinfo.screenmmheight(window) + number(tk_call_without_enc('winfo', 'screenmmheight', window)) + end + def winfo_screenmmheight + TkWinfo.screenmmheight self + end + + def TkWinfo.screenmmwidth(window) + number(tk_call_without_enc('winfo', 'screenmmwidth', window)) + end + def winfo_screenmmwidth + TkWinfo.screenmmwidth self + end + + def TkWinfo.screenvisual(window) + tk_call_without_enc('winfo', 'screenvisual', window) + end + def winfo_screenvisual + TkWinfo.screenvisual self + end + + def TkWinfo.screenwidth(window) + number(tk_call_without_enc('winfo', 'screenwidth', window)) + end + def winfo_screenwidth + TkWinfo.screenwidth self + end + + def TkWinfo.server(window) + tk_call('winfo', 'server', window) + end + def winfo_server + TkWinfo.server self + end + + def TkWinfo.toplevel(window) + window(tk_call_without_enc('winfo', 'toplevel', window)) + end + def winfo_toplevel + TkWinfo.toplevel self + end + + def TkWinfo.visual(window) + tk_call_without_enc('winfo', 'visual', window) + end + def winfo_visual + TkWinfo.visual self + end + + def TkWinfo.visualid(window) + tk_call_without_enc('winfo', 'visualid', window) + end + def winfo_visualid + TkWinfo.visualid self + end + + def TkWinfo.visualsavailable(window, includeids=false) + if includeids + list(tk_call_without_enc('winfo', 'visualsavailable', + window, "includeids")) + else + list(tk_call_without_enc('winfo', 'visualsavailable', window)) + end + end + def winfo_visualsavailable(includeids=false) + TkWinfo.visualsavailable self, includeids + end + + def TkWinfo.vrootheight(window) + number(tk_call_without_enc('winfo', 'vrootheight', window)) + end + def winfo_vrootheight + TkWinfo.vrootheight self + end + + def TkWinfo.vrootwidth(window) + number(tk_call_without_enc('winfo', 'vrootwidth', window)) + end + def winfo_vrootwidth + TkWinfo.vrootwidth self + end + + def TkWinfo.vrootx(window) + number(tk_call_without_enc('winfo', 'vrootx', window)) + end + def winfo_vrootx + TkWinfo.vrootx self + end + + def TkWinfo.vrooty(window) + number(tk_call_without_enc('winfo', 'vrooty', window)) + end + def winfo_vrooty + TkWinfo.vrooty self + end + + def TkWinfo.width(window) + number(tk_call_without_enc('winfo', 'width', window)) + end + def winfo_width + TkWinfo.width self + end + + def TkWinfo.x(window) + number(tk_call_without_enc('winfo', 'x', window)) + end + def winfo_x + TkWinfo.x self + end + + def TkWinfo.y(window) + number(tk_call_without_enc('winfo', 'y', window)) + end + def winfo_y + TkWinfo.y self + end + + def TkWinfo.viewable(window) + bool(tk_call_without_enc('winfo', 'viewable', window)) + end + def winfo_viewable + TkWinfo.viewable self + end + + def TkWinfo.pointerx(window) + number(tk_call_without_enc('winfo', 'pointerx', window)) + end + def winfo_pointerx + TkWinfo.pointerx self + end + + def TkWinfo.pointery(window) + number(tk_call_without_enc('winfo', 'pointery', window)) + end + def winfo_pointery + TkWinfo.pointery self + end + + def TkWinfo.pointerxy(window) + list(tk_call_without_enc('winfo', 'pointerxy', window)) + end + def winfo_pointerxy + TkWinfo.pointerxy self + end +end diff --git a/ext/tk/lib/tk/winpkg.rb b/ext/tk/lib/tk/winpkg.rb new file mode 100644 index 0000000000..1d7d473387 --- /dev/null +++ b/ext/tk/lib/tk/winpkg.rb @@ -0,0 +1,136 @@ +# +# tk/winpkg.rb : methods for Tcl/Tk packages for Microsoft Windows +# 2000/11/22 by Hidetoshi Nagai +# +# ATTENTION !! +# This is NOT TESTED. Because I have no test-environment. +# +require 'tk' + +module TkWinDDE + extend Tk + extend TkWinDDE + + TkCommandNames = ['dde'.freeze].freeze + + if self.const_defined? :FORCE_VERSION + tk_call_without_enc('package', 'require', 'dde', FORCE_VERSION) + else + tk_call_without_enc('package', 'require', 'dde') + end + + def servername(topic=None) + tk_call('dde', 'servername', topic) + end + def servername(*args) + if args.size == 0 + tk_call('dde', 'servername') + else + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + force = (keys.delete('force'))? '-force': None + exact = (keys.delete('exact'))? '-exact': None + if keys.size == 0 + tk_call('dde', 'servername', force, exact) + elsif args.size == 0 + tk_call('dde', 'servername', force, exact, *hash_kv(keys)) + else + tk_call('dde', 'servername', force, exact, + *((hash_kv(keys) << '--') + args)) + end + end + end + end + + def execute(service, topic, data) + tk_call('dde', 'execute', service, topic, data) + end + + def async_execute(service, topic, data) + tk_call('dde', '-async', 'execute', service, topic, data) + end + + def poke(service, topic, item, data) + tk_call('dde', 'poke', service, topic, item, data) + end + + def request(service, topic, item) + tk_call('dde', 'request', service, topic, item) + end + + def binary_request(service, topic, item) + tk_call('dde', 'request', '-binary', service, topic, item) + end + + def services(service, topic) + tk_call('dde', 'services', service, topic) + end + + def eval(topic, cmd, *args) + tk_call('dde', 'eval', topic, cmd, *args) + end + + def async_eval(topic, cmd, *args) + tk_call('dde', 'eval', -async, topic, cmd, *args) + end + + module_function :servername, :execute, :async_execute, + :poke, :request, :services, :eval +end + +module TkWinRegistry + extend Tk + extend TkWinRegistry + + TkCommandNames = ['registry'.freeze].freeze + + if self.const_defined? :FORCE_VERSION + tk_call('package', 'require', 'registry', FORCE_VERSION) + else + tk_call('package', 'require', 'registry') + end + + def broadcast(keynam, timeout=nil) + if timeout + tk_call('registry', 'broadcast', keynam, '-timeout', timeout) + else + tk_call('registry', 'broadcast', keynam) + end + end + + def delete(keynam, valnam=None) + tk_call('registry', 'delete', keynam, valnam) + end + + def get(keynam, valnam) + tk_call('registry', 'get', keynam, valnam) + end + + def keys(keynam, pattern=nil) + lst = tk_split_simplelist(tk_call('registry', 'keys', keynam)) + if pattern + lst.find_all{|key| key =~ pattern} + else + lst + end + end + + def set(keynam, valnam=None, data=None, dattype=None) + tk_call('registry', 'set', keynam, valnam, data, dattype) + end + + def type(keynam, valnam) + tk_call('registry', 'type', keynam, valnam) + end + + def values(keynam, pattern=nil) + lst = tk_split_simplelist(tk_call('registry', 'values', keynam)) + if pattern + lst.find_all{|val| val =~ pattern} + else + lst + end + end + + module_function :delete, :get, :keys, :set, :type, :values +end diff --git a/ext/tk/lib/tk/wm.rb b/ext/tk/lib/tk/wm.rb new file mode 100644 index 0000000000..2467656837 --- /dev/null +++ b/ext/tk/lib/tk/wm.rb @@ -0,0 +1,247 @@ +# +# tk/wm.rb : methods for wm command +# +require 'tk' + +module Tk + module Wm + include TkComm + + TkCommandNames = ['wm'.freeze].freeze + + def aspect(*args) + if args.length == 0 + list(tk_call_without_enc('wm', 'aspect', path)) + else + tk_call('wm', 'aspect', path, *args) + self + end + end + def attributes(slot=nil,value=None) + if slot == nil + lst = tk_split_list(tk_call('wm', 'attributes', path)) + info = {} + while key = lst.shift + info[key[1..-1]] = lst.shift + end + info + elsif slot.kind_of? Hash + tk_call('wm', 'attributes', path, *hash_kv(slot)) + self + elsif value == None + tk_call('wm', 'attributes', path, "-#{slot}") + else + tk_call('wm', 'attributes', path, "-#{slot}", value) + self + end + end + def client(name=None) + if name == None + tk_call('wm', 'client', path) + else + name = '' if name == nil + tk_call('wm', 'client', path, name) + self + end + end + def colormapwindows(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'colormapwindows', path)) + else + tk_call_without_enc('wm', 'colormapwindows', path, *args) + self + end + end + def wm_command(value=nil) + if value + tk_call('wm', 'command', path, value) + self + else + #procedure(tk_call('wm', 'command', path)) + tk_call('wm', 'command', path) + end + end + def deiconify(ex = true) + tk_call_without_enc('wm', 'deiconify', path) if ex + self + end + def focusmodel(mode = nil) + if mode + tk_call_without_enc('wm', 'focusmodel', path, mode) + self + else + tk_call_without_enc('wm', 'focusmodel', path) + end + end + def frame + tk_call_without_enc('wm', 'frame', path) + end + def geometry(geom=nil) + if geom + tk_call_without_enc('wm', 'geometry', path, geom) + self + else + tk_call_without_enc('wm', 'geometry', path) + end + end + def wm_grid(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'grid', path)) + else + tk_call_without_enc('wm', 'grid', path, *args) + self + end + end + def group(leader = nil) + if leader + tk_call('wm', 'group', path, leader) + self + else + window(tk_call('wm', 'group', path)) + end + end + def iconbitmap(bmp=nil) + if bmp + tk_call_without_enc('wm', 'iconbitmap', path, bmp) + self + else + image_obj(tk_call_without_enc('wm', 'iconbitmap', path)) + end + end + def iconify(ex = true) + tk_call_without_enc('wm', 'iconify', path) if ex + self + end + def iconmask(bmp=nil) + if bmp + tk_call_without_enc('wm', 'iconmask', path, bmp) + self + else + image_obj(tk_call_without_enc('wm', 'iconmask', path)) + end + end + def iconname(name=nil) + if name + tk_call('wm', 'iconname', path, name) + self + else + tk_call('wm', 'iconname', path) + end + end + def iconposition(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'iconposition', path)) + else + tk_call_without_enc('wm', 'iconposition', path, *args) + self + end + end + def iconwindow(win = nil) + if win + tk_call_without_enc('wm', 'iconwindow', path, win) + self + else + w = tk_call_without_enc('wm', 'iconwindow', path) + (w == '')? nil: window(w) + end + end + def maxsize(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'maxsize', path)) + else + tk_call_without_enc('wm', 'maxsize', path, *args) + self + end + end + def minsize(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'minsize', path)) + else + tk_call_without_enc('wm', 'minsize', path, *args) + self + end + end + def overrideredirect(bool=None) + if bool == None + bool(tk_call_without_enc('wm', 'overrideredirect', path)) + else + tk_call_without_enc('wm', 'overrideredirect', path, bool) + self + end + end + def positionfrom(who=None) + if who == None + r = tk_call_without_enc('wm', 'positionfrom', path) + (r == "")? nil: r + else + tk_call_without_enc('wm', 'positionfrom', path, who) + self + end + end + def protocol(name=nil, cmd=nil) + if cmd + tk_call_without_enc('wm', 'protocol', path, name, cmd) + self + elsif name + result = tk_call_without_enc('wm', 'protocol', path, name) + (result == "")? nil : tk_tcl2ruby(result) + else + tk_split_simplelist(tk_call_without_enc('wm', 'protocol', path)) + end + end + def resizable(*args) + if args.length == 0 + list(tk_call_without_enc('wm', 'resizable', path)).collect{|e| bool(e)} + else + tk_call_without_enc('wm', 'resizable', path, *args) + self + end + end + def sizefrom(who=None) + if who == None + r = tk_call_without_enc('wm', 'sizefrom', path) + (r == "")? nil: r + else + tk_call_without_enc('wm', 'sizefrom', path, who) + self + end + end + def stackorder + list(tk_call('wm', 'stackorder', path)) + end + def stackorder_isabove(win) + bool(tk_call('wm', 'stackorder', path, 'isabove', win)) + end + def stackorder_isbelow(win) + bool(tk_call('wm', 'stackorder', path, 'isbelow', win)) + end + def state(state=nil) + if state + tk_call_without_enc('wm', 'state', path, state) + self + else + tk_call_without_enc('wm', 'state', path) + end + end + def title(str=nil) + if str + tk_call('wm', 'title', path, str) + self + else + tk_call('wm', 'title', path) + end + end + def transient(master=nil) + if master + tk_call_without_enc('wm', 'transient', path, master) + self + else + window(tk_call_without_enc('wm', 'transient', path)) + end + end + def withdraw(ex = true) + tk_call_without_enc('wm', 'withdraw', path) if ex + self + end + end +end diff --git a/ext/tk/lib/tk/xim.rb b/ext/tk/lib/tk/xim.rb new file mode 100644 index 0000000000..b4dacdc331 --- /dev/null +++ b/ext/tk/lib/tk/xim.rb @@ -0,0 +1,122 @@ +# +# tk/xim.rb : control imput_method +# +require 'tk' + +module TkXIM + include Tk + extend Tk + + TkCommandNames = ['imconfigure'.freeze].freeze + + def TkXIM.useinputmethods(value = None, window = nil) + if value == None + if window + bool(tk_call_without_enc('tk', 'useinputmethods', + '-displayof', window)) + else + bool(tk_call_without_enc('tk', 'useinputmethods')) + end + else + if window + bool(tk_call_without_enc('tk', 'useinputmethods', + '-displayof', window, value)) + else + bool(tk_call_without_enc('tk', 'useinputmethods', value)) + end + end + end + + def TkXIM.useinputmethods_displayof(window, value = None) + TkXIM.useinputmethods(value, window) + end + + def TkXIM.caret(window, keys=nil) + if keys + tk_call_without_enc('tk', 'caret', window, *hash_kv(keys)) + self + else + lst = tk_split_list(tk_call_without_enc('tk', 'caret', window)) + info = {} + while key = lst.shift + info[key[1..-1]] = lst.shift + end + info + end + end + + def TkXIM.configure(window, slot, value=None) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot.kind_of? Hash + tk_call('imconfigure', window, *hash_kv(slot)) + else + tk_call('imconfigure', window, "-#{slot}", value) + end + end + rescue + end + end + + def TkXIM.configinfo(window, slot=nil) + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot + conf = tk_split_list(tk_call('imconfigure', window, "-#{slot}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_list(tk_call('imconfigure', window)).collect{|conf| + conf[0] = conf[0][1..-1] + conf + } + end + else + [] + end + rescue + [] + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + TkXIM.current_configinfo(window, slot) + end + end + + def TkXIM.current_configinfo(window, slot=nil) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot + conf = tk_split_list(tk_call('imconfigure', window, "-#{slot}")) + { conf[0][1..-1] => conf[1] } + else + ret = {} + tk_split_list(tk_call('imconfigure', window)).each{|conf| + ret[conf[0][1..-1]] = conf[1] + } + ret + end + else + {} + end + rescue + {} + end + end + + def useinputmethods(value=None) + TkXIM.useinputmethods(value, self) + end + + def caret(keys=nil) + TkXIM.caret(self, keys=nil) + end + + def imconfigure(slot, value=None) + TkXIM.configure(self, slot, value) + end + + def imconfiginfo(slot=nil) + TkXIM.configinfo(self, slot) + end +end diff --git a/ext/tk/lib/tkafter.rb b/ext/tk/lib/tkafter.rb index 53e78b8808..f65945884c 100644 --- a/ext/tk/lib/tkafter.rb +++ b/ext/tk/lib/tkafter.rb @@ -1,414 +1,4 @@ # -# tkafter.rb : methods for Tcl/Tk after command +# tkafter.rb - load tk/after.rb # -# $Id$ -# -require 'tk' - -class TkTimer - include TkCore - extend TkCore - - TkCommandNames = ['after'.freeze].freeze - - Tk_CBID = ['a'.freeze, '00000'.taint].freeze - Tk_CBTBL = {}.taint - - TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL') - if {[set st [catch {ruby [format "TkTimer.callback %%Q!%s!" $id]} ret]] != 0} { - return -code $st $ret - } { - return $ret - } - EOL - - - ############################### - # class methods - ############################### - def self.callback(obj_id) - @after_id = nil - ex_obj = Tk_CBTBL[obj_id] - return "" if ex_obj == nil; # canceled - ex_obj.cb_call - end - - def self.info - tk_call('after', 'info').split(' ').collect!{|id| - ret = Tk_CBTBL.find{|key,val| val.after_id == id} - (ret == nil)? id: ret[1] - } - end - - ############################### - # instance methods - ############################### - def do_callback - @in_callback = true - begin - @return_value = @current_proc.call(self) - rescue Exception => e - if @cancel_on_exception - cancel - @return_value = e - return e - else - fail e - end - end - if @set_next - set_next_callback(@current_args) - else - @set_next = true - end - @in_callback = false - @return_value - end - - def set_callback(sleep, args=nil) - @after_script = "rb_after #{@id}" - @after_id = tk_call('after', sleep, @after_script) - @current_args = args - @current_script = [sleep, @after_script] - self - end - - def set_next_callback(args) - if @running == false || @proc_max == 0 || @do_loop == 0 - Tk_CBTBL.delete(@id) ;# for GC - @running = false - @wait_var.value = 0 - return - end - if @current_pos >= @proc_max - if @do_loop < 0 || (@do_loop -= 1) > 0 - @current_pos = 0 - else - Tk_CBTBL.delete(@id) ;# for GC - @running = false - @wait_var.value = 0 - return - end - end - - @current_args = args - - if @sleep_time.kind_of? Proc - sleep = @sleep_time.call(self) - else - sleep = @sleep_time - end - @current_sleep = sleep - - cmd, *cmd_args = @loop_proc[@current_pos] - @current_pos += 1 - @current_proc = cmd - - set_callback(sleep, cmd_args) - end - - def initialize(*args) - @id = Tk_CBID.join - Tk_CBID[1].succ! - - @wait_var = TkVariable.new(0) - - @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback)) - - @set_next = true - - @init_sleep = 0 - @init_proc = nil - @init_args = [] - - @current_script = [] - @current_proc = nil - @current_args = nil - @return_value = nil - - @sleep_time = 0 - @current_sleep = 0 - @loop_exec = 0 - @do_loop = 0 - @loop_proc = [] - @proc_max = 0 - @current_pos = 0 - - @after_id = nil - @after_script = nil - - @cancel_on_exception = true - - set_procs(*args) if args != [] - - @running = false - @in_callback = false - end - - attr :after_id - attr :after_script - attr :current_proc - attr :current_args - attr :current_sleep - alias :current_interval :current_sleep - attr :return_value - - attr_accessor :loop_exec - - def cb_call - @cb_cmd.call - end - - def get_procs - [@init_sleep, @init_proc, @init_args, @sleep_time, @loop_exec, @loop_proc] - end - - def current_status - [@running, @current_sleep, @current_proc, @current_args, - @do_loop, @cancel_on_exception] - end - - def cancel_on_exception? - @cancel_on_exception - end - - def cancel_on_exception=(mode) - @cancel_on_exception = mode - self - end - - def running? - @running - end - - def loop_rest - @do_loop - end - - def loop_rest=(rest) - @do_loop = rest - self - end - - def set_procs(interval, loop_exec, *procs) - if !interval == 'idle' \ - && !interval.kind_of?(Integer) && !interval.kind_of?(Proc) - fail Kernel.format("%s need to be Integer or Proc", interval.inspect) - end - @sleep_time = interval - - @loop_proc = [] - procs.each{|e| - if e.kind_of? Proc - @loop_proc.push([e]) - else - @loop_proc.push(e) - end - } - @proc_max = @loop_proc.size - @current_pos = 0 - - @do_loop = 0 - if loop_exec - if loop_exec.kind_of?(Integer) && loop_exec < 0 - @loop_exec = -1 - elsif loop_exec == nil || loop_exec == false || loop_exec == 0 - @loop_exec = 1 - else - if not loop_exec.kind_of?(Integer) - fail Kernel.format("%s need to be Integer", loop_exec.inspect) - end - @loop_exec = loop_exec - end - @do_loop = @loop_exec - end - - self - end - - def add_procs(*procs) - procs.each{|e| - if e.kind_of? Proc - @loop_proc.push([e]) - else - @loop_proc.push(e) - end - } - @proc_max = @loop_proc.size - - self - end - - def delete_procs(*procs) - procs.each{|e| - if e.kind_of? Proc - @loop_proc.delete([e]) - else - @loop_proc.delete(e) - end - } - @proc_max = @loop_proc.size - - cancel if @proc_max == 0 - - self - end - - def delete_at(n) - @loop_proc.delete_at(n) - @proc_max = @loop_proc.size - cancel if @proc_max == 0 - self - end - - def set_start_proc(sleep, init_proc, *init_args) - if !sleep == 'idle' && !sleep.kind_of?(Integer) - fail Kernel.format("%s need to be Integer", sleep.inspect) - end - @init_sleep = sleep - @init_proc = init_proc - @init_args = init_args - self - end - - def start(*init_args) - return nil if @running - - Tk_CBTBL[@id] = self - @do_loop = @loop_exec - @current_pos = 0 - - argc = init_args.size - if argc > 0 - sleep = init_args.shift - if !sleep == 'idle' && !sleep.kind_of?(Integer) - fail Kernel.format("%s need to be Integer", sleep.inspect) - end - @init_sleep = sleep - end - @init_proc = init_args.shift if argc > 1 - @init_args = init_args if argc > 0 - - @current_sleep = @init_sleep - @running = true - if @init_proc - if not @init_proc.kind_of? Proc - fail Kernel.format("%s need to be Proc", @init_proc.inspect) - end - @current_proc = @init_proc - set_callback(@init_sleep, @init_args) - @set_next = false if @in_callback - else - set_next_callback(@init_args) - end - - self - end - - def reset(*reset_args) - restart() if @running - - if @init_proc - @return_value = @init_proc.call(self) - else - @return_value = nil - end - - @current_pos = 0 - @current_args = @init_args - @set_next = false if @in_callback - - self - end - - def restart(*restart_args) - cancel if @running - if restart_args == [] - start(@init_sleep, @init_proc, *@init_args) - else - start(*restart_args) - end - end - - def cancel - @running = false - @wait_var.value = 0 - tk_call 'after', 'cancel', @after_id if @after_id - @after_id = nil - Tk_CBTBL.delete(@id) ;# for GC - self - end - alias stop cancel - - def continue(wait=nil) - fail RuntimeError, "is already running" if @running - sleep, cmd = @current_script - fail RuntimeError, "no procedure to continue" unless cmd - if wait - if not wait.kind_of? Integer - fail RuntimeError, Kernel.format("%s need to be Integer", wait.inspect) - end - sleep = wait - end - Tk_CBTBL[@id] = self - @running = true - @after_id = tk_call('after', sleep, cmd) - self - end - - def skip - fail RuntimeError, "is not running now" unless @running - cancel - Tk_CBTBL[@id] = self - @running = true - set_next_callback(@current_args) - self - end - - def info - if @after_id - inf = tk_split_list(tk_call('after', 'info', @after_id)) - [Tk_CBTBL[inf[0][1]], inf[1]] - else - nil - end - end - - def wait(on_thread = true, check_root = false) - if $SAFE >= 4 - fail SecurityError, "can't wait timer at $SAFE >= 4" - end - - unless @running - if @return_value.kind_of?(Exception) - fail @return_value - else - return @return_value - end - end - - @wait_var.wait(on_thread, check_root) - if @return_value.kind_of?(Exception) - fail @return_value - else - @return_value - end - end - def eventloop_wait(check_root = false) - wait(false, check_root) - end - def thread_wait(check_root = false) - wait(true, check_root) - end - def tkwait(on_thread = true) - wait(on_thread, true) - end - def eventloop_tkwait - wait(false, true) - end - def thread_tkwait - wait(true, true) - end -end - -TkAfter = TkTimer +require 'tk/timer' diff --git a/ext/tk/lib/tkbgerror.rb b/ext/tk/lib/tkbgerror.rb index 760a3901b3..deba7a57fa 100644 --- a/ext/tk/lib/tkbgerror.rb +++ b/ext/tk/lib/tkbgerror.rb @@ -1,29 +1,4 @@ # -# tkbgerror -- bgerror ( tkerror ) module -# 1998/07/16 by Hidetoshi Nagai +# tkbgerror.rb - load tk/bgerror.rb # -require 'tk' - -module TkBgError - extend Tk - - TkCommandNames = ['bgerror'.freeze].freeze - - def bgerror(message) - tk_call 'bgerror', message - end - alias tkerror bgerror - alias show bgerror - module_function :bgerror, :tkerror, :show - - def set_handler(hdlr = Proc.new) #==> handler :: proc{|msg| ...body... } - tk_call('proc', 'bgerror', 'msg', install_cmd(hdlr) + ' $msg') - end - def set_default - begin - tk_call('rename', 'bgerror', '') - rescue RuntimeError - end - end - module_function :set_handler, :set_default -end +require 'tk/bgerror' diff --git a/ext/tk/lib/tkcanvas.rb b/ext/tk/lib/tkcanvas.rb index ccb02c0564..9524614291 100644 --- a/ext/tk/lib/tkcanvas.rb +++ b/ext/tk/lib/tkcanvas.rb @@ -1,1021 +1,4 @@ # -# tkcanvas.rb - Tk canvas classes -# $Date$ -# by Yukihiro Matsumoto -# $Date$ -# by Hidetoshi Nagai - -require "tk" -require 'tkfont' - -module TkTreatCItemFont - include TkTreatItemFont - - ItemCMD = ['itemconfigure'.freeze, TkComm::None].freeze - def __conf_cmd(idx) - ItemCMD[idx] - end - - def __item_pathname(tagOrId) - if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag) - self.path + ';' + tagOrId.id.to_s - else - self.path + ';' + tagOrId.to_s - end - end - - private :__conf_cmd, :__item_pathname -end - -class TkCanvasvalue}) - end - else - tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value - end - end - self - end -# def itemconfigure(tagOrId, key, value=None) -# if key.kind_of? Hash -# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key) -# else -# tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value -# end -# end -# def itemconfigure(tagOrId, keys) -# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys) -# end - - def itemconfiginfo(tagOrId, key=nil) - if key - case key.to_s - when 'dash', 'activedash', 'disableddash' - conf = tk_split_simplelist(tk_send('itemconfigure', - tagid(tagOrId), "-#{key}")) - if conf[3] && conf[3] =~ /^[0-9]/ - conf[3] = list(conf[3]) - end - if conf[4] && conf[4] =~ /^[0-9]/ - conf[4] = list(conf[4]) - end - when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' - conf = tk_split_simplelist(tk_send('itemconfigure', - tagid(tagOrId), "-#{key}")) - when 'font', 'kanjifont' - conf = tk_split_simplelist(tk_send('itemconfigure', - tagid(tagOrId),"-#{key}") ) - conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4]) - else - conf = tk_split_list(tk_send('itemconfigure', - tagid(tagOrId), "-#{key}")) - end - conf[0] = conf[0][1..-1] - conf - else - ret = tk_split_simplelist(tk_send('itemconfigure', - tagid(tagOrId))).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' - when 'dash', 'activedash', 'disableddash' - if conf[3] && conf[3] =~ /^[0-9]/ - conf[3] = list(conf[3]) - end - if conf[4] && conf[4] =~ /^[0-9]/ - conf[4] = list(conf[4]) - end - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - fontconf = ret.assoc('font') - if fontconf - ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} - fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4]) - ret.push(fontconf) - else - ret - end - end - end - - def lower(tag, below=None) - tk_send 'lower', tagid(tag), tagid(below) - self - end - - def move(tag, x, y) - tk_send 'move', tagid(tag), x, y - self - end - - def postscript(keys) - tk_send "postscript", *hash_kv(keys) - end - - def raise(tag, above=None) - tk_send 'raise', tagid(tag), tagid(above) - self - end - - def scale(tag, x, y, xs, ys) - tk_send 'scale', tagid(tag), x, y, xs, ys - self - end - - def scan_mark(x, y) - tk_send 'scan', 'mark', x, y - self - end - def scan_dragto(x, y) - tk_send 'scan', 'dragto', x, y - self - end - - def select(mode, *args) - r = tk_send('select', mode, *args) - (mode == 'item')? TkcItem.id2obj(self, r): self - end - def select_adjust(tagOrId, index) - select('adjust', tagid(tagOrId), index) - end - def select_clear - select('clear') - end - def select_from(tagOrId, index) - select('from', tagid(tagOrId), index) - end - def select_item - select('item') - end - def select_to(tagOrId, index) - select('to', tagid(tagOrId), index) - end - - def itemtype(tag) - TkcItem.type2class(tk_send('type', tagid(tag))) - end -end - -module TkcTagAccess - include TkComm - include TkTreatTagFont - - def addtag(tag) - @c.addtag(tag, 'with', @id) - self - end - - def bbox - @c.bbox(@id) - end - - def bind(seq, cmd=Proc.new, args=nil) - @c.itembind @id, seq, cmd, args - self - end - - def bind_append(seq, cmd=Proc.new, args=nil) - @c.itembind_append @id, seq, cmd, args - self - end - - def bind_remove(seq) - @c.itembind_remove @id, seq - self - end - - def bindinfo(seq=nil) - @c.itembindinfo @id, seq - end - - def cget(option) - @c.itemcget @id, option - end - - def configure(key, value=None) - @c.itemconfigure @id, key, value - self - end -# def configure(keys) -# @c.itemconfigure @id, keys -# end - - def configinfo(key=nil) - @c.itemconfiginfo @id, key - end - - def coords(*args) - @c.coords @id, *args - end - - def dchars(first, last=None) - @c.dchars @id, first, last - self - end - - def dtag(tag_to_del=None) - @c.dtag @id, tag_to_del - self - end - - def find - @c.find 'withtag', @id - end - alias list find - - def focus - @c.itemfocus @id - end - - def gettags - @c.gettags @id - end - - def icursor(index) - @c.icursor @id, index - self - end - - def index(index) - @c.index @id, index - end - - def insert(beforethis, string) - @c.insert @id, beforethis, string - self - end - - def lower(belowthis=None) - @c.lower @id, belowthis - self - end - - def move(xamount, yamount) - @c.move @id, xamount, yamount - self - end - - def raise(abovethis=None) - @c.raise @id, abovethis - self - end - - def scale(xorigin, yorigin, xscale, yscale) - @c.scale @id, xorigin, yorigin, xscale, yscale - self - end - - def select_adjust(index) - @c.select('adjust', @id, index) - self - end - def select_from(index) - @c.select('from', @id, index) - self - end - def select_to(index) - @c.select('to', @id, index) - self - end - - def itemtype - @c.itemtype @id - end - - # Following operators support logical expressions of canvas tags - # (for Tk8.3+). - # If tag1.path is 't1' and tag2.path is 't2', then - # ltag = tag1 & tag2; ltag.path => "(t1)&&(t2)" - # ltag = tag1 | tag2; ltag.path => "(t1)||(t2)" - # ltag = tag1 ^ tag2; ltag.path => "(t1)^(t2)" - # ltag = - tag1; ltag.path => "!(t1)" - def & (tag) - if tag.kind_of? TkObject - TkcTagString.new(@c, '(' + @id + ')&&(' + tag.path + ')') - else - TkcTagString.new(@c, '(' + @id + ')&&(' + tag.to_s + ')') - end - end - - def | (tag) - if tag.kind_of? TkObject - TkcTagString.new(@c, '(' + @id + ')||(' + tag.path + ')') - else - TkcTagString.new(@c, '(' + @id + ')||(' + tag.to_s + ')') - end - end - - def ^ (tag) - if tag.kind_of? TkObject - TkcTagString.new(@c, '(' + @id + ')^(' + tag.path + ')') - else - TkcTagString.new(@c, '(' + @id + ')^(' + tag.to_s + ')') - end - end - - def -@ - TkcTagString.new(@c, '!(' + @id + ')') - end -end - -class TkcTagvalue, ...} for the message text - return nil - end - def msgframe_config - # returns a Hash {option=>value, ...} for the message text frame - return nil - end - def bitmap - # returns a bitmap name or a bitmap file path - # (@ + path ; e.g. '@/usr/share/bitmap/sample.xbm') - return "info" - end - def bitmap_config - # returns nil or a Hash {option=>value, ...} for the bitmap - return nil - end - def default_button - # returns a default button's number or name - # if nil or null string, set no-default - return 0 - end - def buttons - #return "BUTTON1 BUTTON2" - return ["BUTTON1", "BUTTON2"] - end - def button_configs(num) - # returns nil / Proc / Array or Hash (see _set_button_config) - return nil - end - def btnframe_config - # returns nil or a Hash {option=>value, ...} for the button frame - return nil - end -end - - # -# TkDialog : with showing at initialize +# tkdialog.rb - load tk/dialog.rb # -class TkDialog < TkDialog2 - def self.show(*args) - self.new(*args) - end - - def initialize(*args) - super(*args) - show - end -end - - -# -# dialog for warning -# -class TkWarning2 < TkDialog2 - def initialize(parent = nil, mes = nil) - if !mes - if parent.kind_of? TkWindow - mes = "" - else - mes = parent.to_s - parent = nil - end - end - super(parent, :message=>mes) - end - - def show(mes = nil) - mes_bup = @message - @message = mes if mes - ret = super() - @message = mes_bup - ret - end - - ####### - private - - def title - return "WARNING"; - end - def bitmap - return "warning"; - end - def default_button - return 0; - end - def buttons - return "OK"; - end -end - -class TkWarning < TkWarning2 - def self.show(*args) - self.new(*args) - end - def initialize(*args) - super(*args) - show - end -end +require 'tk/dialog' diff --git a/ext/tk/lib/tkentry.rb b/ext/tk/lib/tkentry.rb index fe9a7b6277..2dcfcab5da 100644 --- a/ext/tk/lib/tkentry.rb +++ b/ext/tk/lib/tkentry.rb @@ -1,292 +1,4 @@ # -# tkentry.rb - Tk entry classes -# $Date$ -# by Yukihiro Matsumoto - -require 'tk.rb' - -class TkEntry'Helvetica'.freeze, - 'size'=>-12, 'weight'=>'bold'.freeze} - #knj = 'k14' - #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0' - knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0' - when 'windows' - ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} - knj = 'mincho' - when 'macintosh' - ltn = 'system' - knj = 'mincho' - else # unknown - ltn = 'Helvetica' - knj = 'mincho' - end - end - rescue - ltn = 'Helvetica' - knj = 'mincho' - end - - else # not JAPANIZED_TK - begin - platform = tk_call('set', 'tcl_platform(platform)') - case platform - when 'unix' - ltn = {'family'=>'Helvetica'.freeze, - 'size'=>-12, 'weight'=>'bold'.freeze} - #knj = 'k14' - #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0' - knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0' - when 'windows' - ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} - knj = 'mincho' - when 'macintosh' - ltn = 'system' - knj = 'mincho' - else # unknown - ltn = 'Helvetica' - knj = 'mincho' - end - rescue - ltn = 'Helvetica' - knj = 'mincho' - end - - knj = ltn - end - - DEFAULT_LATIN_FONT_NAME = ltn.freeze - DEFAULT_KANJI_FONT_NAME = knj.freeze - - else # unknown version - DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze - DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze - - end - - if $DEBUG - print "default latin font = "; p DEFAULT_LATIN_FONT_NAME - print "default kanji font = "; p DEFAULT_KANJI_FONT_NAME - end - - - ################################### - class DescendantFont - def initialize(compound, type) - unless compound.kind_of?(TkFont) - fail ArgumentError, "a TkFont object is expected for the 1st argument" - end - @compound = compound - case type - when 'kanji', 'latin', 'ascii' - @type = type - else - fail ArgumentError, "unknown type '#{type}'" - end - end - - def dup - fail RuntimeError, "cannot dupulicate a descendant font" - end - def clone - fail RuntimeError, "cannot clone a descendant font" - end - - def to_eval - @compound.__send__(@type + '_font_id') - end - def font - @compound.__send__(@type + '_font_id') - end - - def [](slot) - @compound.__send__(@type + '_configinfo', slot) - end - def []=(slot, value=None) - @compound.__send__(@type + '_configure', slot, value) - end - - def method_missing(id, *args) - @compound.__send__(@type + '_' + id.id2name, *args) - end - end - - - ################################### - # class methods - ################################### - def TkFont.families(window=nil) - case (Tk::TK_VERSION) - when /^4\.*/ - ['fixed'] - - when /^8\.*/ - if window - tk_split_simplelist(tk_call('font', 'families', '-displayof', window)) - else - tk_split_simplelist(tk_call('font', 'families')) - end - end - end - - def TkFont.names - case (Tk::TK_VERSION) - when /^4\.*/ - r = ['fixed'] - r += ['a14', 'k14'] if JAPANIZED_TK - Tk_FontNameTBL.each_value{|obj| r.push(obj)} - r | [] - - when /^8\.*/ - tk_split_simplelist(tk_call('font', 'names')) - - end - end - - def TkFont.create_copy(font) - fail 'source-font must be a TkFont object' unless font.kind_of? TkFont - keys = {} - font.configinfo.each{|key,value| keys[key] = value } - TkFont.new(font.latin_font_id, font.kanji_font_id, keys) - end - - def TkFont.get_obj(name) - if name =~ /^(@font[0-9]+)(|c|l|k)$/ - Tk_FontNameTBL[$1] - else - nil - end - end - - def TkFont.init_widget_font(path, *args) - case (Tk::TK_VERSION) - when /^4\.*/ - conf = tk_split_simplelist(tk_call(*args)). - find_all{|prop| prop[0..5]=='-font ' || prop[0..10]=='-kanjifont '}. - collect{|prop| tk_split_simplelist(prop)} - if font_inf = conf.assoc('-font') - ltn = font_inf[4] - ltn = nil if ltn == [] - else - #ltn = nil - raise RuntimeError, "unknown option '-font'" - end - if font_inf = conf.assoc('-kanjifont') - knj = font_inf[4] - knj = nil if knj == [] - else - knj = nil - end - TkFont.new(ltn, knj).call_font_configure(path, *(args + [{}])) - - when /^8\.*/ - font_prop = tk_split_simplelist(tk_call(*args)).find{|prop| - prop[0..5] == '-font ' - } - unless font_prop - raise RuntimeError, "unknown option '-font'" - end - fnt = tk_split_simplelist(font_prop)[4] - if fnt == "" - TkFont.new(nil, nil).call_font_configure(path, *(args + [{}])) - else - begin - compound = tk_split_simplelist( - Hash[*tk_split_simplelist(tk_call('font', 'configure', - fnt))].collect{|key,value| - [key[1..-1], value] - }.assoc('compound')[1]) - rescue - compound = [] - end - if compound == [] - #TkFont.new(fnt, DEFAULT_KANJI_FONT_NAME) \ - #.call_font_configure(path, *(args + [{}])) - TkFont.new(fnt).call_font_configure(path, *(args + [{}])) - else - TkFont.new(compound[0], compound[1]) \ - .call_font_configure(path, *(args + [{}])) - end - end - end - end - - def TkFont.used_on(path=nil) - if path - Tk_FontUseTBL[path] - else - Tk_FontUseTBL.values | [] - end - end - - def TkFont.failsafe(font) - begin - if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK - tk_call('font', 'failsafe', font) - end - rescue - end - end - - ################################### - # instance methods - ################################### - private - ################################### - def initialize(ltn=nil, knj=nil, keys=nil) - @id = Tk_FontID.join - Tk_FontID[1].succ! - Tk_FontNameTBL[@id] = self - - @latin_desscendant = nil - @kanji_desscendant = nil - - if knj.kind_of?(Hash) && !keys - keys = knj - knj = nil - end - - # compound font check - if Tk::TK_VERSION == '8.0' && JAPANIZED_TK - begin - compound = tk_split_simplelist(tk_call('font', 'configure', - ltn, '-compound')) - if knj == nil - if compound != [] - ltn, knj = compound - end - else - if compound != [] - ltn = compound[0] - end - compound = tk_split_simplelist(tk_call('font', 'configure', - knj, '-compound')) - if compound != [] - knj = compound[1] - end - end - rescue - end - end - - if ltn - knj = ltn if JAPANIZED_TK && !knj - else - ltn = DEFAULT_LATIN_FONT_NAME - knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj - end - - create_compoundfont(ltn, knj, keys) - end - - def _get_font_info_from_hash(font) - font = _symbolkey2str(font) - foundry = (info = font['foundry'] .to_s)? info: '*' - family = (info = font['family'] .to_s)? info: '*' - weight = (info = font['weight'] .to_s)? info: '*' - slant = (info = font['slant'] .to_s)? info: '*' - swidth = (info = font['swidth'] .to_s)? info: '*' - adstyle = (info = font['adstyle'] .to_s)? info: '*' - pixels = (info = font['pixels'] .to_s)? info: '*' - points = (info = font['points'] .to_s)? info: '*' - resx = (info = font['resx'] .to_s)? info: '*' - resy = (info = font['resy'] .to_s)? info: '*' - space = (info = font['space'] .to_s)? info: '*' - avgWidth = (info = font['avgWidth'].to_s)? info: '*' - charset = (info = font['charset'] .to_s)? info: '*' - encoding = (info = font['encoding'].to_s)? info: '*' - - [foundry, family, weight, slant, swidth, adstyle, - pixels, points, resx, resy, space, avgWidth, charset, encoding] - end - - def create_latinfont_tk4x(font) - if font.kind_of? Hash - @latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-' - - elsif font.kind_of? Array - finfo = {} - finfo['family'] = font[0].to_s - if font[1] - fsize = font[1].to_s - if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ - if $1 == '-' - finfo['pixels'] = $2 - else - finfo['points'] = $2 - end - else - finfo['points'] = '13' - end - end - font[2..-1].each{|style| - case (style) - when 'normal' - finfo['weight'] = style - when 'bold' - finfo['weight'] = style - when 'roman' - finfo['slant'] = 'r' - when 'italic' - finfo['slant'] = 'i' - end - } - - @latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' - - elsif font.kind_of? TkFont - @latinfont = font.latin_font - - else - if font - @latinfont = font - else - @latinfont = DEFAULT_LATIN_FONT_NAME - end - - end - end - - def create_kanjifont_tk4x(font) - unless JAPANIZED_TK - @kanjifont = "" - return - end - - if font.kind_of? Hash - @kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-' - - elsif font.kind_of? Array - finfo = {} - finfo['family'] = font[0].to_s - if font[1] - fsize = font[1].to_s - if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ - if $1 == '-' - finfo['pixels'] = $2 - else - finfo['points'] = $2 - end - else - finfo['points'] = '13' - end - end - font[2..-1].each{|style| - case (style) - when 'normal' - finfo['weight'] = style - when 'bold' - finfo['weight'] = style - when 'roman' - finfo['slant'] = 'r' - when 'italic' - finfo['slant'] = 'i' - end - } - - @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' - elsif font.kind_of? TkFont - @kanjifont = font.kanji_font_id - else - if font - @kanjifont = font - else - @kanjifont = DEFAULT_KANJI_FONT_NAME - end - end - end - - def create_compoundfont_tk4x(ltn, knj, keys) - create_latinfont(ltn) - create_kanjifont(knj) - - if JAPANIZED_TK - @compoundfont = [[@latinfont], [@kanjifont]] - @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} - else - @compoundfont = @latinfont - @fontslot = {'font'=>@latinfont} - end - end - - def create_latinfont_tk8x(font) - @latinfont = @id + 'l' - - if JAPANIZED_TK - if font.kind_of? Hash - if font[:charset] || font['charset'] - tk_call('font', 'create', @latinfont, *hash_kv(font)) - else - tk_call('font', 'create', @latinfont, - '-charset', 'iso8859', *hash_kv(font)) - end - elsif font.kind_of? Array - tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font)) - tk_call('font', 'configure', @latinfont, '-charset', 'iso8859') - elsif font.kind_of? TkFont - tk_call('font', 'create', @latinfont, '-copy', font.latin_font) - elsif font - tk_call('font', 'create', @latinfont, '-copy', font, - '-charset', 'iso8859') - else - tk_call('font', 'create', @latinfont, '-charset', 'iso8859') - end - else - if font.kind_of? Hash - tk_call('font', 'create', @latinfont, *hash_kv(font)) - else - keys = {} - if font.kind_of? Array - actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} - elsif font.kind_of? TkFont - actual_core(font.latin_font).each{|key,val| keys[key] = val} - elsif font - actual_core(font).each{|key,val| keys[key] = val} - end - tk_call('font', 'create', @latinfont, *hash_kv(keys)) - end - - if font && @compoundfont - keys = {} - actual_core(@latinfont).each{|key,val| keys[key] = val} - tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) - end - end - end - - def create_kanjifont_tk8x(font) - @kanjifont = @id + 'k' - - if JAPANIZED_TK - if font.kind_of? Hash - if font[:charset] || font['charset'] - tk_call('font', 'create', @kanjifont, *hash_kv(font)) - else - tk_call('font', 'create', @kanjifont, - '-charset', 'jisx0208.1983', *hash_kv(font)) - end - elsif font.kind_of? Array - tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font)) - tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983') - elsif font.kind_of? TkFont - tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font_id) - elsif font - tk_call('font', 'create', @kanjifont, '-copy', font, - '-charset', 'jisx0208.1983') - else - tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') - end - # end of JAPANIZED_TK - - else - if font.kind_of? Hash - tk_call('font', 'create', @kanjifont, *hash_kv(font)) - else - keys = {} - if font.kind_of? Array - actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} - elsif font.kind_of? TkFont - actual_core(font.kanji_font_id).each{|key,val| keys[key] = val} - elsif font - actual_core(font).each{|key,val| keys[key] = val} - end - tk_call('font', 'create', @kanjifont, *hash_kv(keys)) - end - - if font && @compoundfont - keys = {} - actual_core(@kanjifont).each{|key,val| keys[key] = val} - tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) - end - end - end - - def create_compoundfont_tk8x(ltn, knj, keys) - create_latinfont(ltn) - create_kanjifont(knj) - - @compoundfont = @id + 'c' - if JAPANIZED_TK - unless keys - keys = {} - else - keys = keys.dup - end - if (tk_call('font', 'configure', @latinfont, '-underline') == '1' && - tk_call('font', 'configure', @kanjifont, '-underline') == '1' && - !keys.key?('underline')) - keys['underline'] = true - end - if (tk_call('font', 'configure', @latinfont, '-overstrike') == '1' && - tk_call('font', 'configure', @kanjifont, '-overstrike') == '1' && - !keys.key?('overstrike')) - keys['overstrike'] = true - end - - @fontslot = {'font'=>@compoundfont} - begin - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) - rescue RuntimeError => e - if ltn == knj - if e.message =~ /kanji font .* specified/ - tk_call('font', 'delete', @latinfont) - create_latinfont(DEFAULT_LATIN_FONT_NAME) - opts = [] - Hash[*(tk_split_simplelist(tk_call('font', 'configure', - @kanjifont)))].each{|k,v| - case k - when '-size', '-weight', '-slant', '-underline', '-overstrike' - opts << k << v - end - } - tk_call('font', 'configure', @latinfont, *opts) - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) - - elsif e.message =~ /ascii font .* specified/ - tk_call('font', 'delete', @kanjifont) - create_kanjifont(DEFAULT_KANJI_FONT_NAME) - opts = [] - Hash[*(tk_split_simplelist(tk_call('font', 'configure', - @latinfont)))].each{|k,v| - case k - when '-size', '-weight', '-slant', '-underline', '-overstrike' - opts << k << v - end - } - tk_call('font', 'configure', @kanjifont, *opts) - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) - - else - raise e - end - else - raise e - end - end - else - tk_call('font', 'create', @compoundfont) - - latinkeys = {} - begin - actual_core(@latinfont).each{|key,val| latinkeys[key] = val} - rescue - latinkeys {} - end - if latinkeys != {} - tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) - end - - if knj - kanjikeys = {} - begin - actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val} - rescue - kanjikeys {} - end - if kanjikeys != {} - tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys)) - end - end - - @fontslot = {'font'=>@compoundfont} - tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) - end - end - - def actual_core_tk4x(font, window=nil, option=nil) - # dummy - if option - "" - else - [['family',[]], ['size',[]], ['weight',[]], ['slant',[]], - ['underline',[]], ['overstrike',[]], ['charset',[]], - ['pointadjust',[]]] - end - end - - def actual_core_tk8x(font, window=nil, option=nil) - if option == 'compound' - "" - elsif option - if window - tk_call('font', 'actual', font, "-displayof", window, "-#{option}") - else - tk_call('font', 'actual', font, "-#{option}") - end - else - l = tk_split_simplelist(if window - tk_call('font', 'actual', font, - "-displayof", window) - else - tk_call('font', 'actual', font) - end) - r = [] - while key=l.shift - if key == '-compound' - l.shift - else - r.push [key[1..-1], l.shift] - end - end - r - end - end - - def configure_core_tk4x(font, slot, value=None) - #"" - self - end - - def configinfo_core_tk4x(font, option=nil) - # dummy - if option - "" - else - [['family',[]], ['size',[]], ['weight',[]], ['slant',[]], - ['underline',[]], ['overstrike',[]], ['charset',[]], - ['pointadjust',[]]] - end - end - - def configure_core_tk8x(font, slot, value=None) - if JAPANIZED_TK - begin - padjust = tk_call('font', 'configure', font, '-pointadjust') - rescue - padjust = nil - end - else - padjust = nil - end - if slot.kind_of? Hash - if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family)) - slot = _symbolkey2str(slot) - configure_core_tk8x(font, 'family', slot.delete('family')) - end - - if ((slot.key?('size') || slot.key?(:size)) && - padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust)) - tk_call('font', 'configure', font, - '-pointadjust', padjust, *hash_kv(slot)) - else - tk_call('font', 'configure', font, *hash_kv(slot)) - end - elsif (slot == 'size' || slot == :size) && padjust != nil - tk_call('font', 'configure', font, - "-#{slot}", value, '-pointadjust', padjust) - elsif JAPANIZED_TK && (slot == 'family' || slot == :family) - # coumpund font? - begin - compound = tk_split_simplelist(tk_call('font', 'configure', - font, '-compound')) - rescue - tk_call('font', 'configure', font, '-family', value) - return self - end - if compound == [] - tk_call('font', 'configure', font, '-family', value) - return self - end - ltn, knj = compound - - lfnt = tk_call('font', 'create', '-copy', ltn) - begin - tk_call('font', 'configure', lfnt, '-family', value) - latin_replace_core_tk8x(lfnt) - rescue RuntimeError => e - fail e if $DEBUG - ensure - tk_call('font', 'delete', lfnt) if lfnt != '' - end - - kfnt = tk_call('font', 'create', '-copy', knj) - begin - tk_call('font', 'configure', kfnt, '-family', value) - kanji_replace_core_tk8x(lfnt) - rescue RuntimeError => e - fail e if $DEBUG - ensure - tk_call('font', 'delete', kfnt) if kfnt != '' - end - - else - tk_call('font', 'configure', font, "-#{slot}", value) - end - self - end - - def configinfo_core_tk8x(font, option=nil) - if option == 'compound' - "" - elsif option - tk_call('font', 'configure', font, "-#{option}") - else - l = tk_split_simplelist(tk_call('font', 'configure', font)) - r = [] - while key=l.shift - if key == '-compound' - l.shift - else - r.push [key[1..-1], l.shift] - end - end - r - end - end - - def delete_core_tk4x - Tk_FontNameTBL.delete(@id) - Tk_FontUseTBL.delete_if{|key,value| value == self} - end - - def delete_core_tk8x - begin - tk_call('font', 'delete', @latinfont) - rescue - end - begin - tk_call('font', 'delete', @kanjifont) - rescue - end - begin - tk_call('font', 'delete', @compoundfont) - rescue - end - Tk_FontNameTBL.delete(@id) - Tk_FontUseTBL.delete_if{|key,value| value == self} - end - - def latin_replace_core_tk4x(ltn) - create_latinfont_tk4x(ltn) - @compoundfont[0] = [@latinfont] if JAPANIZED_TK - @fontslot['font'] = @latinfont - Tk_FontUseTBL.dup.each{|w, fobj| - if self == fobj - begin - if w.include?(';') - win, tag = w.split(';') - winobj = tk_tcl2ruby(win) -# winobj.tagfont_configure(tag, {'font'=>@latinfont}) - if winobj.kind_of? TkText - tk_call(win, 'tag', 'configure', tag, '-font', @latinfont) - elsif winobj.kind_of? TkCanvas - tk_call(win, 'itemconfigure', tag, '-font', @latinfont) - elsif winobj.kind_of? TkMenu - tk_call(win, 'entryconfigure', tag, '-font', @latinfont) - else - raise RuntimeError, "unknown widget type" - end - else -# tk_tcl2ruby(w).font_configure('font'=>@latinfont) - tk_call(w, 'configure', '-font', @latinfont) - end - rescue - Tk_FontUseTBL.delete(w) - end - end - } - self - end - - def kanji_replace_core_tk4x(knj) - return self unless JAPANIZED_TK - - create_kanjifont_tk4x(knj) - @compoundfont[1] = [@kanjifont] - @fontslot['kanjifont'] = @kanjifont - Tk_FontUseTBL.dup.each{|w, fobj| - if self == fobj - begin - if w.include?(';') - win, tag = w.split(';') - winobj = tk_tcl2ruby(win) -# winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont}) - if winobj.kind_of? TkText - tk_call(win, 'tag', 'configure', tag, '-kanjifont', @kanjifont) - elsif winobj.kind_of? TkCanvas - tk_call(win, 'itemconfigure', tag, '-kanjifont', @kanjifont) - elsif winobj.kind_of? TkMenu - tk_call(win, 'entryconfigure', tag, '-kanjifont', @latinfont) - else - raise RuntimeError, "unknown widget type" - end - else -# tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont) - tk_call(w, 'configure', '-kanjifont', @kanjifont) - end - rescue - Tk_FontUseTBL.delete(w) - end - end - } - self - end - - def latin_replace_core_tk8x(ltn) - if JAPANIZED_TK - begin - tk_call('font', 'delete', '@font_tmp') - rescue - end - begin - fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont) - rescue - #fnt_bup = '' - fnt_bup = DEFAULT_LATIN_FONT_NAME - end - end - - begin - tk_call('font', 'delete', @latinfont) - rescue - end - create_latinfont(ltn) - - if JAPANIZED_TK - keys = self.configinfo - tk_call('font', 'delete', @compoundfont) - begin - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) -=begin - latinkeys = {} - begin - actual_core(@latinfont).each{|key,val| latinkeys[key] = val} - rescue - latinkeys {} - end - if latinkeys != {} - tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) - end -=end - rescue RuntimeError => e - tk_call('font', 'delete', @latinfont) - if fnt_bup && fnt_bup != '' - tk_call('font', 'create', @latinfont, '-copy', fnt_bup) - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) - tk_call('font', 'delete', fnt_bup) - else - fail e - end - end - - else - latinkeys = {} - begin - actual_core(@latinfont).each{|key,val| latinkeys[key] = val} - rescue - latinkeys {} - end - if latinkeys != {} - tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) - end - end - self - end - - def kanji_replace_core_tk8x(knj) - if JAPANIZED_TK - begin - tk_call('font', 'delete', '@font_tmp') - rescue - end - begin - fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont) - rescue - #fnt_bup = '' - fnt_bup = DEFAULT_KANJI_FONT_NAME - end - end - - begin - tk_call('font', 'delete', @kanjifont) - rescue - end - create_kanjifont(knj) - - if JAPANIZED_TK - keys = self.configinfo - tk_call('font', 'delete', @compoundfont) - begin - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) - rescue RuntimeError => e - tk_call('font', 'delete', @kanjifont) - if fnt_bup && fnt_bup != '' - tk_call('font', 'create', @kanjifont, '-copy', fnt_bup) - tk_call('font', 'create', @compoundfont, - '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) - tk_call('font', 'delete', fnt_bup) - else - fail e - end - end - end - self - end - - def measure_core_tk4x(window, text) - 0 - end - - def measure_core_tk8x(window, text) - if window - number(tk_call('font', 'measure', @compoundfont, - '-displayof', window, text)) - else - number(tk_call('font', 'measure', @compoundfont, text)) - end - end - - def metrics_core_tk4x(font, window, option=nil) - # dummy - if option - "" - else - [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]] - end - end - - def metrics_core_tk8x(font, window, option=nil) - if option - if window - number(tk_call('font', 'metrics', font, - "-displayof", window, "-#{option}")) - else - number(tk_call('font', 'metrics', font, "-#{option}")) - end - else - l = tk_split_list(if window - tk_call('font','metrics',font,"-displayof",window) - else - tk_call('font','metrics',font) - end) - r = [] - while key=l.shift - r.push [key[1..-1], l.shift.to_i] - end - r - end - end - - ################################### - # private alias - ################################### - case (Tk::TK_VERSION) - when /^4\.*/ - alias create_latinfont create_latinfont_tk4x - alias create_kanjifont create_kanjifont_tk4x - alias create_compoundfont create_compoundfont_tk4x - alias actual_core actual_core_tk4x - alias configure_core configure_core_tk4x - alias configinfo_core configinfo_core_tk4x - alias delete_core delete_core_tk4x - alias latin_replace_core latin_replace_core_tk4x - alias kanji_replace_core kanji_replace_core_tk4x - alias measure_core measure_core_tk4x - alias metrics_core metrics_core_tk4x - - when /^8\.[0-4]/ - alias create_latinfont create_latinfont_tk8x - alias create_kanjifont create_kanjifont_tk8x - alias create_compoundfont create_compoundfont_tk8x - alias actual_core actual_core_tk8x - alias configure_core configure_core_tk8x - alias configinfo_core configinfo_core_tk8x - alias delete_core delete_core_tk8x - alias latin_replace_core latin_replace_core_tk8x - alias kanji_replace_core kanji_replace_core_tk8x - alias measure_core measure_core_tk8x - alias metrics_core metrics_core_tk8x - - when /^8\.*/ - alias create_latinfont create_latinfont_tk8x - alias create_kanjifont create_kanjifont_tk8x - alias create_compoundfont create_compoundfont_tk8x - alias actual_core actual_core_tk8x - alias configure_core configure_core_tk8x - alias configinfo_core configinfo_core_tk8x - alias delete_core delete_core_tk8x - alias latin_replace_core latin_replace_core_tk8x - alias kanji_replace_core kanji_replace_core_tk8x - alias measure_core measure_core_tk8x - alias metrics_core metrics_core_tk8x - - end - - ################################### - public - ################################### - def method_missing(id, *args) - name = id.id2name - case args.length - when 1 - configure name, args[0] - when 0 - begin - configinfo name - rescue - fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at - end - else - fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at - end - end - - def call_font_configure(path, *args) - args += hash_kv(args.pop.update(@fontslot)) - tk_call(*args) - Tk_FontUseTBL[path] = self - self - end - - def used - ret = [] - Tk_FontUseTBL.each{|key,value| - if key.include?(';') - win, tag = key.split(';') - winobj = tk_tcl2ruby(win) - if winobj.kind_of? TkText - ret.push([winobj, winobj.tagid2obj(tag)]) - elsif winobj.kind_of? TkCanvas - if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag - ret.push([winobj, tagobj]) - elsif (tagobj = TkcItem.id2obj(tag)).kind_of? TkcItem - ret.push([winobj, tagobj]) - else - ret.push([winobj, tag]) - end - elsif winobj.kind_of? TkMenu - ret.push([winobj, tag]) - else - ret.push([win, tag]) - end - else - ret.push(tk_tcl2ruby(key)) if value == self - end - } - ret - end - - def id - @id - end - - def to_eval - font - end - - def font - @compoundfont - end - alias font_id font - - def latin_font_id - @latinfont - end - - def latin_font - # @latinfont - if @latin_descendant - @latin_descendant - else - @latin_descendant = DescendantFont.new(self, 'latin') - end - end - alias latinfont latin_font - - def kanji_font_id - @kanjifont - end - - def kanji_font - # @kanjifont - if @kanji_descendant - @kanji_descendant - else - @kanji_descendant = DescendantFont.new(self, 'kanji') - end - end - alias kanjifont kanji_font - - def actual(option=nil) - actual_core(@compoundfont, nil, option) - end - - def actual_displayof(window, option=nil) - window = '.' unless window - actual_core(@compoundfont, window, option) - end - - def latin_actual(option=nil) - actual_core(@latinfont, nil, option) - end - - def latin_actual_displayof(window, option=nil) - window = '.' unless window - actual_core(@latinfont, window, option) - end - - def kanji_actual(option=nil) - #if JAPANIZED_TK - if @kanjifont != "" - actual_core(@kanjifont, nil, option) - else - actual_core_tk4x(nil, nil, option) - end - end - - def kanji_actual_displayof(window, option=nil) - #if JAPANIZED_TK - if @kanjifont != "" - window = '.' unless window - actual_core(@kanjifont, window, option) - else - actual_core_tk4x(nil, window, option) - end - end - - def [](slot) - configinfo slot - end - - def []=(slot, val) - configure slot, val - end - - def configure(slot, value=None) - configure_core(@compoundfont, slot, value) - self - end - - def configinfo(slot=nil) - configinfo_core(@compoundfont, slot) - end - - def delete - delete_core - end - - def latin_configure(slot, value=None) - if JAPANIZED_TK - configure_core(@latinfont, slot, value) - else - configure(slot, value) - end - self - end - - def latin_configinfo(slot=nil) - if JAPANIZED_TK - configinfo_core(@latinfont, slot) - else - configinfo(slot) - end - end - - def kanji_configure(slot, value=None) - #if JAPANIZED_TK - if @kanjifont != "" - configure_core(@kanjifont, slot, value) - configure('size'=>configinfo('size')) # to reflect new configuration - else - #"" - configure(slot, value) - end - self - end - - def kanji_configinfo(slot=nil) - #if JAPANIZED_TK - if @kanjifont != "" - configinfo_core(@kanjifont, slot) - else - #[] - configinfo(slot) - end - end - - def replace(ltn, knj) - latin_replace(ltn) - kanji_replace(knj) - self - end - - def latin_replace(ltn) - latin_replace_core(ltn) - reset_pointadjust - self - end - - def kanji_replace(knj) - kanji_replace_core(knj) - reset_pointadjust - self - end - - def measure(text) - measure_core(nil, text) - end - - def measure_displayof(window, text) - window = '.' unless window - measure_core(window, text) - end - - def metrics(option=nil) - metrics_core(@compoundfont, nil, option) - end - - def metrics_displayof(window, option=nil) - window = '.' unless window - metrics_core(@compoundfont, window, option) - end - - def latin_metrics(option=nil) - metrics_core(@latinfont, nil, option) - end - - def latin_metrics_displayof(window, option=nil) - window = '.' unless window - metrics_core(@latinfont, window, option) - end - - def kanji_metrics(option=nil) - if JAPANIZED_TK - metrics_core(@kanjifont, nil, option) - else - metrics_core_tk4x(nil, nil, option) - end - end - - def kanji_metrics_displayof(window, option=nil) - if JAPANIZED_TK - window = '.' unless window - metrics_core(@kanjifont, window, option) - else - metrics_core_tk4x(nil, window, option) - end - end - - def reset_pointadjust - begin - if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK - configure('pointadjust' => latin_actual.assoc('size')[1].to_f / - kanji_actual.assoc('size')[1].to_f ) - end - rescue - end - self - end - - ################################### - # public alias - ################################### - alias ascii_font latin_font - alias asciifont latinfont - alias create_asciifont create_latinfont - alias ascii_actual latin_actual - alias ascii_actual_displayof latin_actual_displayof - alias ascii_configure latin_configure - alias ascii_configinfo latin_configinfo - alias ascii_replace latin_replace - alias ascii_metrics latin_metrics - - ################################### - def dup - src = self - obj = super() - obj.instance_eval{ initialize(src) } - obj - end - def clone - src = self - obj = super() - obj.instance_eval{ initialize(src) } - obj - end -end - -module TkTreatTagFont - def font_configinfo - @parent.tagfont_configinfo(@id) - end -# alias font font_configinfo - - def font_configure(slot) - @parent.tagfont_configure(@id, slot) - self - end - - def latinfont_configure(ltn, keys=nil) - @parent.latintagfont_configure(@id, ltn, keys) - self - end - alias asciifont_configure latinfont_configure - - def kanjifont_configure(knj, keys=nil) - @parent.kanjitagfont_configure(@id, ltn, keys) - self - end - - def font_copy(window, wintag=nil) - @parent.tagfont_copy(@id, window, wintag) - self - end - - def latinfont_copy(window, wintag=nil) - @parent.latintagfont_copy(@id, window, wintag) - self - end - alias asciifont_copy latinfont_copy - - def kanjifont_copy(window, wintag=nil) - @parent.kanjitagfont_copy(@id, window, wintag) - self - end -end +require 'tk/font' diff --git a/ext/tk/lib/tkmacpkg.rb b/ext/tk/lib/tkmacpkg.rb index 3bac5e6c3e..35560e78ce 100644 --- a/ext/tk/lib/tkmacpkg.rb +++ b/ext/tk/lib/tkmacpkg.rb @@ -1,56 +1,4 @@ # -# tkmacpkg.rb : methods for Tcl/Tk packages for Macintosh -# 2000/11/22 by Hidetoshi Nagai +# tkmacpkg.rb - load tk/macpkg.rb # -# ATTENTION !! -# This is NOT TESTED. Because I have no test-environment. -# -# -require 'tk' - -module TkMacResource - extend Tk - extend TkMacResource - - TkCommandNames = ['resource'.freeze].freeze - - tk_call('package', 'require', 'resource') - - def close(rsrcRef) - tk_call('resource', 'close', rsrcRef) - end - - def delete(rsrcType, opts=nil) - tk_call('resource', 'delete', *(hash_kv(opts) + rsrcType)) - end - - def files(rsrcRef=nil) - if rsrcRef - tk_call('resource', 'files', rsrcRef) - else - tk_split_simplelist(tk_call('resource', 'files')) - end - end - - def list(rsrcType, rsrcRef=nil) - tk_split_simplelist(tk_call('resource', 'list', rsrcType, rsrcRef)) - end - - def open(fname, access=nil) - tk_call('resource', 'open', fname, access) - end - - def read(rsrcType, rsrcID, rsrcRef=nil) - tk_call('resource', 'read', rsrcType, rsrcID, rsrcRef) - end - - def types(rsrcRef=nil) - tk_split_simplelist(tk_call('resource', 'types', rsrcRef)) - end - - def write(rsrcType, data, opts=nil) - tk_call('resource', 'write', *(hash_kv(opts) + rsrcType + data)) - end - - module_function :close, :delete, :files, :list, :open, :read, :types, :write -end +require 'tk/macpkg' diff --git a/ext/tk/lib/tkmenubar.rb b/ext/tk/lib/tkmenubar.rb index 0d29571eb7..70214fda1a 100644 --- a/ext/tk/lib/tkmenubar.rb +++ b/ext/tk/lib/tkmenubar.rb @@ -1,143 +1,4 @@ # -# tkmenubar.rb +# tkmenubar.rb - load tk/menubar.rb # -# Copyright (C) 1998 maeda shugo. All rights reserved. -# This file can be distributed under the terms of the Ruby. - -# Usage: -# -# menu_spec = [ -# [['File', 0], -# ['Open', proc{puts('Open clicked')}, 0], -# '---', -# ['Quit', proc{exit}, 0]], -# [['Edit', 0], -# ['Cut', proc{puts('Cut clicked')}, 2], -# ['Copy', proc{puts('Copy clicked')}, 0], -# ['Paste', proc{puts('Paste clicked')}, 0]] -# ] -# menubar = TkMenubar.new(nil, menu_spec, -# 'tearoff'=>false, -# 'foreground'=>'grey40', -# 'activeforeground'=>'red', -# 'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1') -# menubar.pack('side'=>'top', 'fill'=>'x') -# -# -# OR -# -# -# menubar = TkMenubar.new -# menubar.add_menu([['File', 0], -# ['Open', proc{puts('Open clicked')}, 0], -# '---', -# ['Quit', proc{exit}, 0]]) -# menubar.add_menu([['Edit', 0], -# ['Cut', proc{puts('Cut clicked')}, 2], -# ['Copy', proc{puts('Copy clicked')}, 0], -# ['Paste', proc{puts('Paste clicked')}, 0]]) -# menubar.configure('tearoff', false) -# menubar.configure('foreground', 'grey40') -# menubar.configure('activeforeground', 'red') -# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1') -# menubar.pack('side'=>'top', 'fill'=>'x') - -# The format of the menu_spec is: -# [ -# [ -# [button text, underline, accelerator], -# [menu label, command, underline, accelerator], -# '---', # separator -# ... -# ], -# ... -# ] - -# underline and accelerator are optional parameters. -# Hashes are OK instead of Arrays. - -# To use add_menu, configuration must be done by calling configure after -# adding all menus by add_menu, not by the constructor arguments. - -require "tk" - -class TkMenubar item_info) - end - end - - mbtn.menu(menu) - @menus.push([mbtn, menu]) - delegate('tearoff', menu) - delegate('foreground', mbtn, menu) - delegate('background', mbtn, menu) - delegate('disabledforeground', mbtn, menu) - delegate('activeforeground', mbtn, menu) - delegate('activebackground', mbtn, menu) - delegate('font', mbtn, menu) - delegate('kanjifont', mbtn, menu) - mbtn.pack('side' => 'left') - end - - def [](index) - return @menus[index] - end -end +require 'tk/menubar' diff --git a/ext/tk/lib/tkmngfocus.rb b/ext/tk/lib/tkmngfocus.rb index 461525009f..fe70950e8e 100644 --- a/ext/tk/lib/tkmngfocus.rb +++ b/ext/tk/lib/tkmngfocus.rb @@ -1,33 +1,4 @@ # -# tkmngfocus.rb : methods for Tcl/Tk standard library 'focus.tcl' -# by Hidetoshi Nagai +# tkmngfocus.rb - load tk/mngfocus.rb # -require 'tk' - -module TkManageFocus - extend Tk - - TkCommandNames = [ - 'tk_focusFollowMouse'.freeze, - 'tk_focusNext'.freeze, - 'tk_focusPrev'.freeze - ].freeze - - def TkManageFocus.followsMouse - tk_call 'tk_focusFollowsMouse' - end - - def TkManageFocus.next(window) - tk_tcl2ruby(tk_call('tk_focusNext', window)) - end - def focusNext - TkManageFocus.next(self) - end - - def TkManageFocus.prev(window) - tk_tcl2ruby(tk_call('tk_focusPrev', window)) - end - def focusPrev - TkManageFocus.prev(self) - end -end +require 'tk/mngfocus' diff --git a/ext/tk/lib/tkpalette.rb b/ext/tk/lib/tkpalette.rb index dc2fd47e5c..56b203bbb9 100644 --- a/ext/tk/lib/tkpalette.rb +++ b/ext/tk/lib/tkpalette.rb @@ -1,54 +1,4 @@ # -# tkpalette.rb : methods for Tcl/Tk standard library 'palette.tcl' -# 1998/06/21 by Hidetoshi Nagai +# tkpalette.rb - load tk/palette.rb # -require 'tk' - -module TkPalette - include Tk - extend Tk - - TkCommandNames = [ - 'tk_setPalette'.freeze, - 'tk_bisque'.freeze, - 'tkDarken'.freeze - ].freeze - - def TkPalette.set(*args) - args = args.to_a.flatten if args.kind_of? Hash - tk_call 'tk_setPalette', *args - end - def TkPalette.setPalette(*args) - TkPalette.set(*args) - end - - def TkPalette.bisque - tk_call 'tk_bisque' - end - - def TkPalette.darken(color, percent) - tk_call 'tkDarken', color, percent - end - - def TkPalette.recolorTree(window, colors) - if not colors.kind_of?(Hash) - fail "2nd arg need to be Hash" - end - - colors.each{|key, value| - begin - if window.cget(key) == tk_call('set', "tkPalette(#{key})") - window[key] = colors[key] - end - rescue - # ignore - end - } - - TkWinfo.children(window).each{|w| TkPalette.recolorTree(w, colors)} - end - - def recolorTree(colors) - TkPalette.recolorTree(self, colors) - end -end +require 'tk/palette' diff --git a/ext/tk/lib/tkscrollbox.rb b/ext/tk/lib/tkscrollbox.rb index 3f1191c740..6093b2e4e7 100644 --- a/ext/tk/lib/tkscrollbox.rb +++ b/ext/tk/lib/tkscrollbox.rb @@ -1,30 +1,4 @@ # -# tkscrollbox.rb - Tk Listbox with Scrollbar -# as an example of Composite Widget -# $Date$ -# by Yukihiro Matsumoto - -require 'tk.rb' - -class TkScrollbox'left','fill'=>'both','expand'=>'yes' - scroll.configure 'command', list.path+" yview" - scroll.pack 'side'=>'right','fill'=>'y' - - delegate('DEFAULT', list) - delegate('foreground', list) - delegate('background', list, scroll) - delegate('borderwidth', @frame) - delegate('relief', @frame) - - configure keys if keys - end - private :initialize_composite -end +# tkscrollbox.rb - load tk/scrollbox.rb +# +require 'tk/scrollbox' diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb index 2d37fb8c05..97ad62a3ea 100644 --- a/ext/tk/lib/tktext.rb +++ b/ext/tk/lib/tktext.rb @@ -1,1356 +1,4 @@ # -# tktext.rb - Tk text classes -# $Date$ -# by Yukihiro Matsumoto - -require 'tk.rb' -require 'tkfont' - -module TkTreatTextTagFont - include TkTreatItemFont - - ItemCMD = ['tag'.freeze, 'configure'.freeze].freeze - def __conf_cmd(idx) - ItemCMD[idx] - end - - def __item_pathname(tagOrId) - if tagOrId.kind_of?(TkTextTag) - self.path + ';' + tagOrId.id - else - self.path + ';' + tagOrId - end - end - - private :__conf_cmd, :__item_pathname -end - -class TkText 0 - tags.shift.collect{|x|_get_eval_string(x)}.join(' ') # taglist - args << tags.shift if tags.size > 0 # chars - end - super index, *args - else - # single chars-taglist argument - super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ') - end - end - - def destroy - @tags = {} unless @tags - @tags.each_value do |t| - t.destroy - end - super - end - - def backspace - self.delete 'insert' - end - - def compare(idx1, op, idx2) - bool(tk_send('compare', idx1, op, idx2)) - end - - def debug - bool(tk_send('debug')) - end - def debug=(boolean) - tk_send 'debug', boolean - self - end - def bbox(index) - list(tk_send('bbox', index)) - end - - def dlineinfo(index) - list(tk_send('dlineinfo', index)) - end - - def modified? - bool(tk_send('edit', 'modified')) - end - def modified(mode) - tk_send('edit', 'modified', mode) - self - end - def edit_redo - tk_send('edit', 'redo') - self - end - def edit_reset - tk_send('edit', 'reset') - self - end - def edit_separator - tk_send('edit', 'separator') - self - end - def edit_undo - tk_send('edit', 'undo') - self - end - - def yview_pickplace(*what) - tk_send 'yview', '-pickplace', *what - self - end - - def xview_pickplace(*what) - tk_send 'xview', '-pickplace', *what - self - end - - def text_copy - # Tk8.4 feature - tk_call('tk_textCopy', @path) - end - - def text_cut - # Tk8.4 feature - tk_call('tk_textCut', @path) - end - - def text_paste - # Tk8.4 feature - tk_call('tk_textPaste', @path) - end - - def tag_add(tag, index1, index2=None) - tk_send 'tag', 'add', tag, index1, index2 - self - end - alias addtag tag_add - alias add_tag tag_add - - def tag_delete(*tags) - tk_send 'tag', 'delete', *tags - if TkTextTag::TTagID_TBL[@path] - tags.each{|tag| - if tag.kind_of? TkTextTag - TTagID_TBL[@path].delete(tag.id) - else - TTagID_TBL[@path].delete(tag) - end - } - end - self - end - alias deltag tag_delete - alias delete_tag tag_delete - - def tag_bind(tag, seq, cmd=Proc.new, args=nil) - _bind([@path, 'tag', 'bind', tag], seq, cmd, args) - self - end - - def tag_bind_append(tag, seq, cmd=Proc.new, args=nil) - _bind_append([@path, 'tag', 'bind', tag], seq, cmd, args) - self - end - - def tag_bind_remove(tag, seq) - _bind_remove([@path, 'tag', 'bind', tag], seq) - self - end - - def tag_bindinfo(tag, context=nil) - _bindinfo([@path, 'tag', 'bind', tag], context) - end - - def tag_cget(tag, key) - case key.to_s - when 'text', 'label', 'show', 'data', 'file' - tk_call(@path, 'tag', 'cget', tag, "-#{key}") - when 'font', 'kanjifont' - #fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}")) - fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, '-font')) - unless fnt.kind_of?(TkFont) - fnt = tagfontobj(tag, fnt) - end - if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ - # obsolete; just for compatibility - fnt.kanji_font - else - fnt - end - else - tk_tcl2ruby(tk_call(@path, 'tag', 'cget', tag, "-#{key}")) - end - end - - def tag_configure(tag, key, val=None) - if key.kind_of? Hash - key = _symbolkey2str(key) - if ( key['font'] || key['kanjifont'] \ - || key['latinfont'] || key['asciifont'] ) - tagfont_configure(tag, key) - else - tk_send 'tag', 'configure', tag, *hash_kv(key) - end - - else - if key == 'font' || key == :font || - key == 'kanjifont' || key == :kanjifont || - key == 'latinfont' || key == :latinfont || - key == 'asciifont' || key == :asciifont - if val == None - tagfontobj(tag) - else - tagfont_configure(tag, {key=>val}) - end - else - tk_send 'tag', 'configure', tag, "-#{key}", val - end - end - self - end - - def tag_configinfo(tag, key=nil) - if key - case key.to_s - when 'text', 'label', 'show', 'data', 'file' - conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}")) - when 'font', 'kanjifont' - conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}") ) - conf[4] = tagfont_configinfo(tag, conf[4]) - else - conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}")) - end - conf[0] = conf[0][1..-1] - conf - else - ret = tk_split_simplelist(tk_send('tag', 'configure', - tag)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show', 'data', 'file' - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - fontconf = ret.assoc('font') - if fontconf - ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'} - fontconf[4] = tagfont_configinfo(tag, fontconf[4]) - ret.push(fontconf) - else - ret - end - end - end - - def tag_raise(tag, above=None) - tk_send 'tag', 'raise', tag, above - self - end - - def tag_lower(tag, below=None) - tk_send 'tag', 'lower', tag, below - self - end - - def tag_remove(tag, *index) - tk_send 'tag', 'remove', tag, *index - self - end - - def tag_ranges(tag) - l = tk_split_simplelist(tk_send('tag', 'ranges', tag)) - r = [] - while key=l.shift - r.push [key, l.shift] - end - r - end - - def tag_nextrange(tag, first, last=None) - tk_split_list(tk_send('tag', 'nextrange', tag, first, last)) - end - - def tag_prevrange(tag, first, last=None) - tk_split_list(tk_send('tag', 'prevrange', tag, first, last)) - end - - def window_cget(index, slot) - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - tk_send('window', 'cget', index, "-#{slot}") - when 'font', 'kanjifont' - #fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}")) - fnt = tk_tcl2ruby(tk_send('window', 'cget', index, '-font')) - unless fnt.kind_of?(TkFont) - fnt = tagfontobj(index, fnt) - end - if slot.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ - # obsolete; just for compatibility - fnt.kanji_font - else - fnt - end - else - tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}")) - end - end - - def window_configure(index, slot, value=None) - if index.kind_of? TkTextWindow - index.configure(slot, value) - else - if slot.kind_of? Hash - slot = _symbolkey2str(slot) - win = slot['window'] - slot['window'] = win.epath if win.kind_of?(TkWindow) - if slot['create'] - p_create = slot['create'] - if p_create.kind_of? Proc - slot['create'] = install_cmd(proc{ - id = p_create.call - if id.kind_of?(TkWindow) - id.epath - else - id - end - }) - end - end - tk_send('window', 'configure', index, *hash_kv(slot)) - else - if slot == 'window' || slot == :window - id = value - value = id.epath if id.kind_of?(TkWindow) - end - if slot == 'create' || slot == :create - p_create = value - if p_create.kind_of? Proc - value = install_cmd(proc{ - id = p_create.call - if id.kind_of?(TkWindow) - id.epath - else - id - end - }) - end - end - tk_send('window', 'configure', index, "-#{slot}", value) - end - end - self - end - - def window_configinfo(win, slot = nil) - if slot - case slot.to_s - when 'text', 'label', 'show', 'data', 'file' - conf = tk_split_simplelist(tk_send('window', 'configure', - win, "-#{slot}")) - else - conf = tk_split_list(tk_send('window', 'configure', - win, "-#{slot}")) - end - conf[0] = conf[0][1..-1] - conf - else - tk_split_simplelist(tk_send('window', 'configure', - win)).collect{|conflist| - conf = tk_split_simplelist(conflist) - conf[0] = conf[0][1..-1] - case conf[0] - when 'text', 'label', 'show', 'data', 'file' - else - if conf[3] - if conf[3].index('{') - conf[3] = tk_split_list(conf[3]) - else - conf[3] = tk_tcl2ruby(conf[3]) - end - end - if conf[4] - if conf[4].index('{') - conf[4] = tk_split_list(conf[4]) - else - conf[4] = tk_tcl2ruby(conf[4]) - end - end - end - conf - } - end - end - - def window_names - tk_split_simplelist(tk_send('window', 'names')).collect{|elt| - tagid2obj(elt) - } - end - - def _ktext_length(txt) - if $KCODE !~ /n/i - return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length - end - - # $KCODE == 'NONE' - if JAPANIZED_TK - tk_call('kstring', 'length', txt).to_i - else - begin - tk_call('encoding', 'convertto', 'ascii', txt).length - rescue StandardError, NameError - # sorry, I have no plan - txt.length - end - end - end - private :_ktext_length - - def search_with_length(pat,start,stop=None) - pat = pat.chr if pat.kind_of? Integer - if stop != None - return ["", 0] if compare(start,'>=',stop) - txt = get(start,stop) - if (pos = txt.index(pat)) - match = $& - #pos = txt[0..(pos-1)].split('').length if pos > 0 - pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 - if pat.kind_of? String - #return [index(start + " + #{pos} chars"), pat.split('').length] - return [index(start + " + #{pos} chars"), - _ktext_length(pat), pat.dup] - else - #return [index(start + " + #{pos} chars"), $&.split('').length] - return [index(start + " + #{pos} chars"), - _ktext_length(match), match] - end - else - return ["", 0] - end - else - txt = get(start,'end - 1 char') - if (pos = txt.index(pat)) - match = $& - #pos = txt[0..(pos-1)].split('').length if pos > 0 - pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 - if pat.kind_of? String - #return [index(start + " + #{pos} chars"), pat.split('').length] - return [index(start + " + #{pos} chars"), - _ktext_length(pat), pat.dup] - else - #return [index(start + " + #{pos} chars"), $&.split('').length] - return [index(start + " + #{pos} chars"), - _ktext_length(match), match] - end - else - txt = get('1.0','end - 1 char') - if (pos = txt.index(pat)) - match = $& - #pos = txt[0..(pos-1)].split('').length if pos > 0 - pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 - if pat.kind_of? String - #return [index("1.0 + #{pos} chars"), pat.split('').length] - return [index("1.0 + #{pos} chars"), - _ktext_length(pat), pat.dup] - else - #return [index("1.0 + #{pos} chars"), $&.split('').length] - return [index("1.0 + #{pos} chars"), _ktext_length(match), match] - end - else - return ["", 0] - end - end - end - end - - def search(pat,start,stop=None) - search_with_length(pat,start,stop)[0] - end - - def rsearch_with_length(pat,start,stop=None) - pat = pat.chr if pat.kind_of? Integer - if stop != None - return ["", 0] if compare(start,'<=',stop) - txt = get(stop,start) - if (pos = txt.rindex(pat)) - match = $& - #pos = txt[0..(pos-1)].split('').length if pos > 0 - pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 - if pat.kind_of? String - #return [index(stop + " + #{pos} chars"), pat.split('').length] - return [index(stop + " + #{pos} chars"), _ktext_length(pat), pat.dup] - else - #return [index(stop + " + #{pos} chars"), $&.split('').length] - return [index(stop + " + #{pos} chars"), _ktext_length(match), match] - end - else - return ["", 0] - end - else - txt = get('1.0',start) - if (pos = txt.rindex(pat)) - match = $& - #pos = txt[0..(pos-1)].split('').length if pos > 0 - pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 - if pat.kind_of? String - #return [index("1.0 + #{pos} chars"), pat.split('').length] - return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] - else - #return [index("1.0 + #{pos} chars"), $&.split('').length] - return [index("1.0 + #{pos} chars"), _ktext_length(match), match] - end - else - txt = get('1.0','end - 1 char') - if (pos = txt.rindex(pat)) - match = $& - #pos = txt[0..(pos-1)].split('').length if pos > 0 - pos = _ktext_length(txt[0..(pos-1)]) if pos > 0 - if pat.kind_of? String - #return [index("1.0 + #{pos} chars"), pat.split('').length] - return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup] - else - #return [index("1.0 + #{pos} chars"), $&.split('').length] - return [index("1.0 + #{pos} chars"), _ktext_length(match), match] - end - else - return ["", 0] - end - end - end - end - - def rsearch(pat,start,stop=None) - rsearch_with_length(pat,start,stop)[0] - end - - def dump(type_info, *index, &block) - args = type_info.collect{|inf| '-' + inf} - args << '-command' << block if block - str = tk_send('dump', *(args + index)) - result = [] - sel = nil - i = 0 - while i < str.size - # retrieve key - idx = str.index(/ /, i) - result.push str[i..(idx-1)] - i = idx + 1 - - # retrieve value - case result[-1] - when 'text' - if str[i] == ?{ - # text formed as {...} - val, i = _retrieve_braced_text(str, i) - result.push val - else - # text which may contain backslahes - val, i = _retrieve_backslashed_text(str, i) - result.push val - end - else - idx = str.index(/ /, i) - val = str[i..(idx-1)] - case result[-1] - when 'mark' - case val - when 'insert' - result.push TkTextMarkInsert.new(self) - when 'current' - result.push TkTextMarkCurrent.new(self) - when 'anchor' - result.push TkTextMarkAnchor.new(self) - else - result.push tk_tcl2ruby(val) - end - when 'tagon' - if val == 'sel' - if sel - result.push sel - else - result.push TkTextTagSel.new(self) - end - else - result.push tk_tcl2ruby(val) - end - when 'tagoff' - result.push tk_tcl2ruby(val) - when 'window' - result.push tk_tcl2ruby(val) - end - i = idx + 1 - end - - # retrieve index - idx = str.index(/ /, i) - if idx - result.push str[i..(idx-1)] - i = idx + 1 - else - result.push str[i..-1] - break - end - end - - kvis = [] - until result.empty? - kvis.push [result.shift, result.shift, result.shift] - end - kvis # result is [[key1, value1, index1], [key2, value2, index2], ...] - end - - def _retrieve_braced_text(str, i) - cnt = 0 - idx = i - while idx < str.size - case str[idx] - when ?{ - cnt += 1 - when ?} - cnt -= 1 - if cnt == 0 - break - end - end - idx += 1 - end - return str[i+1..idx-1], idx + 2 - end - private :_retrieve_braced_text - - def _retrieve_backslashed_text(str, i) - j = i - idx = nil - loop { - idx = str.index(/ /, j) - if str[idx-1] == ?\\ - j += 1 - else - break - end - } - val = str[i..(idx-1)] - val.gsub!(/\\( |\{|\})/, '\1') - return val, idx + 1 - end - private :_retrieve_backslashed_text - - def dump_all(*index, &block) - dump(['all'], *index, &block) - end - def dump_mark(*index, &block) - dump(['mark'], *index, &block) - end - def dump_tag(*index, &block) - dump(['tag'], *index, &block) - end - def dump_text(*index, &block) - dump(['text'], *index, &block) - end - def dump_window(*index, &block) - dump(['window'], *index, &block) - end - def dump_image(*index, &block) - dump(['image'], *index, &block) - end -end - -class TkTextTag 0 - tk_call(@t.path, 'window', 'configure', @index, *hash_kv(slot)) - end - else - if slot == 'window' || slot == :window - @id = value - value = @id.epath if @id.kind_of?(TkWindow) - end - if slot == 'create' || slot == :create - self.create=value - else - tk_call(@t.path, 'window', 'configure', @index, "-#{slot}", value) - end - end - self - end - - def configinfo(slot = nil) - @t.window_configinfo(@index, slot) - end - - def window - @id - end - - def window=(value) - @id = value - value = @id.epath if @id.kind_of?(TkWindow) - tk_call @t.path, 'window', 'configure', @index, '-window', value - end - - def create - @p_create - end - - def create=(value) - @p_create = value - if @p_create.kind_of? Proc - value = install_cmd(proc{ - @id = @p_create.call - if @id.kind_of?(TkWindow) - @id.epath - else - @id - end - }) - end - tk_call @t.path, 'window', 'configure', @index, '-create', value - end -end - -class TkTextImage +# tkvirtevent.rb - load tk/virtevent.rb # -require 'tk' - -class TkVirtualEvent".freeze].freeze - TkVirtualEventTBL = TkCore::INTERP.create_table - - TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear } - - class PreDefVirtEvent") - PreDefVirtEvent.new(event) - else - fail ArgumentError, "undefined virtual event '<#{event}>'" - end - end - end - - def TkVirtualEvent.info - tk_call('event', 'info').split(/\s+/).collect!{|seq| - TkVirtualEvent.getobj(seq[1..-2]) - } - end - - def initialize(*sequences) - @path = @id = TkVirtualEventID.join - TkVirtualEventID[1].succ! - add(*sequences) - end - - def add(*sequences) - if sequences != [] - tk_call('event', 'add', "<#{@id}>", - *(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) ) - TkVirtualEventTBL[@id] = self - end - self - end - - def delete(*sequences) - if sequences == [] - tk_call('event', 'delete', "<#{@id}>") - TkVirtualEventTBL.delete(@id) - else - tk_call('event', 'delete', "<#{@id}>", - *(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) ) - TkVirtualEventTBL.delete(@id) if info == [] - end - self - end - - def info - tk_call('event', 'info', "<#{@id}>").split(/\s+/).collect!{|seq| - l = seq.scan(/<*[^<>]+>*/).collect!{|subseq| - case (subseq) - when /^<<[^<>]+>>$/ - TkVirtualEvent.getobj(subseq[1..-2]) - when /^<[^<>]+>$/ - subseq[1..-2] - else - subseq.split('') - end - }.flatten - (l.size == 1) ? l[0] : l - } - end -end +require 'tk/virtevent' diff --git a/ext/tk/lib/tkwinpkg.rb b/ext/tk/lib/tkwinpkg.rb index 7762b3a596..83371c546d 100644 --- a/ext/tk/lib/tkwinpkg.rb +++ b/ext/tk/lib/tkwinpkg.rb @@ -1,84 +1,4 @@ # -# tkwinpkg.rb : methods for Tcl/Tk packages for Microsoft Windows -# 2000/11/22 by Hidetoshi Nagai +# tkwinpkg.rb - load tk/winpkg.rb # -# ATTENTION !! -# This is NOT TESTED. Because I have no test-environment. -# -# -require 'tk' - -module TkWinDDE - extend Tk - extend TkWinDDE - - TkCommandNames = ['dde'.freeze].freeze - - tk_call('package', 'require', 'dde') - - def servername(topic=nil) - tk_call('dde', 'servername', topic) - end - - def execute(service, topic, data) - tk_call('dde', 'execute', service, topic, data) - end - - def async_execute(service, topic, data) - tk_call('dde', '-async', 'execute', service, topic, data) - end - - def poke(service, topic, item, data) - tk_call('dde', 'poke', service, topic, item, data) - end - - def request(service, topic, item) - tk_call('dde', 'request', service, topic, item) - end - - def services(service, topic) - tk_call('dde', 'services', service, topic) - end - - def eval(topic, cmd, *args) - tk_call('dde', 'eval', topic, cmd, *args) - end - - module_function :servername, :execute, :async_execute, - :poke, :request, :services, :eval -end - -module TkWinRegistry - extend Tk - extend TkWinRegistry - - TkCommandNames = ['registry'.freeze].freeze - - tk_call('package', 'require', 'registry') - - def delete(keynam, valnam=nil) - tk_call('registry', 'delete', keynam, valnam) - end - - def get(keynam, valnam) - tk_call('registry', 'get', keynam, valnam) - end - - def keys(keynam) - tk_split_simplelist(tk_call('registry', 'keys', keynam)) - end - - def set(keynam, valnam=nil, data=nil, dattype=nil) - tk_call('registry', 'set', keynam, valnam, data, dattype) - end - - def type(keynam, valnam) - tk_call('registry', 'type', keynam, valnam) - end - - def values(keynam) - tk_split_simplelist(tk_call('registry', 'values', keynam)) - end - - module_function :delete, :get, :keys, :set, :type, :values -end +require 'tk/winpkg' diff --git a/ext/tk/sample/binding_sample.rb b/ext/tk/sample/binding_sample.rb new file mode 100644 index 0000000000..b98cd66a2e --- /dev/null +++ b/ext/tk/sample/binding_sample.rb @@ -0,0 +1,87 @@ +#!/usr/bin/env ruby + +require 'tk' + +class Button_clone < TkLabel + def initialize(*args) + @command = nil + + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + @command = keys.delete('command') + + keys['highlightthickness'] = 1 unless keys.key?('highlightthickness') + keys['padx'] = '3m' unless keys.key?('padx') + keys['pady'] = '1m' unless keys.key?('pady') + keys['relief'] = 'raised' unless keys.key?('relief') + + args.push(keys) + end + + super(*args) + + @press = false + + self.bind('Enter', proc{self.background(self.activebackground)}) + self.bind('Leave', proc{ + @press = false + self.background(self.highlightbackground) + self.relief('raised') + }) + + self.bind('ButtonPress-1', proc{@press = true; self.relief('sunken')}) + self.bind('ButtonRelease-1', proc{ + self.relief('raised') + @command.call if @press && @command + @press = false + }) + end + + def command(cmd = Proc.new) + @command = cmd + end + + def invoke + if @command + @command.call + else + '' + end + end +end + +TkLabel.new(:text=><'red').pack(:pady=>3) + +v = TkVariable.new(0) + +TkFrame.new{|f| + TkLabel.new(f, :text=>'click count : ').pack(:side=>:left) + TkLabel.new(f, :textvariable=>v).pack(:side=>:left) +}.pack + +TkButton.new(:text=>'normal Button widget', + :command=>proc{ + puts 'button is clicked!!' + lbl.text 'button is clicked!!' + v.numeric += 1 + }){ + pack(:fill=>:x, :expand=>true) +} + +Button_clone.new(:text=>'Label with Button binding', + :command=>proc{ + puts 'label is clicked!!' + lbl.text 'label is clicked!!' + v.numeric += 1 + }){ + pack(:fill=>:x, :expand=>true) +} + +Tk.mainloop diff --git a/ext/tk/sample/bindtag_sample.rb b/ext/tk/sample/bindtag_sample.rb new file mode 100644 index 0000000000..caf7a2d750 --- /dev/null +++ b/ext/tk/sample/bindtag_sample.rb @@ -0,0 +1,127 @@ +#!/usr/bin/env ruby +require 'tk' + +TkLabel.new(:text=><:left).pack +This is a sample of bindtags and usage of +Tk.callback_break/Tk.callback_continue. +Please check the work of following buttons +(attend the difference between before/after + pressing the bottom button), and see the +source code. +EOT + +def set_class_bind + TkButton.bind('ButtonPress-1', + proc{puts 'bind "ButtonPress-1" of TkButton class'}) + TkButton.bind('ButtonRelease-1', + proc{puts 'bind "ButtonRelease-1" of TkButton class'}) +end + +# set root binding +r = TkRoot.new +r.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of root widget'}) +r.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of root widget'}) + +# set 'all' binding +TkBindTag::ALL.bind('ButtonPress-1', + proc{puts 'bind "ButtonPress-1" of the tag "all"'}) +TkBindTag::ALL.bind('ButtonRelease-1', + proc{puts 'bind "ButtonRelease-1" of the tag "all"'}) + +# create buttons +b1 = TkButton.new(:text=>'button-1', + :command=>proc{puts "command of button-1"}).pack +b2 = TkButton.new(:text=>'button-2', + :command=>proc{puts "command of button-2"}).pack +b3 = TkButton.new(:text=>'button-3', + :command=>proc{puts "command of button-3"}).pack +b4 = TkButton.new(:text=>'button-4', + :command=>proc{puts "command of button-4"}).pack +b5 = TkButton.new(:text=>'button-5', + :command=>proc{puts "command of button-5"}).pack + +# set button binding +b1.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of button-1'}) +b1.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of button-1'}) + +b2.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of button-2'}) +b2.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of button-2'}) + +b3.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of button-3'}) +b3.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of button-3'}) + +b4.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of button-4'}) +b4.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of button-4'}) + +b5.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of button-5'}) +b5.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of button-5'}) + +# create bindtag and set binding +tag1 = TkBindTag.new +tag1.bind('ButtonPress-1', proc{puts 'bind "ButtonPress-1" of tag1'}) +tag1.bind('ButtonRelease-1', proc{puts 'bind "ButtonRelease-1" of tag1'}) + +tag2 = TkBindTag.new +tag2.bind('ButtonPress-1', + proc{ + puts 'bind "ButtonPress-1" of tag2' + puts 'call Tk.callback_continue' + Tk.callback_continue + puts 'never see this message' + }) +tag2.bind('ButtonRelease-1', + proc{ + puts 'bind "ButtonRelease-1" of tag2' + puts 'call Tk.callback_continue' + Tk.callback_continue + puts 'never see this message' + }) + +tag3 = TkBindTag.new +tag3.bind('ButtonPress-1', + proc{ + puts 'bind "ButtonPress-1" of tag3' + puts 'call Tk.callback_break' + Tk.callback_break + puts 'never see this message' + }) +tag3.bind('ButtonRelease-1', + proc{ + puts 'bind "ButtonRelease-1" of tag3' + puts 'call Tk.callback_break' + Tk.callback_break + puts 'never see this message' + }) + +# set bindtags +p b1.bindtags + +tags = b2.bindtags +tags[2,0] = tag1 +tags[0,0] = tag1 +b2.bindtags(tags) +p b2.bindtags + +tags = b3.bindtags +tags[2,0] = tag2 +tags[0,0] = tag2 +b3.bindtags(tags) +p b3.bindtags + +tags = b4.bindtags +tags[2,0] = tag3 +tags[0,0] = tag3 +b4.bindtags(tags) +p b4.bindtags + +b5.bindtags([tag1, TkButton, tag2, b5]) + +# create button to set button class binding +TkButton.new(:text=>'set binding to TkButton class', + :command=>proc{ + puts 'call "set_class_bind"' + set_class_bind + }).pack(:pady=>7) + +# start event-loop +Tk.mainloop diff --git a/ext/tk/sample/binstr_usage.rb b/ext/tk/sample/binstr_usage.rb new file mode 100644 index 0000000000..91692856f9 --- /dev/null +++ b/ext/tk/sample/binstr_usage.rb @@ -0,0 +1,39 @@ +#!/usr/bin/env ruby + +require "tk" + +TkMessage.new(:width=>360, :text=><ImgFile) +p ph1.configinfo + +b_str = Tk::BinaryString(IO.read(ImgFile)) +p [b_str, b_str.encoding] + +ph2 = TkPhotoImage.new(:data=>b_str) +p ph2.configinfo +p ph2.data(:grayscale=>true) + +ph3 = TkPhotoImage.new() +ph3.put(ph2.data(:grayscale=>true)) + +f = TkFrame.new.pack +TkButton.new(:parent=>f, :image=>ph1, :command=>proc{exit}).pack(:side=>:left) +TkButton.new(:parent=>f, :image=>ph2, :command=>proc{exit}).pack(:side=>:left) +TkButton.new(:parent=>f, :image=>ph3, :command=>proc{exit}).pack(:side=>:left) + +Tk.mainloop diff --git a/ext/tk/sample/btn_with_frame.rb b/ext/tk/sample/btn_with_frame.rb new file mode 100644 index 0000000000..d04c95a289 --- /dev/null +++ b/ext/tk/sample/btn_with_frame.rb @@ -0,0 +1,20 @@ +require 'tk' + +class Button_with_Frame < TkButton + def create_self(keys) + @frame = TkFrame.new('widgetname'=>@path, 'background'=>'yellow') + install_win(@path) # create new @path which is a daughter of old @path + super(keys) + TkPack(@path, :padx=>7, :pady=>7) + @epath = @frame.path + end + def epath + @epath + end +end + +Button_with_Frame.new(:text=>'QUIT', :command=>proc{exit}) { + pack(:padx=>15, :pady=>5) +} + +Tk.mainloop diff --git a/ext/tk/sample/demos-en/README.1st b/ext/tk/sample/demos-en/README.1st new file mode 100644 index 0000000000..e031f123d2 --- /dev/null +++ b/ext/tk/sample/demos-en/README.1st @@ -0,0 +1,18 @@ +There are Ruby/Tk demo scripts. + +Files with '.rb' extension are sub-scripts which are launched 'widget' +script. Those files don't work independently. Please call them from +'widget' script. + +If you want start some sub-scripts at same time when the launcher +script tarts, please give the sub-script names as arguments. +(e.g. /usr/local/bin/ruby widget button.rb entry1.rb text.rb ) +You can ommit '.rb' of the sub-scripts +(e.g. /usr/local/bin/ruby widget button entry1 text ) + +If you don't need launcher's main window, give -n option. +(e.g. /usr/local/bin/ruby widget -n button.rb entry1.rb text.rb ) + +Others (browse1, hello, and so on) are standalone scripts. + + 2004/04/14 Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) diff --git a/ext/tk/sample/demos-en/README.tkencoding b/ext/tk/sample/demos-en/README.tkencoding index 8fcb494c03..f576bc593e 100644 --- a/ext/tk/sample/demos-en/README.tkencoding +++ b/ext/tk/sample/demos-en/README.tkencoding @@ -1,3 +1,8 @@ +This is a original document of 'tkencoding.rb'. +The library 'tkencoding.rb' is obsolete. +Functions of tkencoding.rb is already included into Ruby/Tk. + +------------------------------------------------- tkencoding.rbを用いた日本語の表示について Copyright (C) 1999/07, Takaaki Tateishi diff --git a/ext/tk/sample/demos-en/arrow.rb b/ext/tk/sample/demos-en/arrow.rb index 8ee13254ea..3f07b8e660 100644 --- a/ext/tk/sample/demos-en/arrow.rb +++ b/ext/tk/sample/demos-en/arrow.rb @@ -150,7 +150,7 @@ if TkWinfo.depth($arrow_canvas) > 1 $demo_arrowInfo.activeStyle = {'fill'=>'red', 'outline'=>'black', 'width'=>1} else $demo_arrowInfo.bigLineStyle = {'fill'=>'black', - 'stipple'=>'@'+[$demo_dir, 'images', 'grey.25'].join(File::Separator)} + 'stipple'=>'@'+[$demo_dir,'..','images','grey.25'].join(File::Separator)} $demo_arrowInfo.boxStyle = {'fill'=>'', 'outline'=>'black', 'width'=>1} $demo_arrowInfo.activeStyle = {'fill'=>'black','outline'=>'black','width'=>1} end diff --git a/ext/tk/sample/demos-en/bind.rb b/ext/tk/sample/demos-en/bind.rb index 5d30d228f0..ab2a32de82 100644 --- a/ext/tk/sample/demos-en/bind.rb +++ b/ext/tk/sample/demos-en/bind.rb @@ -67,7 +67,7 @@ TkText.new($bind_demo){|t| tagstyle_normal = {'foreground'=>'', 'background'=>''} end - # テキスト挿入 + # insert text insert 'insert', "The same tag mechanism that controls display styles in text widgets can also be used to associate Tcl commands with regions of text, so that mouse or keyboard actions on the text cause particular Tcl commands to be invoked. For example, in the text below the descriptions of the canvas demonstrations have been tagged. When you move the mouse over a demo description the description lights up, and when you press button 1 over a description then that particular demonstration is invoked. " diff --git a/ext/tk/sample/demos-en/browse2 b/ext/tk/sample/demos-en/browse2 index 304a5f547e..edad04dbcb 100644 --- a/ext/tk/sample/demos-en/browse2 +++ b/ext/tk/sample/demos-en/browse2 @@ -39,11 +39,11 @@ class Browse } # Set up bindings for the browser. - base.bind('Control-c', - proc{ - base.destroy + base.bind('Destroy', proc{ Browse::BROWSE_WIN_COUNTER.value = \ - Browse::BROWSE_WIN_COUNTER.to_i - 1}) + Browse::BROWSE_WIN_COUNTER.to_i - 1 + }) + base.bind('Control-c', proc{base.destroy}) list.bind('Double-Button-1', proc{TkSelection.get.each{|f| self.browse dir, f}}) end diff --git a/ext/tk/sample/demos-en/check2.rb b/ext/tk/sample/demos-en/check2.rb new file mode 100644 index 0000000000..b01e3ffc93 --- /dev/null +++ b/ext/tk/sample/demos-en/check2.rb @@ -0,0 +1,107 @@ +# +# checkbutton widget demo2 (called by 'widget') +# + +# delete old toplevel widget +if defined?($check2_demo) && $check2_demo + $check2_demo.destroy + $check2_demo = nil +end + +# create demo toplevel widget +$check2_demo = TkToplevel.new {|w| + title("Checkbutton Demonstration 2") + iconname("check2") + positionWindow(w) +} + +# label +msg = TkLabel.new($check2_demo) { + font $font + wraplength '4i' + justify 'left' + text "Four checkbuttons are displayed below. If you click on a button, it will toggle the button's selection state and set a Tcl variable to a value indicating the state of the checkbutton. The first button also follows the state of the other three. If only some of the three are checked, the first button will display the tri-state mode. Click the \"See Variables\" button to see the current values of the variables." +} +msg.pack('side'=>'top') + +# variable +safety = TkVariable.new(0) +wipers = TkVariable.new(0) +brakes = TkVariable.new(0) +sober = TkVariable.new(0) + +# frame +TkFrame.new($check2_demo) {|frame| + TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), + :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + TkButton.new(frame, :text=>'See Variables', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars($check2_demo, + ['safety', safety], ['wipers', wipers], + ['brakes', brakes], ['sober', sober]) + }), + TkButton.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'check2'}), + TkButton.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $check2_demo + $check2_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) +}.pack('side'=>'bottom', 'fill'=>'x') + + +# checkbutton +TkCheckButton.new($check2_demo, :text=>'Safety Check', :variable=>safety, + :relief=>:flat, :onvalue=>'all', :offvalue=>'none', + :tristatevalue=>'partial'){ + pack('side'=>'top', 'pady'=>2, 'anchor'=>'w') +} + +[ TkCheckButton.new($check2_demo, 'text'=>'Wipers OK', 'variable'=>wipers), + TkCheckButton.new($check2_demo, 'text'=>'Brakes OK', 'variable'=>brakes), + TkCheckButton.new($check2_demo, 'text'=>'Driver Sober', 'variable'=>sober) +].each{|w| + w.relief('flat') + w.pack('side'=>'top', 'padx'=>15, 'pady'=>2, 'anchor'=>'w') +} + +# tristate check +in_check = false +tristate_check = proc{|n1,n2,op| + return if in_check + + in_check = true + begin + if n1 == safety + if safety == 'none' + wipers.value = 0 + brakes.value = 0 + sober.value = 0 + elsif safety == 'all' + wipers.value = 1 + brakes.value = 1 + sober.value = 1 + end + else + if wipers == 1 && brakes == 1 && sober == 1 + safety.value = 'all' + elsif wipers == 1 || brakes == 1 || sober == 1 + safety.value = 'partial' + else + safety.value = 'none' + end + end + ensure + in_check = false + end +} + +[wipers, brakes, sober, safety].each{|v| v.trace('w', tristate_check)} diff --git a/ext/tk/sample/demos-en/cscroll.rb b/ext/tk/sample/demos-en/cscroll.rb index 2f2be60da2..8250c6e5e6 100644 --- a/ext/tk/sample/demos-en/cscroll.rb +++ b/ext/tk/sample/demos-en/cscroll.rb @@ -52,7 +52,7 @@ unless $tk_version =~ /^4\.[01]/ TkGrid.columnconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0) end -# canvas 設定 +# canvas $cscroll_canvas = TkCanvas.new($cscroll_demo, 'relief'=>'sunken', 'borderwidth'=>2, 'scrollregion'=>['-11c', '-11c', '50c', '20c'] diff --git a/ext/tk/sample/demos-en/dialog1.rb b/ext/tk/sample/demos-en/dialog1.rb index 374fedc985..af476ecd05 100644 --- a/ext/tk/sample/demos-en/dialog1.rb +++ b/ext/tk/sample/demos-en/dialog1.rb @@ -22,7 +22,7 @@ class TkDialog_Demo1 < TkDialog end def buttons - ["Dismiss", "", "Show Code"] + # ["Dismiss", "", "Show Code"] ["OK", "Cancel", "Show Code"] end end diff --git a/ext/tk/sample/demos-en/entry3.rb b/ext/tk/sample/demos-en/entry3.rb index 44f788225c..3ec162e482 100644 --- a/ext/tk/sample/demos-en/entry3.rb +++ b/ext/tk/sample/demos-en/entry3.rb @@ -158,6 +158,8 @@ def validatePhoneChange(widget, vmode, idx, char) widget.insert(idx, $phoneNumberMap[char] || char) Tk.after_idle(proc{phoneSkipRight(widget, -1)}) return true + # Tk.update(true) # Don't work 'update' inter validation callback. + # It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). end return false end diff --git a/ext/tk/sample/demos-en/floor2.rb b/ext/tk/sample/demos-en/floor2.rb new file mode 100644 index 0000000000..7e418066d4 --- /dev/null +++ b/ext/tk/sample/demos-en/floor2.rb @@ -0,0 +1,1720 @@ +%# floor2.rb +# +# This demonstration script creates a canvas widet that displays the +# floorplan for DEC's Western Research Laboratory. +# +# floorDisplay widget demo (called by 'widget') +# + +# floorDisplay2 -- +# Recreate the floorplan display in the canvas given by "w". The +# floor given by "active" is displayed on top with its office structure +# visible. +# +# Arguments: +# w - Name of the canvas window. +# active - Number of active floor (1, 2, or 3). + +def floorDisplay2(w,active) + return if $activeFloor2 == active + + w.delete('all') + $activeFloor2 = active + + # First go through the three floors, displaying the backgrounds for + # each floor. + + floor2_bg1(w,$floor2_colors['bg1'],$floor2_colors['outline1']) + floor2_bg2(w,$floor2_colors['bg2'],$floor2_colors['outline2']) + floor2_bg3(w,$floor2_colors['bg3'],$floor2_colors['outline3']) + + # Raise the background for the active floor so that it's on top. + + w.raise("floor#{active}") + + # Create a dummy item just to mark this point in the display list, + # so we can insert highlights here. + + w.create(TkcRectangle,0,100,1,101,'fill'=>'','outline'=>'','tags'=>'marker') + + # Add the walls and labels for the active floor, along with + # transparent polygons that define the rooms on the floor. + # Make sure that the room polygons are on top. + + $floorLabels2.clear + $floorItems2.clear + send("floor2_fg#{active}", w, $floor2_colors['offices']) + w.raise('room') + + # Offset the floors diagonally from each other. + + w.move('floor1', '2c', '2c') + w.move('floor2', '1c', '1c') + + # Create items for the room entry and its label. + w.create(TkcWindow, 600, 100, 'anchor'=>'w', 'window'=>$floor2_entry) + w.create(TkcText, 600, 100, 'anchor'=>'e', 'text'=>"Room: ") + w['scrollregion'] = w.bbox('all') +end + +# newRoom2 -- +# This method is invoked whenever the mouse enters a room +# in the floorplan. It changes tags so that the current room is +# highlighted. +# +# Arguments: +# w - The name of the canvas window. + +def newRoom2(w) + id = w.find_withtag('current')[0] + $currentRoom2.value = $floorLabels2[id.id] if id != "" + Tk.update(true) +end + +# roomChanged2 -- +# This method is invoked whenever the currentRoom variable changes. +# It highlights the current room and unhighlights any previous room. +# +# Arguments: +# w - The canvas window displaying the floorplan. +# args - Not used. + +def roomChanged2(w,*args) + w.delete('highlight') + item = $floorItems2[$currentRoom2.value] + return if item == nil + new = TkcPolygon.new(w, *(w.coords(item))) + new.configure('fill'=>$floor2_colors['active'], 'tags'=>'highlight') + w.raise(new, 'marker') +end + +# floor2_bg1 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the background information for the first +# floor. +# +# Arguments: +# w - The canvas window. +# fill - Fill color to use for the floor's background. +# outline - Color to use for the floor's outline. + +def floor2_bg1(w,fill,outline) + w.create(TkcPolygon,347,80,349,82,351,84,353,85,363,92,375,99,386,104, + 386,129,398,129,398,162,484,162,484,129,559,129,559,133,725, + 133,725,129,802,129,802,389,644,389,644,391,559,391,559,327, + 508,327,508,311,484,311,484,278,395,278,395,288,400,288,404, + 288,409,290,413,292,418,297,421,302,422,309,421,318,417,325, + 411,330,405,332,397,333,344,333,340,334,336,336,335,338,332, + 342,331,347,332,351,334,354,336,357,341,359,340,360,335,363, + 331,365,326,366,304,366,304,355,258,355,258,387,60,387,60,391, + 0,391,0,337,3,337,3,114,8,114,8,25,30,25,30,5,93,5,98,5,104,7, + 110,10,116,16,119,20,122,28,123,32,123,68,220,68,220,34,221, + 22,223,17,227,13,231,8,236,4,242,2,246,0,260,0,283,1,300,5, + 321,14,335,22,348,25,365,29,363,39,358,48,352,56,337,70, + 344,76,347,80, 'tags'=>['floor1','bg'], 'fill'=>fill) + w.create(TkcLine,386,129,398,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,258,355,258,387, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,0,337,0,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,3,114,3,337, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,162,398,162, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,398,162,398,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,278,484,311, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,327,508,327, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,644,391,559,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,644,389,644,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,725,133,559,133, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,725,129,802,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,802,389,802,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,3,337,0,337, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,391,559,327, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,802,389,644,389, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,8,25,8,114, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,8,114,3,114, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,30,25,8,25, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,278,395,278, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,30,25,30,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,93,5,30,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,98,5,93,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,104,7,98,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,110,10,104,7, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,116,16,110,10, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,119,20,116,16, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,122,28,119,20, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,123,32,122,28, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,123,68,123,32, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,220,68,123,68, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,386,129,386,104, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,386,104,375,99, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,375,99,363,92, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,353,85,363,92, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,220,68,220,34, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,337,70,352,56, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,352,56,358,48, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,358,48,363,39, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,363,39,365,29, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,365,29,348,25, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,348,25,335,22, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,335,22,321,14, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,321,14,300,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,300,5,283,1, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,283,1,260,0, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,260,0,246,0, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,246,0,242,2, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,242,2,236,4, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,236,4,231,8, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,231,8,227,13, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,223,17,227,13, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,221,22,223,17, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,220,34,221,22, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,340,360,335,363, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,335,363,331,365, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,331,365,326,366, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,326,366,304,366, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,304,355,304,366, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,395,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,404,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,409,290,404,288, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,413,292,409,290, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,418,297,413,292, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,421,302,418,297, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,422,309,421,302, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,421,318,422,309, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,421,318,417,325, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,417,325,411,330, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,411,330,405,332, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,405,332,397,333, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,397,333,344,333, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,344,333,340,334, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,340,334,336,336, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,336,336,335,338, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,335,338,332,342, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,331,347,332,342, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,332,351,331,347, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,334,354,332,351, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,336,357,334,354, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,341,359,336,357, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,341,359,340,360, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,395,288,395,278, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,304,355,258,355, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,347,80,344,76, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,344,76,337,70, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,349,82,347,80, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,351,84,349,82, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,353,85,351,84, 'fill'=>outline, 'tags'=>['floor1','bg']) +end + +# floor2_bg2 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the background information for the first +# floor. +# +# Arguments: +# w - The canvas window. +# fill - Fill color to use for the floor's background. +# outline - Color to use for the floor's outline. + +def floor2_bg2(w,fill,outline) + w.create(TkcPolygon,559,129,484,129,484,162,398,162,398,129,315,129, + 315,133,176,133,176,129,96,129,96,133,3,133,3,339,0,339,0,391, + 60,391,60,387,258,387,258,329,350,329,350,311,395,311,395,280, + 484,280,484,311,508,311,508,327,558,327,558,391,644,391,644, + 367,802,367,802,129,725,129,725,133,559,133,559,129, + 'tags'=>['floor2','bg'], 'fill'=>fill) + w.create(TkcLine,350,311,350,329, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,398,129,398,162, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,802,367,802,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,802,129,725,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,559,133,725,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,802,367,644,367, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,644,367,644,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,644,391,558,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,558,327,558,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,558,327,508,327, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,280,484,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,398,162,484,162, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,280,395,280, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,395,280,395,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,3,133,3,339, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,3,339,0,339, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,0,339,0,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,258,329,258,387, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,395,311,350,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,398,129,315,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,176,133,315,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,3,133,96,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,176,133,176,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor2','bg']) +end + +# floor2_bg3 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the background information for the first +# floor. +# +# Arguments: +# w - The canvas window. +# fill - Fill color to use for the floor's background. +# outline - Color to use for the floor's outline. + +def floor2_bg3(w,fill,outline) + w.create(TkcPolygon,159,300,107,300,107,248,159,248,159,129,96,129,96, + 133,21,133,21,331,0,331,0,391,60,391,60,370,159,370,159,300, + 'tags'=>['floor3','bg'], 'fill'=>fill) + w.create(TkcPolygon,258,370,258,329,350,329,350,311,399,311,399,129, + 315,129,315,133,176,133,176,129,159,129,159,370,258,370, + 'tags'=>['floor3','bg'], 'fill'=>fill) + w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,176,129,176,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,315,133,176,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,399,129,315,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,399,311,399,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,399,311,350,311, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,350,329,350,311, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,258,370,258,329, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,60,370,258,370, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,60,370,60,391, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,0,391,0,331, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,21,331,0,331, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,21,331,21,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,96,133,21,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,107,300,159,300,159,248,107,248,107,300, + 'fill'=>outline, 'tags'=>['floor3','bg']) +end + +# floor2_fg1 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the foreground information for the first +# floor (office outlines and numbers). +# +# Arguments: +# w - The canvas window. +# color - Color to use for drawing foreground information. + +def floor2_fg1(w,color) + i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '101' + $floorItems2['101'] = i + w.create(TkcText,358,209, 'text'=>'101', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Pub Lift1' + $floorItems2['Pub Lift1'] = i + w.create(TkcText,323,223, 'text'=>'Pub Lift1', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Priv Lift1' + $floorItems2['Priv Lift1'] = i + w.create(TkcText,323,188, 'text'=>'Priv Lift1', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,42,389,42,337,1,337,1,389, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '110' + $floorItems2['110'] = i + w.create(TkcText,21.5,363, 'text'=>'110', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,59,389,59,385,90,385,90,337,44,337,44,389, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '109' + $floorItems2['109'] = i + w.create(TkcText,67,363, 'text'=>'109', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,51,300,51,253,6,253,6,300, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '111' + $floorItems2['111'] = i + w.create(TkcText,28.5,276.5, 'text'=>'111', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,98,248,98,309,79,309,79,248, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '117B' + $floorItems2['117B'] = i + w.create(TkcText,88.5,278.5, 'text'=>'117B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,51,251,51,204,6,204,6,251, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '112' + $floorItems2['112'] = i + w.create(TkcText,28.5,227.5, 'text'=>'112', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,6,156,51,156,51,203,6,203, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '113' + $floorItems2['113'] = i + w.create(TkcText,28.5,179.5, 'text'=>'113', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,85,169,79,169,79,192,85,192, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '117A' + $floorItems2['117A'] = i + w.create(TkcText,82,180.5, 'text'=>'117A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,77,302,77,168,53,168,53,302, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '117' + $floorItems2['117'] = i + w.create(TkcText,65,235, 'text'=>'117', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,51,155,51,115,6,115,6,155, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '114' + $floorItems2['114'] = i + w.create(TkcText,28.5,135, 'text'=>'114', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,95,115,53,115,53,168,95,168, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '115' + $floorItems2['115'] = i + w.create(TkcText,74,141.5, 'text'=>'115', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,87,113,87,27,10,27,10,113, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '116' + $floorItems2['116'] = i + w.create(TkcText,48.5,70, 'text'=>'116', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,89,91,128,91,128,113,89,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '118' + $floorItems2['118'] = i + w.create(TkcText,108.5,102, 'text'=>'118', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,178,128,178,132,216,132,216,91, + 163,91,163,112,149,112,149,128, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '120' + $floorItems2['120'] = i + w.create(TkcText,189.5,111.5, 'text'=>'120', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,79,193,87,193,87,169,136,169,136,192, + 156,192,156,169,175,169,175,246,79,246, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '122' + $floorItems2['122'] = i + w.create(TkcText,131,207.5, 'text'=>'122', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,138,169,154,169,154,191,138,191, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '121' + $floorItems2['121'] = i + w.create(TkcText,146,180, 'text'=>'121', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,99,300,126,300,126,309,99,309, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '106A' + $floorItems2['106A'] = i + w.create(TkcText,112.5,304.5, 'text'=>'106A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,128,299,128,309,150,309,150,248,99,248,99,299, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '105' + $floorItems2['105'] = i + w.create(TkcText,124.5,278.5, 'text'=>'105', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,174,309,174,300,152,300,152,309, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '106B' + $floorItems2['106B'] = i + w.create(TkcText,163,304.5, 'text'=>'106B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,176,299,176,309,216,309,216,248,152,248,152,299, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '104' + $floorItems2['104'] = i + w.create(TkcText,184,278.5, 'text'=>'104', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,138,385,138,337,91,337,91,385, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '108' + $floorItems2['108'] = i + w.create(TkcText,114.5,361, 'text'=>'108', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,256,337,140,337,140,385,256,385, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '107' + $floorItems2['107'] = i + w.create(TkcText,198,361, 'text'=>'107', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,300,353,300,329,260,329,260,353, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Smoking' + $floorItems2['Smoking'] = i + w.create(TkcText,280,341, 'text'=>'Smoking', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,314,135,314,170,306,170,306,246,177,246,177,135, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '123' + $floorItems2['123'] = i + w.create(TkcText,245.5,190.5, 'text'=>'123', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,217,248,301,248,301,326,257,326,257,310,217,310, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '103' + $floorItems2['103'] = i + w.create(TkcText,259,287, 'text'=>'103', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,396,188,377,188,377,169,316,169,316,131,396,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '124' + $floorItems2['124'] = i + w.create(TkcText,356,150, 'text'=>'124', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,397,226,407,226,407,189,377,189,377,246,397,246, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '125' + $floorItems2['125'] = i + w.create(TkcText,392,217.5, 'text'=>'125', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,399,187,409,187,409,207,474,207,474,164,399,164, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '126' + $floorItems2['126'] = i + w.create(TkcText,436.5,185.5, 'text'=>'126', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,409,209,409,229,399,229,399,253, + 486,253,486,239,474,239,474,209, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '127' + $floorItems2['127'] = i + w.create(TkcText,436.5,'231', 'text'=>'127', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,501,164,501,174,495,174,495,188, + 490,188,490,204,476,204,476,164, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'MShower' + $floorItems2['MShower'] = i + w.create(TkcText,488.5,'184', 'text'=>'MShower', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,497,176,513,176,513,204,492,204,492,190,497,190, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Closet' + $floorItems2['Closet'] = i + w.create(TkcText,502.5,190, 'text'=>'Closet', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,476,237,476,206,513,206,513,254,488,254,488,237, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'WShower' + $floorItems2['WShower'] = i + w.create(TkcText,494.5,230, 'text'=>'WShower', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,486,131,558,131,558,135,724,135,724,166, + 697,166,697,275,553,275,531,254,515,254, + 515,174,503,174,503,161,486,161, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '130' + $floorItems2['130'] = i + w.create(TkcText,638.5,205, 'text'=>'130', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,308,242,339,242,339,248,342,248, + 342,246,397,246,397,276,393,276, + 393,309,300,309,300,248,308,248, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '102' + $floorItems2['102'] = i + w.create(TkcText,367.5,278.5, 'text'=>'102', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,397,255,486,255,486,276,397,276, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '128' + $floorItems2['128'] = i + w.create(TkcText,441.5,265.5, 'text'=>'128', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,510,309,486,309,486,255,530,255, + 552,277,561,277,561,325,510,325, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '129' + $floorItems2['129'] = i + w.create(TkcText,535.5,293, 'text'=>'129', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,696,281,740,281,740,387,642,387, + 642,389,561,389,561,277,696,277, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '133' + $floorItems2['133'] = i + w.create(TkcText,628.5,335, 'text'=>'133', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,742,387,742,281,800,281,800,387, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '132' + $floorItems2['132'] = i + w.create(TkcText,771,334, 'text'=>'132', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,800,168,800,280,699,280,699,168, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '134' + $floorItems2['134'] = i + w.create(TkcText,749.5,224, 'text'=>'134', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,726,131,726,166,800,166,800,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '135' + $floorItems2['135'] = i + w.create(TkcText,763,148.5, 'text'=>'135', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,340,360,335,363,331,365,326,366,304,366, + 304,312,396,312,396,288,400,288,404,288, + 409,290,413,292,418,297,421,302,422,309, + 421,318,417,325,411,330,405,332,397,333, + 344,333,340,334,336,336,335,338,332,342, + 331,347,332,351,334,354,336,357,341,359, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Ramona Stair' + $floorItems2['Ramona Stair'] = i + w.create(TkcText,368,323, 'text'=>'Ramona Stair', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,30,23,30,5,93,5,98,5,104,7,110,10,116,16,119,20, + 122,28,123,32,123,68,220,68,220,87,90,87,90,23, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'University Stair' + $floorItems2['University Stair'] = i + w.create(TkcText,155,77.5, 'text'=>'University Stair', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,282,37,295,40,312,49,323,56,337,70,352,56, + 358,48,363,39,365,29,348,25,335,22,321,14, + 300,5,283,1,260,0,246,0,242,2,236,4,231,8, + 227,13,223,17,221,22,220,34,260,34, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Plaza Stair' + $floorItems2['Plaza Stair'] = i + w.create(TkcText,317.5,28.5, 'text'=>'Plaza Stair', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,220,34,260,34,282,37,295,40,312,49, + 323,56,337,70,350,83,365,94,377,100, + 386,104,386,128,220,128, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Plaza Deck' + $floorItems2['Plaza Deck'] = i + w.create(TkcText,303,81, 'text'=>'Plaza Deck', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,257,336,77,336,6,336,6,301,77,301,77,310,257,310, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '106' + $floorItems2['106'] = i + w.create(TkcText,131.5,318.5, 'text'=>'106', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,146,110,162,110,162,91,130,91,130,115,95,115, + 95,128,114,128,114,151,157,151,157,153,112,153, + 112,130,97,130,97,168,175,168,175,131,146,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '119' + $floorItems2['119'] = i + w.create(TkcText,143.5,133, 'text'=>'119', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + w.create(TkcLine,155,191,155,189, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,96,129,96,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,169,176,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,176,247,176,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,376,246,376,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,307,247,307,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,147,129,176,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,202,133,176,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,352,258,387, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,0,337,0,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,3,114,3,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,237,52,273, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,189,52,225, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,140,52,177, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,395,306,395,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,531,254,398,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,475,178,475,238, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,502,162,398,162, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,398,129,398,188, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,208,475,208, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,278,484,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,327,508,327, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,644,391,559,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,644,389,644,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,514,205,475,205, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,496,189,496,187, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,149,725,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,129,802,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,802,389,802,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,739,167,802,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,0,337,9,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,58,337,21,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,43,391,43,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,105,337,75,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,91,387,91,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,154,337,117,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,139,387,139,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,227,337,166,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,337,251,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,328,302,328, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,302,355,302,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,395,311,302,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,278,395,278, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,395,294,395,278, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,473,278,473,275, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,473,256,473,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,533,257,531,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,553,276,551,274, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,698,276,553,276, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,391,559,327, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,802,389,644,389, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,741,314,741,389, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,698,280,698,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,707,280,698,280, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,802,280,731,280, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,741,280,741,302, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,698,167,727,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,137,725,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,514,254,514,175, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,496,175,514,175, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,502,175,502,162, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,475,166,475,162, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,496,176,496,175, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,491,189,496,189, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,491,205,491,189, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,487,238,475,238, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,487,240,487,238, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,487,252,487,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,315,133,304,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,256,133,280,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,247,270,247, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,307,247,294,247, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,214,133,232,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,217,247,217,266, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,217,309,217,291, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,217,309,172,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,154,309,148,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,175,300,175,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,151,300,175,300, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,151,247,151,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,237,78,265, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,286,78,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,106,309,78,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,130,309,125,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,99,309,99,247, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,127,299,99,299, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,127,309,127,299, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,155,191,137,191, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,137,169,137,191, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,171,78,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,190,78,218, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,86,192,86,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,86,192,78,192, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,301,3,301, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,286,52,301, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,252,3,252, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,203,3,203, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,3,156,52,156, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,8,25,8,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,63,114,3,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,75,114,97,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,108,114,129,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,129,114,129,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,114,52,128, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,132,89,88,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,88,25,88,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,88,114,88,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,218,89,144,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,147,111,147,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,162,111,147,111, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,162,109,162,111, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,162,96,162,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,218,89,218,94, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,218,89,218,119, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,8,25,88,25, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,337,258,328, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,129,96,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,302,355,258,355, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,386,104,386,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,377,100,386,104, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,365,94,377,100, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,350,83,365,94, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,337,70,350,83, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,337,70,323,56, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,312,49,323,56, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,295,40,312,49, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,282,37,295,40, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,260,34,282,37, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,253,34,260,34, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,386,128,386,104, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,152,113,129, 'fill'=>color, 'tags'=>['floor1','wall']) +end + +# floor2_fg2 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the foreground information for the second +# floor (office outlines and numbers). +# +# Arguments: +# w - The canvas window. +# color - Color to use for drawing foreground information. + +def floor2_fg2(w,color) + i = TkcPolygon.new(w,748,188,755,188,755,205,758,205,758,222, + 800,222,800,168,748,168, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '238' + $floorItems2['238'] = i + w.create(TkcText,774,195, 'text'=>'238', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,726,188,746,188,746,166,800,166,800,131,726,131, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '237' + $floorItems2['237'] = i + w.create(TkcText,763,148.5, 'text'=>'237', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,497,187,497,204,559,204,559,324,641,324, + 643,324,643,291,641,291,641,205,696,205, + 696,291,694,291,694,314,715,314,715,291, + 715,205,755,205,755,190,724,190,724,187, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '246' + $floorItems2['246'] = i + w.create(TkcText,600,264, 'text'=>'246', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,694,279,643,279,643,314,694,314, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '247' + $floorItems2['247'] = i + w.create(TkcText,668.5,296.5, 'text'=>'247', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,232,250,308,250,308,242,339,242,339,246, + 397,246,397,255,476,255,476,250,482,250,559,250, + 559,274,482,274,482,278,396,278,396,274,232,274, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '202' + $floorItems2['202'] = i + w.create(TkcText,285.5,260, 'text'=>'202', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,53,228,53,338,176,338,233,338,233,196, + 306,196,306,180,175,180,175,169,156,169, + 156,196,176,196,176,228, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '206' + $floorItems2['206'] = i + w.create(TkcText,143,267, 'text'=>'206', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,277,6,277,6,338,51,338, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '212' + $floorItems2['212'] = i + w.create(TkcText,28.5,307.5, 'text'=>'212', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,557,276,486,276,486,309,510,309,510,325,557,325, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '245' + $floorItems2['245'] = i + w.create(TkcText,521.5,300.5, 'text'=>'245', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,560,389,599,389,599,326,560,326, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '244' + $floorItems2['244'] = i + w.create(TkcText,579.5,357.5, 'text'=>'244', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,601,389,601,326,643,326,643,389, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '243' + $floorItems2['243'] = i + w.create(TkcText,622,357.5, 'text'=>'243', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,688,316,645,316,645,365,688,365, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '242' + $floorItems2['242'] = i + w.create(TkcText,666.5,340.5, 'text'=>'242', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,802,367,759,367,759,226,802,226, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = 'Barbecue Deck' + $floorItems2['Barbecue Deck'] = i + w.create(TkcText,780.5,296.5, 'text'=>'Barbecue Deck', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,755,262,755,314,717,314,717,262, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '240' + $floorItems2['240'] = i + w.create(TkcText,736,288, 'text'=>'240', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,755,316,689,316,689,365,755,365, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '241' + $floorItems2['241'] = i + w.create(TkcText,722,340.5, 'text'=>'241', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,755,206,717,206,717,261,755,261, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '239' + $floorItems2['239'] = i + w.create(TkcText,736,233.5, 'text'=>'239', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,695,277,643,277,643,206,695,206, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '248' + $floorItems2['248'] = i + w.create(TkcText,669,241.5, 'text'=>'248', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,676,135,676,185,724,185,724,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '236' + $floorItems2['236'] = i + w.create(TkcText,700,160, 'text'=>'236', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,675,135,635,135,635,145,628,145,628,185,675,185, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '235' + $floorItems2['235'] = i + w.create(TkcText,651.5,160, 'text'=>'235', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,626,143,633,143,633,135,572,135, + 572,143,579,143,579,185,626,185, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '234' + $floorItems2['234'] = i + w.create(TkcText,606,160, 'text'=>'234', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,557,135,571,135,571,145,578,145, + 578,185,527,185,527,131,557,131, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '233' + $floorItems2['233'] = i + w.create(TkcText,552.5,158, 'text'=>'233', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,476,249,557,249,557,205,476,205, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '230' + $floorItems2['230'] = i + w.create(TkcText,516.5,227, 'text'=>'230', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,476,164,486,164,486,131,525,131,525,185,476,185, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '232' + $floorItems2['232'] = i + w.create(TkcText,500.5,158, 'text'=>'232', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,476,186,495,186,495,204,476,204, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '229' + $floorItems2['229'] = i + w.create(TkcText,485.5,195, 'text'=>'229', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,474,207,409,207,409,187,399,187,399,164,474,164, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '227' + $floorItems2['227'] = i + w.create(TkcText,436.5,185.5, 'text'=>'227', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,399,228,399,253,474,253,474,209,409,209,409,228, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '228' + $floorItems2['228'] = i + w.create(TkcText,436.5,231, 'text'=>'228', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,397,246,397,226,407,226,407,189,377,189,377,246, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '226' + $floorItems2['226'] = i + w.create(TkcText,392,217.5, 'text'=>'226', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,377,169,316,169,316,131,397,131,397,188,377,188, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '225' + $floorItems2['225'] = i + w.create(TkcText,356.5,150, 'text'=>'225', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,234,198,306,198,306,249,234,249, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '224' + $floorItems2['224'] = i + w.create(TkcText,270,223.5, 'text'=>'224', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,270,179,306,179,306,170,314,170,314,135,270,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '223' + $floorItems2['223'] = i + w.create(TkcText,292,157, 'text'=>'223', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,268,179,221,179,221,135,268,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '222' + $floorItems2['222'] = i + w.create(TkcText,244.5,157, 'text'=>'222', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,177,179,219,179,219,135,177,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '221' + $floorItems2['221'] = i + w.create(TkcText,198,157, 'text'=>'221', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,299,327,349,327,349,284,341,284,341,276,299,276, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '204' + $floorItems2['204'] = i + w.create(TkcText,324,301.5, 'text'=>'204', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,234,276,297,276,297,327,257,327,257,338,234,338, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '205' + $floorItems2['205'] = i + w.create(TkcText,265.5,307, 'text'=>'205', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,256,385,256,340,212,340,212,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '207' + $floorItems2['207'] = i + w.create(TkcText,234,362.5, 'text'=>'207', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,210,340,164,340,164,385,210,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '208' + $floorItems2['208'] = i + w.create(TkcText,187,362.5, 'text'=>'208', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,115,340,162,340,162,385,115,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '209' + $floorItems2['209'] = i + w.create(TkcText,138.5,362.5, 'text'=>'209', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,89,228,89,156,53,156,53,228, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '217' + $floorItems2['217'] = i + w.create(TkcText,71,192, 'text'=>'217', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,89,169,97,169,97,190,89,190, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '217A' + $floorItems2['217A'] = i + w.create(TkcText,93,179.5, 'text'=>'217A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,89,156,89,168,95,168,95,135,53,135,53,156, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '216' + $floorItems2['216'] = i + w.create(TkcText,71,145.5, 'text'=>'216', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,179,51,135,6,135,6,179, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '215' + $floorItems2['215'] = i + w.create(TkcText,28.5,157, 'text'=>'215', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,227,6,227,6,180,51,180, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '214' + $floorItems2['214'] = i + w.create(TkcText,28.5,203.5, 'text'=>'214', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,275,6,275,6,229,51,229, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '213' + $floorItems2['213'] = i + w.create(TkcText,28.5,252, 'text'=>'213', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,114,340,67,340,67,385,114,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '210' + $floorItems2['210'] = i + w.create(TkcText,90.5,362.5, 'text'=>'210', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,59,389,59,385,65,385,65,340,1,340,1,389, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '211' + $floorItems2['211'] = i + w.create(TkcText,33,364.5, 'text'=>'211', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,393,309,350,309,350,282,342,282,342,276,393,276, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '203' + $floorItems2['203'] = i + w.create(TkcText,367.5,292.5, 'text'=>'203', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,99,191,91,191,91,226,174,226,174,198, + 154,198,154,192,109,192,109,169,99,169, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '220' + $floorItems2['220'] = i + w.create(TkcText,132.5,208.5, 'text'=>'220', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = 'Priv Lift2' + $floorItems2['Priv Lift2'] = i + w.create(TkcText,323,188, 'text'=>'Priv Lift2', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = 'Pub Lift 2' + $floorItems2['Pub Lift 2'] = i + w.create(TkcText,323,223, 'text'=>'Pub Lift 2', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '218' + $floorItems2['218'] = i + w.create(TkcText,136,149.5, 'text'=>'218', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '219' + $floorItems2['219'] = i + w.create(TkcText,132.5,180, 'text'=>'219', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '201' + $floorItems2['201'] = i + w.create(TkcText,358,209, 'text'=>'201', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + w.create(TkcLine,641,186,678,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,350,757,367, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,634,133,634,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,634,144,627,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,572,133,572,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,572,144,579,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,129,398,162, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,174,197,175,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,175,197,175,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,206,757,221, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,727,189,725,189, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,747,167,802,167, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,747,167,747,189, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,755,189,739,189, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,769,224,757,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,802,224,802,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,802,129,725,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,725,189,725,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,725,186,690,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,676,133,676,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,627,144,627,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,629,186,593,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,579,144,579,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,526,129,526,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,540,186,581,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,528,186,523,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,511,186,475,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,496,190,496,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,496,205,496,202, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,475,205,527,205, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,205,539,205, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,205,558,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,249,475,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,662,206,642,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,695,206,675,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,695,278,642,278, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,642,291,642,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,695,291,695,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,716,208,716,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,206,716,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,221,757,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,793,224,802,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,262,716,262, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,716,220,716,264, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,716,315,716,276, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,315,703,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,325,757,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,367,644,367, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,689,367,689,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,647,315,644,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,659,315,691,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,600,325,600,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,627,325,644,325, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,644,391,644,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,615,325,575,325, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,644,391,558,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,563,325,558,325, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,391,558,314, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,327,508,327, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,275,484,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,302,558,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,275,484,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,475,208,408,208, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,188,398,162, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,162,484,162, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,475,162,475,254, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,254,475,254, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,280,395,280, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,395,311,395,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,307,197,293,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,278,197,233,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,233,197,233,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,307,179,284,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,233,249,278,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,269,179,269,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,220,179,220,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,155,191,110,191, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,90,190,98,190, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,98,169,98,190, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,133,52,165, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,214,52,177, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,226,52,262, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,274,52,276, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,234,275,234,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,226,339,258,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,211,387,211,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,214,339,177,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,3,133,3,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,165,339,129,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,117,339,80,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,68,339,59,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,0,339,46,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,0,339,0,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,258,329,258,387, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,395,311,350,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,176,133,315,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,3,133,96,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,66,387,66,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,115,387,115,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,163,387,163,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,234,275,276,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,288,275,309,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,321,275,341,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,375,275,395,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,376,245,376,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,245,340,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,293,250,307,250, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,271,179,238,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,226,179,195,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,174,169,176,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,162,169,90,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,96,169,96,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,175,227,90,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,90,190,90,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,179,3,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,228,3,228, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,276,3,276, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,110,191,110,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,155,189,155,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor2','wall']) +end + +# floor2_fg3 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the foreground information for the third +# floor (office outlines and numbers). +# +# Arguments: +# w - The canvas window. +# color - Color to use for drawing foreground information. + +def floor2_fg3(w,color) + i = TkcPolygon.new(w,89,228,89,180,70,180,70,228, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '316' + $floorItems2['316'] = i + w.create(TkcText,79.5,204, 'text'=>'316', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,115,368,162,368,162,323,115,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '309' + $floorItems2['309'] = i + w.create(TkcText,138.5,345.5, 'text'=>'309', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,164,323,164,368,211,368,211,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '308' + $floorItems2['308'] = i + w.create(TkcText,187.5,345.5, 'text'=>'308', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,256,368,212,368,212,323,256,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '307' + $floorItems2['307'] = i + w.create(TkcText,234,345.5, 'text'=>'307', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,244,276,297,276,297,327,260,327,260,321,244,321, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '305' + $floorItems2['305'] = i + w.create(TkcText,270.5,301.5, 'text'=>'305', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,251,219,251,203,244,203,244,219, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '324B' + $floorItems2['324B'] = i + w.create(TkcText,247.5,211, 'text'=>'324B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,251,249,244,249,244,232,251,232, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '324A' + $floorItems2['324A'] = i + w.create(TkcText,247.5,240.5, 'text'=>'324A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,223,135,223,179,177,179,177,135, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '320' + $floorItems2['320'] = i + w.create(TkcText,200,157, 'text'=>'320', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,114,368,114,323,67,323,67,368, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '310' + $floorItems2['310'] = i + w.create(TkcText,90.5,345.5, 'text'=>'310', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,23,277,23,321,68,321,68,277, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '312' + $floorItems2['312'] = i + w.create(TkcText,45.5,299, 'text'=>'312', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,23,229,68,229,68,275,23,275, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '313' + $floorItems2['313'] = i + w.create(TkcText,45.5,252, 'text'=>'313', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,68,227,23,227,23,180,68,180, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '314' + $floorItems2['314'] = i + w.create(TkcText,40.5,203.5, 'text'=>'314', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,95,179,95,135,23,135,23,179, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '315' + $floorItems2['315'] = i + w.create(TkcText,59,157, 'text'=>'315', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,99,226,99,204,91,204,91,226, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '316B' + $floorItems2['316B'] = i + w.create(TkcText,95,215, 'text'=>'316B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,91,202,99,202,99,180,91,180, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '316A' + $floorItems2['316A'] = i + w.create(TkcText,95,191, 'text'=>'316A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,97,169,109,169,109,192,154,192,154,198, + 174,198,174,226,101,226,101,179,97,179, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '319' + $floorItems2['319'] = i + w.create(TkcText,141.5,209, 'text'=>'319', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,65,368,58,368,58,389,1,389,1,333,23,333,23,323,65,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '311' + $floorItems2['311'] = i + w.create(TkcText,29.5,361, 'text'=>'311', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '318' + $floorItems2['318'] = i + w.create(TkcText,132.5,180, 'text'=>'318', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '317' + $floorItems2['317'] = i + w.create(TkcText,136,149.5, 'text'=>'317', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,274,194,274,221,306,221,306,194, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '323' + $floorItems2['323'] = i + w.create(TkcText,290,207.5, 'text'=>'323', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,306,222,274,222,274,249,306,249, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '325' + $floorItems2['325'] = i + w.create(TkcText,290,235.5, 'text'=>'325', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,263,179,224,179,224,135,263,135, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '321' + $floorItems2['321'] = i + w.create(TkcText,243.5,157, 'text'=>'321', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,314,169,306,169,306,192,273,192, + 264,181,264,135,314,135, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '322' + $floorItems2['322'] = i + w.create(TkcText,293.5,163.5, 'text'=>'322', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = 'Pub Lift3' + $floorItems2['Pub Lift3'] = i + w.create(TkcText,323,223, 'text'=>'Pub Lift3', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = 'Priv Lift3' + $floorItems2['Priv Lift3'] = i + w.create(TkcText,323,188, 'text'=>'Priv Lift3', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,350,284,376,284,376,276,397,276,397,309,350,309, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '303' + $floorItems2['303'] = i + w.create(TkcText,373.5,292.5, 'text'=>'303', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,272,203,272,249,252,249,252,230, + 244,230,244,221,252,221,252,203, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '324' + $floorItems2['324'] = i + w.create(TkcText,262,226, 'text'=>'324', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,299,276,299,327,349,327,349,284,341,284,341,276, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '304' + $floorItems2['304'] = i + w.create(TkcText,324,301.5, 'text'=>'304', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '301' + $floorItems2['301'] = i + w.create(TkcText,358,209, 'text'=>'301', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,397,246,377,246,377,185,397,185, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '327' + $floorItems2['327'] = i + w.create(TkcText,387,215.5, 'text'=>'327', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,316,131,316,169,377,169,377,185,397,185,397,131, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '326' + $floorItems2['326'] = i + w.create(TkcText,365.5,150, 'text'=>'326', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,308,251,242,251,242,274,342,274,342,282,375, 282, + 375,274,397,274,397,248,339,248,339,242,308,242, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '302' + $floorItems2['302'] = i + w.create(TkcText,319.5,261, 'text'=>'302', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,70,321,242,321,242,200,259,200,259,203,272,203, + 272,193,263,180,242,180,175,180,175,169,156,169, + 156,196,177,196,177,228,107,228,70,228,70,275,107,275, + 107,248,160,248,160,301,107,301,107,275,70,275, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '306' + $floorItems2['306'] = i + w.create(TkcText,200.5,284.5, 'text'=>'306', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,396,247,399,247, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,399,129,399,311, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,202,243,202, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,251,231,243,231, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,220,251,220, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,250,243,202, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,155,197,155,190, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,110,192,110,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,155,192,110,192, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,176,197,176,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,69,280,69,274, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,276,69,276, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,69,262,69,226, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,228,69,228, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,179,75,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,69,179,69,214, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,220,90,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,204,90,202, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,203,100,203, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,187,90,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,227,176,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,100,179,100,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,100,179,87,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,96,179,96,129, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,162,169,96,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,173,169,176,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,195,179,226,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,224,133,224,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,264,179,264,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,238,179,264,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,207,273,193, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,235,273,250, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,224,273,219, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,193,307,193, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,222,307,222, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,384,247,376,247, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,247,376,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,283,366,283, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,283,376,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,399,275,376,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,341,275,320,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,308,275,298,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,322,243,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,275,284,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,322,226,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,212,370,212,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,214,322,177,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,163,370,163,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,165,322,129,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,84,322,117,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,71,322,64,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,115,322,115,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,66,322,66,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,52,322,21,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,331,0,331, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,331,21,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,96,133,21,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,315,133,176,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,315,129,399,129, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,399,311,350,311, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,322,258,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,60,370,258,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,60,370,60,391, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,0,391,0,331, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,307,250,307,242, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,250,243,250, 'fill'=>color, 'tags'=>['floor3','wall']) +end + +# Below is the "main program" that creates the floorplan demonstration. + +# toplevel widget +if defined?($floor2_demo) && $floor2_demo + $floor2_demo.destroy + $floor2_demo = nil +end + +# demo toplevel widget +$floor2_demo = TkToplevel.new {|w| + title("Floorplan Canvas Demonstration 2") + iconname("Floorplan2") + positionWindow(w) + geometry('+20+20') + minsize(100,100) +} + +# label +TkLabel.new($floor2_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', + 'text'=>"This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory. It has three levels. At any given time one of the levels is active, meaning that you can see its room structure. To activate a level, click the left mouse button anywhere on it. As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \"Room:\" entry. You can also type a room number in the entry and the room will light up."){ + pack('side'=>'top') +} + +# frame +$floor2_buttons = TkFrame.new($floor2_demo) {|frame| + TkButton.new(frame) { + text 'Dismiss' + command proc{ + tmppath = $floor2_demo + $floor2_demo = nil + tmppath.destroy + } + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'Show Code' + command proc{showCode 'floor2'} + }.pack('side'=>'left', 'expand'=>'yes') +} +$floor2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# +$floorLabels2 = {} +$floorItems2 = {} + +# canvas +if $tk_version =~ /^4\.[01]/ + $floor2_canvas_frame = TkFrame.new($floor2_demo,'bd'=>2,'relief'=>'sunken', + 'highlightthickness'=>2) + $floor2_canvas = TkCanvas.new($floor2_canvas_frame, + 'width'=>900, 'height'=>500, 'borderwidth'=>0, + 'highlightthickness'=>0) {|c| + TkScrollbar.new($floor2_demo, 'orient'=>'horiz', + 'command'=>proc{|*args| c.xview(*args)}){|hs| + c.xscrollcommand(proc{|first,last| hs.set first,last}) + pack('side'=>'bottom', 'fill'=>'x') + } + TkScrollbar.new($floor2_demo, 'command'=>proc{|*args| c.yview(*args)}){|vs| + c.yscrollcommand(proc{|first,last| vs.set first,last}) + pack('side'=>'right', 'fill'=>'y') + } + } + $floor2_canvas_frame.pack('side'=>'top','fill'=>'both', 'expand'=>'yes') + $floor2_canvas.pack('expand'=>'yes', 'fill'=>'both') + +else + TkFrame.new($floor2_demo) {|f| + pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') + + h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal') + v = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'vertical') + + TkFrame.new(f, 'bd'=>2, 'relief'=>'sunken') {|f1| + $floor2_canvas = TkCanvas.new(f1, 'width'=>900, 'height'=>500, + 'borderwidth'=>0, + 'highlightthickness'=>0) { + xscrollcommand(proc{|first,last| h.set first,last}) + yscrollcommand(proc{|first,last| v.set first,last}) + pack('expand'=>'yes', 'fill'=>'both') + } + grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, + 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') + } + + v.grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, + 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') + h.grid('padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, + 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') + + TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0) + TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0) + + pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1) + + v.command(proc{|*args| c.yview(*args)}) + h.command(proc{|*args| c.xview(*args)}) + } +end + + +# Create an entry for displaying and typing in current room. + +$currentRoom2 = TkVariable.new +$floor2_entry = TkEntry.new($floor2_canvas, 'width'=>10, 'relief'=>'sunken', + 'bd'=>2, 'textvariable'=>$currentRoom2) + +# Choose colors, then fill in the floorplan. + +$floor2_colors = {} +if TkWinfo.depth($floor2_canvas) > 1 + $floor2_colors['bg1'] = '#a9c1da' + $floor2_colors['outline1'] = '#77889a' + $floor2_colors['bg2'] = '#9ab0c6' + $floor2_colors['outline2'] = '#687786' + $floor2_colors['bg3'] = '#8ba0b3' + $floor2_colors['outline3'] = '#596673' + $floor2_colors['offices'] = 'Black' + $floor2_colors['active'] = '#c4d1df' +else + $floor2_colors['bg1'] = 'white' + $floor2_colors['outline1'] = 'black' + $floor2_colors['bg2'] = 'white' + $floor2_colors['outline2'] = 'black' + $floor2_colors['bg3'] = 'white' + $floor2_colors['outline3'] = 'black' + $floor2_colors['offices'] = 'Black' + $floor2_colors['active'] = 'black' +end + +$activeFloor2 = '' +floorDisplay2 $floor2_canvas,3 + +# Set up event bindings for canvas: + +$floor2_canvas.itembind('floor1', '1', proc{floorDisplay2 $floor2_canvas,1}) +$floor2_canvas.itembind('floor2', '1', proc{floorDisplay2 $floor2_canvas,2}) +$floor2_canvas.itembind('floor3', '1', proc{floorDisplay2 $floor2_canvas,3}) +$floor2_canvas.itembind('room', 'Enter', proc{newRoom2 $floor2_canvas}) +$floor2_canvas.itembind('room', 'Leave', proc{$currentRoom2.value = ''}) +$floor2_canvas.bind('2', proc{|x,y| $floor2_canvas.scan_mark x,y}, '%x %y') +$floor2_canvas.bind('B2-Motion', + proc{|x,y| $floor2_canvas.scan_dragto x,y}, '%x %y') +$floor2_canvas.bind('Destroy', proc{$currentRoom2.unset}) +$currentRoom2.value = '' +$currentRoom2.trace('w',proc{roomChanged2 $floor2_canvas}) diff --git a/ext/tk/sample/demos-en/icon.rb b/ext/tk/sample/demos-en/icon.rb index 7557257ef4..0acf8c041a 100644 --- a/ext/tk/sample/demos-en/icon.rb +++ b/ext/tk/sample/demos-en/icon.rb @@ -48,30 +48,33 @@ TkFrame.new($icon_demo) {|frame| # image flagup = \ -TkBitmapImage.new('file'=>[$demo_dir, +TkBitmapImage.new('file'=>[$demo_dir,'..', 'images','flagup.xbm'].join(File::Separator), 'maskfile'=>\ - [$demo_dir,'images','flagup.xbm'].join(File::Separator)) + [$demo_dir,'..','images','flagup.xbm'].join(File::Separator)) flagdown = \ -TkBitmapImage.new('file'=>[$demo_dir, +TkBitmapImage.new('file'=>[$demo_dir,'..', 'images','flagdown.xbm'].join(File::Separator), 'maskfile'=>\ - [$demo_dir,'images','flagdown.xbm'].join(File::Separator)) + [$demo_dir,'..', + 'images','flagdown.xbm'].join(File::Separator)) -# 変数生成 +# create variable letters = TkVariable.new # frame TkFrame.new($icon_demo, 'borderwidth'=>10){|w| TkFrame.new(w) {|f| TkRadioButton.new(f){ - bitmap '@' + [$demo_dir,'images','letters.xbm'].join(File::Separator) + bitmap '@' + [$demo_dir,'..', + 'images','letters.xbm'].join(File::Separator) variable letters value 'full' }.pack('side'=>'top', 'expand'=>'yes') TkRadioButton.new(f){ - bitmap '@' + [$demo_dir,'images','noletter.xbm'].join(File::Separator) + bitmap '@' + [$demo_dir,'..', + 'images','noletter.xbm'].join(File::Separator) variable letters value 'empty' }.pack('side'=>'top', 'expand'=>'yes') @@ -86,7 +89,8 @@ TkFrame.new($icon_demo, 'borderwidth'=>10){|w| }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') TkCheckButton.new(w) { - bitmap '@' + [$demo_dir,'images','letters.xbm'].join(File::Separator) + bitmap '@' + [$demo_dir,'..', + 'images','letters.xbm'].join(File::Separator) indicatoron 0 selectcolor 'SeaGreen1' }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') diff --git a/ext/tk/sample/demos-en/image1.rb b/ext/tk/sample/demos-en/image1.rb index 8d39b20049..05c9705c9c 100644 --- a/ext/tk/sample/demos-en/image1.rb +++ b/ext/tk/sample/demos-en/image1.rb @@ -47,10 +47,10 @@ TkFrame.new($image1_demo) {|frame| # image image1a = \ -TkPhotoImage.new('file'=>[$demo_dir, +TkPhotoImage.new('file'=>[$demo_dir,'..', 'images','earth.gif'].join(File::Separator)) image1b = \ -TkPhotoImage.new('file'=>[$demo_dir, +TkPhotoImage.new('file'=>[$demo_dir,'..', 'images','earthris.gif'].join(File::Separator)) # label diff --git a/ext/tk/sample/demos-en/image2.rb b/ext/tk/sample/demos-en/image2.rb index 9924195675..1aff7173be 100644 --- a/ext/tk/sample/demos-en/image2.rb +++ b/ext/tk/sample/demos-en/image2.rb @@ -46,8 +46,8 @@ TkFrame.new($image2_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') -# 変数生成 -$dirName = TkVariable.new([$demo_dir,'images'].join(File::Separator)) +# create variable +$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator)) # image $image2a = TkPhotoImage.new diff --git a/ext/tk/sample/demos-en/image3.rb b/ext/tk/sample/demos-en/image3.rb index d997ef7772..d7d823ccf2 100644 --- a/ext/tk/sample/demos-en/image3.rb +++ b/ext/tk/sample/demos-en/image3.rb @@ -75,7 +75,7 @@ TkFrame.new($image3_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # variable -$dirName = TkVariable.new([$demo_dir,'images'].join(File::Separator)) +$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator)) # image begin diff --git a/ext/tk/sample/demos-en/images/earthris.gif b/ext/tk/sample/demos-en/images/earthris.gif deleted file mode 100644 index 48f08c4421..0000000000 Binary files a/ext/tk/sample/demos-en/images/earthris.gif and /dev/null differ diff --git a/ext/tk/sample/demos-en/images/tcllogo.gif b/ext/tk/sample/demos-en/images/tcllogo.gif deleted file mode 100644 index 3fc7720b17..0000000000 Binary files a/ext/tk/sample/demos-en/images/tcllogo.gif and /dev/null differ diff --git a/ext/tk/sample/demos-en/items.rb b/ext/tk/sample/demos-en/items.rb index 8447430694..974d7caef9 100644 --- a/ext/tk/sample/demos-en/items.rb +++ b/ext/tk/sample/demos-en/items.rb @@ -123,7 +123,7 @@ TkcLine.new(cvs, '5c','6c','9c','6c','9c','1c','8c','1c','8c','4.8c','8.8c', '8.6c','1.4c','8.4c','1.4c','8.4c','4.4c', 'width'=>3, 'fill'=>red, 'tags'=>$tag_item ) TkcLine.new(cvs, '1c','5c','7c','5c','7c','7c','9c','7c', 'width'=>'.5c', - 'stipple'=>'@'+[$demo_dir, + 'stipple'=>'@'+[$demo_dir,'..', 'images','gray25.xbm'].join(File::Separator), 'arrow'=>'both', 'arrowshape'=>'15 15 7', 'tags'=>$tag_item ) TkcLine.new(cvs, '1c','7c','1.75c','5.8c','2.5c','7c','3.25c','5.8c','4c','7c', @@ -139,7 +139,7 @@ TkcLine.new(cvs, '15.5c','1c','19.5c','1.5c','15.5c','4.5c','19.5c','4c', TkcLine.new(cvs, '12c','6c','13.5c','4.5c','16.5c','7.5c','18c','6c', '16.5c','4.5c','13.5c','7.5c','12c','6c', 'smooth'=>'on', 'width'=>'3m', 'capstyle'=>'round', - 'stipple'=>'@'+[$demo_dir, + 'stipple'=>'@'+[$demo_dir, '..', 'images', 'gray25.xbm'].join(File::Separator), 'fill'=>red, 'tags'=>$tag_item ) @@ -154,7 +154,7 @@ TkcPolygon.new(cvs, '25c','4c','25c','4c','25c','1c','26c','1c','27c','4c', TkcPolygon.new(cvs, '22c','4.5c','25c','4.5c','25c','6.75c','28c','6.75c', '28c','5.25c','24c','5.25c','24c','6.0c','26c','6c','26c', '7.5c','22c','7.5c', - 'stipple'=>'@' + [$demo_dir, + 'stipple'=>'@' + [$demo_dir, '..', 'images', 'gray25.xbm'].join(File::Separator), 'outline'=>'black', 'tags'=>$tag_item ) @@ -164,7 +164,7 @@ TkcRectangle.new(cvs, '1c','9.5c','4c','12.5c', TkcRectangle.new(cvs, '0.5c','13.5c','4.5c','15.5c', 'fill'=>green, 'tags'=>$tag_item ) TkcRectangle.new(cvs, '6c','10c','9c','15c', 'outline'=>'', - 'stipple'=>'@'+[$demo_dir, + 'stipple'=>'@'+[$demo_dir,'..', 'images','gray25.xbm'].join(File::Separator), 'fill'=>blue, 'tags'=>$tag_item ) @@ -174,7 +174,7 @@ TkcOval.new(cvs, '11c','9.5c','14c','12.5c', TkcOval.new(cvs, '10.5c','13.5c','14.5c','15.5c', 'fill'=>green, 'tags'=>$tag_item ) TkcOval.new(cvs, '16c','10c','19c','15c', 'outline'=>'', - 'stipple'=>'@'+[$demo_dir, + 'stipple'=>'@'+[$demo_dir,'..', 'images','gray25.xbm'].join(File::Separator), 'fill'=>blue, 'tags'=>$tag_item ) @@ -188,7 +188,7 @@ TkcText.new(cvs, '25.5c', '11c', 'anchor'=>'w', 'font'=>font1, 'fill'=>blue, TkcRectangle.new(cvs, '24.9c','13.9c','25.1c','14.1c') if $tk_version =~ /^4\.[01]/ TkcText.new(cvs, '25c', '14c', 'anchor'=>'c', 'font'=>font2, 'fill'=>red, - 'stipple'=>'@' + [$demo_dir, + 'stipple'=>'@' + [$demo_dir, '..', 'images', 'grey.5'].join(File::Separator), 'text'=>'Stippled characters', 'tags'=>$tag_item ) else @@ -206,7 +206,7 @@ TkcArc.new(cvs, '0.5c','17c','7c','20c', 'fill'=>green, 'outline'=>'black', # 'tags'=>$tag_item) TkcArc.new(cvs, '6.5c','17c','9.5c','20c', 'width'=>'4m', 'style'=>'arc', 'outline'=>blue, 'start'=>135, 'extent'=>270, - 'outlinestipple'=>'@'+[$demo_dir, + 'outlinestipple'=>'@'+[$demo_dir, '..', 'images','gray25.xbm'].join(File::Separator), 'tags'=>$tag_item) TkcArc.new(cvs, '0.5c','20c','9.5c','24c', 'width'=>'4m', 'style'=>'pieslice', @@ -221,14 +221,14 @@ TkcText.new(cvs, '15c', '16.2c', 'text'=>'Bitmaps', 'anchor'=>'n') # 'bitmap'=>'@' + ['images', 'face'].join(File::Separator), # 'tags'=>$tag_item) TkcBitmap.new(cvs, '13c','20c', - 'bitmap'=>'@' + [$demo_dir, + 'bitmap'=>'@' + [$demo_dir, '..', 'images', 'face.xbm'].join(File::Separator), 'tags'=>$tag_item) #TkcBitmap.new(cvs, '17c','18.5c', # 'bitmap'=>'@' + ['images', 'noletters'].join(File::Separator), # 'tags'=>$tag_item) TkcBitmap.new(cvs, '17c','18.5c', - 'bitmap'=>'@' + [$demo_dir, + 'bitmap'=>'@' + [$demo_dir, '..', 'images', 'noletter.xbm'].join(File::Separator), 'tags'=>$tag_item) #TkcBitmap.new(cvs, '17c','21.5c', @@ -236,7 +236,7 @@ TkcBitmap.new(cvs, '17c','18.5c', # 'tags'=>$tag_item) # TkcBitmap.new(cvs, '17c','21.5c') { - bitmap '@' + [$demo_dir, 'images', 'letters.xbm'].join(File::Separator) + bitmap '@' + [$demo_dir, '..', 'images', 'letters.xbm'].join(File::Separator) tags $tag_item } #TkcBitmap.new(cvs, '17c','21.5c') { diff --git a/ext/tk/sample/demos-en/label.rb b/ext/tk/sample/demos-en/label.rb index ef1bfa6f8a..96f76d35f1 100644 --- a/ext/tk/sample/demos-en/label.rb +++ b/ext/tk/sample/demos-en/label.rb @@ -60,7 +60,7 @@ f_right = TkFrame.new($label_demo) ].each{|w| w.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'anchor'=>'w')} TkLabel.new(f_right) { - bitmap('@' + [$demo_dir,'images','face.xbm'].join(File::Separator)) + bitmap('@' + [$demo_dir,'..','images','face.xbm'].join(File::Separator)) borderwidth 2 relief 'sunken' }.pack('side'=>'top') diff --git a/ext/tk/sample/demos-en/menu.rb b/ext/tk/sample/demos-en/menu.rb index 7ea3fd2ebb..c29f6e90da 100644 --- a/ext/tk/sample/demos-en/menu.rb +++ b/ext/tk/sample/demos-en/menu.rb @@ -15,7 +15,7 @@ $menu_demo = TkToplevel.new {|w| positionWindow(w) } -# menu frame 生成 +# menu frame $menu_frame = TkFrame.new($menu_demo, 'relief'=>'raised', 'bd'=>2) $menu_frame.pack('side'=>'top', 'fill'=>'x') @@ -149,7 +149,8 @@ TkMenubutton.new($menu_frame, 'text'=>'Icons', 'underline'=>0) {|m| TkMenu.new(m, 'tearoff'=>false) {|icon_menu| m.configure('menu'=>icon_menu) add('command', - 'bitmap'=>'@'+[$demo_dir,'images','pattern.xbm'].join(File::Separator), + 'bitmap'=>'@'+[$demo_dir,'..', + 'images','pattern.xbm'].join(File::Separator), 'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', 'text'=>'The menu entry you invoked displays a bitmap rather than a text string. Other than this, it is just like any other menu entry.', 'bitmap'=>'', 'default'=>0, diff --git a/ext/tk/sample/demos-en/menu84.rb b/ext/tk/sample/demos-en/menu84.rb index 82e29f6475..8f7be97707 100644 --- a/ext/tk/sample/demos-en/menu84.rb +++ b/ext/tk/sample/demos-en/menu84.rb @@ -157,7 +157,8 @@ TkMenu.new($menu84_frame, 'tearoff'=>false) {|m| TkMenu.new($menu84_frame, 'tearoff'=>false) {|m| $menu84_frame.add('cascade', 'label'=>'Icons', 'menu'=>m, 'underline'=>0) add('command', 'hidemargin'=>1, - 'bitmap'=>'@'+[$demo_dir,'images','pattern.xbm'].join(File::Separator), + 'bitmap'=>'@'+[$demo_dir,'..', + 'images','pattern.xbm'].join(File::Separator), 'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', 'text'=>'The menu entry you invoked displays a bitmap rather than a text string. Other than this, it is just like any other menu entry.', 'bitmap'=>'', 'default'=>0, diff --git a/ext/tk/sample/demos-en/menubu.rb b/ext/tk/sample/demos-en/menubu.rb index 42a5931dd1..cc1ccafa76 100644 --- a/ext/tk/sample/demos-en/menubu.rb +++ b/ext/tk/sample/demos-en/menubu.rb @@ -58,7 +58,7 @@ TkFrame.new($menubu_demo) {|frame| TkButton.new(frame) { text 'Show Code' - command proc{showCode 'menu'} + command proc{showCode 'menubu'} }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') diff --git a/ext/tk/sample/demos-en/radio2.rb b/ext/tk/sample/demos-en/radio2.rb index aefd81bdca..090e75c2cb 100644 --- a/ext/tk/sample/demos-en/radio2.rb +++ b/ext/tk/sample/demos-en/radio2.rb @@ -1,4 +1,4 @@ -# radio.rb +# radio2.rb # # This demonstration script creates a toplevel window containing # several radiobutton widgets. @@ -14,8 +14,8 @@ end # demo toplevel widget $radio2_demo = TkToplevel.new {|w| - title("Radiobutton Demonstration") - iconname("radio") + title("Radiobutton Demonstration 2") + iconname("radio2") positionWindow(w) } @@ -47,7 +47,7 @@ TkFrame.new($radio2_demo) {|frame| TkButton.new(frame) { text 'Show Code' - command proc{showCode 'radio'} + command proc{showCode 'radio2'} }.pack('side'=>'left', 'expand'=>'yes') TkButton.new(frame) { diff --git a/ext/tk/sample/demos-en/radio3.rb b/ext/tk/sample/demos-en/radio3.rb new file mode 100644 index 0000000000..ca0453416c --- /dev/null +++ b/ext/tk/sample/demos-en/radio3.rb @@ -0,0 +1,114 @@ +# radio3.rb +# +# This demonstration script creates a toplevel window containing +# several radiobutton widgets. +# +# radiobutton widget demo (called by 'widget') +# + +# toplevel widget +if defined?($radio3_demo) && $radio3_demo + $radio3_demo.destroy + $radio3_demo = nil +end + +# demo toplevel widget +$radio3_demo = TkToplevel.new {|w| + title("Radiobutton Demonstration 3") + iconname("radio3") + positionWindow(w) +} + +# label +msg = TkLabel.new($radio3_demo) { + font $font + wraplength '5i' + justify 'left' + text "Three groups of radiobuttons are displayed below. If you click on a button then the button will become selected exclusively among all the buttons in its group. A Tcl variable is associated with each group to indicate which of the group's buttons is selected. When the 'Tristate' button is pressed, the radio buttons will display the tri-state mode. Selecting any radio button will return the buttons to their respective on/off state. Click the \"See Variables\" button to see the current values of the variables." +} +msg.grid(:row=>0, :column=>0, :columnspan=>3, :sticky=>'nsew') + +# variable +size = TkVariable.new +color = TkVariable.new +align = TkVariable.new + +# frame +TkFrame.new($radio3_demo) {|frame| + TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), + :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + TkButton.new(frame, :text=>'See Variables', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars($radio3_demo, ['size', size], + ['color', color], ['compound', align]) + }), + TkButton.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'radio3'}), + TkButton.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $radio3_demo + $radio3_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) + TkGrid(frame, :row=>3, :column=>0, :columnspan=>3, :sticky=>'nsew') +} + +# frame +f_left = TkLabelFrame.new($radio3_demo, 'text'=>'Point Size', + 'pady'=>2, 'padx'=>2) +f_mid = TkLabelFrame.new($radio3_demo, 'text'=>'Color', + 'pady'=>2, 'padx'=>2) +f_right = TkLabelFrame.new($radio3_demo, 'text'=>'Alignment', + 'pady'=>2, 'padx'=>2) +f_left .grid('column'=>0, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) +f_mid .grid('column'=>1, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) +f_right.grid('column'=>2, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c') + +TkButton.new($radio3_demo, 'text'=>'Tristate', + 'command'=>proc{size.value = 'multi'; color.value = 'multi'}){ + grid('column'=>2, 'row'=>2, 'pady'=>'.5c', 'padx'=>'.5c') +} + +# radiobutton +[10, 12, 14, 18, 24].each {|sz| + TkRadioButton.new(f_left) { + text "Point Size #{sz}" + variable size + relief 'flat' + value sz + tristatevalue 'multi' + }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w', 'fill'=>'x') +} + +['Red', 'Green', 'Blue', 'Yellow', 'Orange', 'Purple'].each {|col| + TkRadioButton.new(f_mid) { + text col + variable color + relief 'flat' + value col.downcase + anchor 'w' + tristatevalue 'multi' + command proc{f_mid.fg(color.value)} + }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x') +} + +label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', + 'compound'=>'left') +label.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top') +label.height(TkWinfo.reqheight(label)) +a_btn = ['Top', 'Left', 'Right', 'Bottom'].collect{|a| + TkRadioButton.new(f_right, 'text'=>a, 'variable'=>align, 'relief'=>'flat', + 'value'=>a.downcase, 'indicatoron'=>0, 'width'=>7, + 'command'=>proc{label.compound(align.value)}) +} + +Tk.grid('x', a_btn[0]) +Tk.grid(a_btn[1], label, a_btn[2]) +Tk.grid('x', a_btn[3]) diff --git a/ext/tk/sample/demos-en/ruler.rb b/ext/tk/sample/demos-en/ruler.rb index f5e7add516..03a00b75b6 100644 --- a/ext/tk/sample/demos-en/ruler.rb +++ b/ext/tk/sample/demos-en/ruler.rb @@ -76,11 +76,13 @@ $demo_rulerInfo.normalStyle = {'fill'=>'black'} if TkWinfo.depth($ruler_canvas) > 1 $demo_rulerInfo.activeStyle = {'fill'=>'red', 'stipple'=>''} $demo_rulerInfo.deleteStyle = {'fill'=>'red', - 'stipple'=>'@'+[$demo_dir, 'images', 'gray25.xbm'].join(File::Separator)} + 'stipple'=>'@'+[$demo_dir, '..', + 'images', 'gray25.xbm'].join(File::Separator)} else $demo_rulerInfo.activeStyle = {'fill'=>'black', 'stipple'=>''} $demo_rulerInfo.deleteStyle = {'fill'=>'black', - 'stipple'=>'@'+[$demo_dir, 'images', 'gray25.xbm'].join(File::Separator)} + 'stipple'=>'@'+[$demo_dir, '..', + 'images', 'gray25.xbm'].join(File::Separator)} end TkcLine.new($ruler_canvas, diff --git a/ext/tk/sample/demos-en/search.rb b/ext/tk/sample/demos-en/search.rb index 2b27cdbb42..59a8117bb7 100644 --- a/ext/tk/sample/demos-en/search.rb +++ b/ext/tk/sample/demos-en/search.rb @@ -133,7 +133,7 @@ TkFrame.new($search_demo) {|f| } }.pack('side'=>'top', 'fill'=>'x') -$search_text = TkText.new($search_demo, 'setgrid'=>true) {|t| +$search_text = TkText.new($search_demo, 'setgrid'=>true, 'wrap'=>'word') {|t| $search_Tag = TkTextTag.new(t) TkScrollbar.new($search_demo, 'command'=>proc{|*args| t.yview(*args)}) {|sc| t.yscrollcommand(proc{|first,last| sc.set first,last}) @@ -146,45 +146,33 @@ $search_text = TkText.new($search_demo, 'setgrid'=>true) {|t| if TkWinfo.depth($search_demo) > 1 textToggle(proc{ - begin - $search_Tag.configure('background'=>'#ce5555', - 'foreground'=>'white') - rescue - end + $search_Tag.configure('background'=>'#ce5555', + 'foreground'=>'white') }, 800, proc{ - begin - $search_Tag.configure('background'=>'', 'foreground'=>'') - rescue - end + $search_Tag.configure('background'=>'', 'foreground'=>'') }, 200 ) else textToggle(proc{ - begin - $search_Tag.configure('background'=>'black', - 'foreground'=>'white') - rescue - end + $search_Tag.configure('background'=>'black', + 'foreground'=>'white') }, 800, proc{ - begin - $search_Tag.configure('background'=>'', 'foreground'=>'') - rescue - end + $search_Tag.configure('background'=>'', 'foreground'=>'') }, 200 ) end -$search_text.insert('1.0', '\ -This window demonstrates how to use the tagging facilities in text -widgets to implement a searching mechanism. First, type a file name -in the top entry, then type or click on "Load File". Then -type a string in the lower entry and type or click on -"Load File". This will cause all of the instances of the string to -be tagged with the tag "search", and it will arrange for the tag\'s -display attributes to change to make all of the strings blink.') +$search_text.insert('1.0', "\ +This window demonstrates how to use the tagging facilities in text \ +widgets to implement a searching mechanism. First, type a file name \ +in the top entry, then type or click on \"Load File\". Then \ +type a string in the lower entry and type or click on \ +\"Load File\". This will cause all of the instances of the string to \ +be tagged with the tag \"search\", and it will arrange for the tag\'s \ +display attributes to change to make all of the strings blink.") $search_text.set_insert '0.0' $search_fileName.value = '' diff --git a/ext/tk/sample/demos-en/style.rb b/ext/tk/sample/demos-en/style.rb index 8bf9c09662..def83d1a2f 100644 --- a/ext/tk/sample/demos-en/style.rb +++ b/ext/tk/sample/demos-en/style.rb @@ -94,7 +94,7 @@ TkText.new($style_demo){|t| 'relief'=>'sunken', 'borderwidth'=>1) end - # テキストタグ設定 (その他) + # if $tk_version =~ /^4\.[01]/ style_tag_bgstipple = TkTextTag.new(t, 'background'=>'black', 'borderwidth'=>0, diff --git a/ext/tk/sample/demos-en/tcolor b/ext/tk/sample/demos-en/tcolor index 6d023f0f8b..5b29797906 100644 --- a/ext/tk/sample/demos-en/tcolor +++ b/ext/tk/sample/demos-en/tcolor @@ -1,30 +1,28 @@ #!/usr/bin/env ruby # # tcolor -- -# このスクリプトはRGB,HSB,CYM形式をサポートする -# 簡易カラーエディタです。 +# simple color editor which supports RGB, HSB and CYM color space # # Copyright (C) 1998 Takaaki Tateishi(ttate@jaist.ac.jp) # last update: Thu Jun 18 06:32:35 JST 1998 # -# まずはtk.rbを読み込む。 - require "tk" -# Tkによって変更される変数はTkVariableのインスタンスを使う。 +# use TkVariable instance for the variable which is changed by Tk interpreter $colorSpace = TkVariable.new(:rgb) +$master = nil $red = 65535 $green = 0 $blue = 0 $color = "#ffff00000000" $updating = TkVariable.new(0) $autoUpdate = TkVariable.new(1) -$name = TkVariable.new("") -# $command = TkVariable.new("print(%%,\"\n\")") -$command = TkVariable.new("") +$name = TkVariable.new($color) +$command = TkVariable.new("print(%%,\"\n\")") +# $command = TkVariable.new("") $label1 = TkVariable.new("label1") $label2 = TkVariable.new("label2") $label3 = TkVariable.new("label3") @@ -36,7 +34,7 @@ if (TkVarAccess.new('tcl_platform')['platform'] == 'unix') end -# 各イベント用のメソッド +# methods for events def rgbToHsv(red,green,blue) @@ -134,6 +132,8 @@ def tc_scaleChanged return end + $master = :scale if $master == nil + scale1 = $root.middle.middle.scale1 scale2 = $root.middle.middle.scale2 scale3 = $root.middle.middle.scale3 @@ -158,11 +158,13 @@ def tc_scaleChanged raise(Exception,"unknown colorSpace") end $color = format("#%04x%04x%04x",$red.to_i,$green.to_i,$blue.to_i) + $name.value = $color if $master == :scale $root.middle.right.set_color($color) if( $autoUpdate.to_i == 1 ) doUpdate end - Tk.update(TRUE) + Tk.update(true) + $master = nil if $master == :scale end @@ -196,6 +198,8 @@ end def tc_loadNamedColor(name) + $name.value = name + $master = :name if $master == nil if name[0,1] != "#" list = TkWinfo.rgb($root.middle.right.swatch,name) $red = list[0] @@ -222,9 +226,9 @@ def tc_loadNamedColor(name) if strlist.length != 3 raise(eException,"syntax error in color name \"#{name}\"") end - $red = strlist[0].to_i - $green = strlist[1].to_i - $blue = strlist[2].to_i + $red = strlist[0].hex + $green = strlist[1].hex + $blue = strlist[2].hex } $red = $red << shift $green = $green << shift @@ -237,6 +241,8 @@ def tc_loadNamedColor(name) if $autoUpdate.to_i == 1 doUpdate end + Tk.update(true) + $master = nil if $master == :name end @@ -259,10 +265,7 @@ def changeColorSpace(space) end - - - -# tcolor用のメニュー +# menu class TkColorMenuFrame"raised", "borderwidth"=>"2") - # Fileメニューボタンの生成 + # File menubutton @file = TkMenubutton.new(self){|button| - # Fileメニューの作成 + # File menu @file_menu = TkMenu.new(button){ add "radio", "label" => "RGB color space", @@ -311,7 +314,7 @@ class TkColorMenuFrame proc{exit} } - # FileメニューとFileボタンを関連付ける + # assign File menu to File button menu @file_menu text "File" @@ -323,7 +326,7 @@ class TkColorMenuFrame2, :relief=>:sunken, :bd=>2), + :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + TkButton.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'twind2'}), + TkButton.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $twind2_demo + $twind2_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) +} +$twind2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# frame +$twind2_text = nil +TkFrame.new($twind2_demo, 'highlightthickness'=>2, 'borderwidth'=>2, + 'relief'=>'sunken') {|f| + $twind2_text = TkText.new(f, 'setgrid'=>true, 'font'=>$font, + # 'width'=>'70', 'height'=>35, 'wrap'=>'word', + 'width'=>'70', 'height'=>35, 'wrap'=>'char', + 'highlightthickness'=>0, 'borderwidth'=>0 ){|t| + TkScrollbar.new(f) {|s| + command proc{|*args| t.yview(*args)} + t.yscrollcommand proc{|first,last| s.set first,last} + }.pack('side'=>'right', 'fill'=>'y') + }.pack('expand'=>'yes', 'fill'=>'both') +}.pack('expand'=>'yes', 'fill'=>'both') + +# text tags +$tag2_center = TkTextTag.new($twind2_text, + 'justify' =>'center', + 'spacing1'=>'5m', + 'spacing3'=>'5m' ) +$tag2_buttons = TkTextTag.new($twind2_text, + 'lmargin1'=>'1c', + 'lmargin2'=>'1c', + 'rmargin' =>'1c', + 'spacing1'=>'3m', + 'spacing2'=>0, + 'spacing3'=>0 ) + +# insert text +$twind2_text.insert('end', + 'A text widget can contain many different kinds of items, ') +$twind2_text.insert('end', + "both active and passive. It can lay these out in various ") +$twind2_text.insert('end', + "ways, with wrapping, tabs, centering, etc. In addition, ") +$twind2_text.insert('end', + "when the contents are too big for the window, smooth ") +$twind2_text.insert('end', "scrolling in all directions is provided.\n\n") + +$twind2_text.insert('end', "A text widget can contain other widgets embedded ") +$twind2_text.insert('end', "it. These are called \"embedded windows\", ") +$twind2_text.insert('end', "and they can consist of arbitrary widgets. ") +$twind2_text.insert('end', "For example, here are two embedded button ") +$twind2_text.insert('end', "widgets. You can click on the first button to ") +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text 'ON' + command proc{textWindOn2 $twind2_text,$twind2_buttons} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', " horizontal scrolling, which also turns off ") +$twind2_text.insert('end', "word wrapping. Or, you can click on the second ") +$twind2_text.insert('end', "button to\n") +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text 'OFF' + command proc{textWindOff2 $twind2_text} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', + " horizontal scrolling and turn back on word wrapping.\n\n") + +$twind2_text.insert('end', "Or, here is another example. If you ") +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text 'Click Here' + command proc{textWindPlot2 $twind2_text} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', + " a canvas displaying an x-y plot will appear right here.") +$mark2_plot = TkTextMark.new($twind2_text, 'insert') +$mark2_plot.gravity='left' +$twind2_text.insert('end', + " You can drag the data points around with the mouse, ") +$twind2_text.insert('end', "or you can click here to ") +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text 'Delete' + command proc{textWindDel2 $twind2_text} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', " the plot again.\n\n") + +$twind2_text.insert('end', + "You may also find it useful to put embedded windows in ") +$twind2_text.insert('end', + "a text without any actual text. In this case the ") +$twind2_text.insert('end', "text widget acts like a geometry manager. For ") +$twind2_text.insert('end', + "example, here is a collection of buttons laid out ") +$twind2_text.insert('end', + "neatly into rows by the text widget. These buttons ") +$twind2_text.insert('end', + "can be used to change the background color of the ") +$twind2_text.insert('end', "text widget (\"Default\" restores the color to ") +$twind2_text.insert('end', + "its default). If you click on the button labeled ") +$twind2_text.insert('end', "\"Short\", it changes to a longer string so that ") +$twind2_text.insert('end', "you can see how the text widget automatically ") +$twind2_text.insert('end', "changes the layout. Click on the button again ") +$twind2_text.insert('end', "to restore the short string.\n") + +btn_default = TkButton.new($twind2_text) {|b| + text 'Default' + command proc{embDefBg2 $twind2_text} + cursor 'top_left_arrow' +} +TkTextWindow.new($twind2_text, 'end', 'window'=>btn_default, 'padx'=>3) +embToggle = TkVariable.new('Short') +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkCheckButton.new($twind2_text) { + textvariable embToggle + indicatoron 0 + variable embToggle + onvalue 'A much longer string' + offvalue 'Short' + cursor 'top_left_arrow' + pady 5 + padx 2 + }, + 'padx'=>3, + 'pady'=>2 ) + +[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4', + 'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1', + 'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1', + 'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4' +].each{|twind_color| + TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text twind_color + cursor 'top_left_arrow' + command proc{$twind2_text.bg twind_color} + }, + 'padx'=>3, + 'pady'=>2 ) +} + +$tag2_buttons.add(btn_default, 'end') + +$text_normal2 = {} +$text_normal2['border'] = $twind2_text.cget('borderwidth') +$text_normal2['highlight'] = $twind2_text.cget('highlightthickness') +$text_normal2['pad'] = $twind2_text.cget('padx') + +$twind2_text.insert('end', "\nYou can also change the usual border width and ") +$twind2_text.insert('end', "highlightthickness and padding.\n") + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Big borders", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinBigB2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Small borders", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinSmallB2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Big highlight", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinBigH2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Small highlight", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinSmallH2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Big pad", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinBigP2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Small pad", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinSmallP2 $twind2_text + })) + +$twind2_text.insert('end', + "\n\nFinally, images fit comfortably in text widgets too:") + +TkTextImage.new($twind2_text, 'end', + 'image'=>TkBitmapImage.new(:file=>[ + $demo_dir, '..', + 'images', 'face.xbm' + ].join(File::Separator))) + +# methods +def textWinBigB2(w) + w.borderwidth 15 +end +def textWinSmallB2(w) + w.borderwidth $text_normal2['border'] +end +def textWinBigH2(w) + w.highlightthickness 15 +end +def textWinSmallH2(w) + w.highlightthickness $text_normal2['highlight'] +end +def textWinBigP2(w) + w.configure(:padx=>15, :pady=>15) +end +def textWinSmallP2(w) + w.configure(:padx=>$text_normal2['pad'], :pady=>$text_normal2['pad']) +end + +def textWindOn2 (w,f) + if defined? $twind2_scroll + begin + $twind2_scroll.destroy + rescue + end + $twind2_scroll = nil + end + + base = TkWinfo.parent( TkWinfo.parent(w) ) + $twind2_scroll = TkScrollbar.new(base) {|s| + orient 'horizontal' + command proc{|*args| w.xview(*args)} + w.xscrollcommand proc{|first,last| s.set first,last} + w.wrap 'none' + pack('after'=>f, 'side'=>'bottom', 'fill'=>'x') + } + + return nil +end + +def textWindOff2 (w) + if defined? $twind2_scroll + begin + $twind2_scroll.destroy + rescue + end + $twind2_scroll = nil + end + w.xscrollcommand '' + #w.wrap 'word' + w.wrap 'char' +end + +def textWindPlot2 (t) + if (defined? $twind2_plot) && (TkWinfo.exist?($twind2_plot)) + return + end + + $twind2_plot = TkCanvas.new(t) { + relief 'sunken' + width 450 + height 300 + cursor 'top_left_arrow' + } + + #font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*' + font = 'Helvetica 18' + + TkcLine.new($twind2_plot, 100, 250, 400, 250, 'width'=>2) + TkcLine.new($twind2_plot, 100, 250, 100, 50, 'width'=>2) + TkcText.new($twind2_plot, 225, 20, + 'text'=>"A Simple Plot", 'font'=>font, 'fill'=>'brown') + + (0..10).each {|i| + x = 100 + (i * 30) + TkcLine.new($twind2_plot, x, 250, x, 245, 'width'=>2) + TkcText.new($twind2_plot, x, 254, + 'text'=>10*i, 'font'=>font, 'anchor'=>'n') + } + (0..5).each {|i| + y = 250 - (i * 40) + TkcLine.new($twind2_plot, 100, y, 105, y, 'width'=>2) + TkcText.new($twind2_plot, 96, y, + 'text'=>"#{i*50}.0", 'font'=>font, 'anchor'=>'e') + } + + for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]] + x = 100 + (3*xx) + y = 250 - (4*yy)/5 + item = TkcOval.new($twind2_plot, x-6, y-6, x+6, y+6, + 'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2') + item.addtag 'point' + end + + $twind2_plot.itembind('point', 'Any-Enter', + proc{$twind2_plot.itemconfigure 'current', 'fill', 'red'}) + $twind2_plot.itembind('point', 'Any-Leave', + proc{$twind2_plot.itemconfigure 'current', 'fill', 'SkyBlue2'}) + $twind2_plot.itembind('point', '1', + proc{|x,y| embPlotDown2 $twind2_plot,x,y}, "%x %y") + $twind2_plot.itembind('point', 'ButtonRelease-1', + proc{$twind2_plot.dtag 'selected'}) + $twind2_plot.bind('B1-Motion', + proc{|x,y| embPlotMove2 $twind2_plot,x,y}, "%x %y") + while ($twind2_text.get($mark2_plot) =~ /[ \t\n]/) + $twind2_text.delete $mark2_plot + end + $twind2_text.insert $mark2_plot,"\n" + TkTextWindow.new($twind2_text, $mark2_plot, 'window'=>$twind2_plot) + $tag2_center.add $mark2_plot + $twind2_text.insert $mark2_plot,"\n" +end + +$embPlot2 = {'lastX'=>0, 'lastY'=>0} + +def embPlotDown2 (w, x, y) + w.dtag 'selected' + w.addtag_withtag 'selected', 'current' + w.raise 'current' + $embPlot2['lastX'] = x + $embPlot2['lastY'] = y +end + +def embPlotMove2 (w, x, y) + w.move 'selected', x - $embPlot2['lastX'], y - $embPlot2['lastY'] + $embPlot2['lastX'] = x + $embPlot2['lastY'] = y +end + +def textWindDel2 (w) + if (defined? $twind2_text) && TkWinfo.exist?($twind2_plot) + $twind2_text.delete $twind2_plot + $twind2_plot = nil + while ($twind2_text.get($mark2_plot) =~ /[ \t\n]/) + $twind2_text.delete $mark2_plot + end + $twind2_text.insert $mark2_plot," " + end +end + +def embDefBg2 (w) + w['background'] = w.configinfo('background')[3] +end diff --git a/ext/tk/sample/demos-en/widget b/ext/tk/sample/demos-en/widget index aa702883de..f529792e78 100644 --- a/ext/tk/sample/demos-en/widget +++ b/ext/tk/sample/demos-en/widget @@ -10,12 +10,7 @@ # as needed. require 'tk' - -#unless /^8\.[1-9]/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK -# require 'tkencoding' -#end - -require 'tkafter' +# require 'tkafter' ### $DEBUG=1 ########## @@ -33,12 +28,78 @@ $root = TkRoot.new{title "Ruby/Tk Widget Demonstration"} # tk $tk_version = Tk::TK_VERSION +$tk_major_ver, $tk_minor_ver = $tk_version.split('.').map{|n| n.to_i} +$tk_patchlevel = Tk::TK_PATCHLEVEL # tcl_platform $tk_platform = TkVarAccess.new('tcl_platform') # -$font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil) +case($tk_version) +when /^4.*/ + $font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil) +else + $font = TkFont.new('Helvetica -12') +end + +# images +$image = {} + +if $tk_major_ver >= 8 +$image['refresh'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><= 8 +$image['view'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><= 8 +$image['delete'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><= 8 +$image['print'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><'top', 'fill'=>'x') $root.bind('F1', proc{aboutBox}) +$root.bind('Meta-q', proc{exit}) =begin TkFrame.new($root){|frame| @@ -67,7 +129,7 @@ if $tk_version =~ /^4\.[01]/ scr = TkScrollbar.new($root, 'orient'=>'vertical') txt = TkText.new($root) { wrap 'word' - width 60 + width 70 height 30 font $font setgrid 'yes' @@ -84,7 +146,7 @@ else } txt = TkText.new($root) { wrap 'word' - width 60 + width 70 height 30 font $font setgrid 'yes' @@ -92,6 +154,7 @@ else padx 4 pady 2 takefocus 0 + bd 1 yscrollcommand proc{|first,last| scr.set first,last} } scr.command(proc{|*args| txt.yview(*args)}) @@ -123,7 +186,7 @@ tag_title = TkTextTag.new(txt, 'font'=>'-*-Helvetica-Bold-R-Normal--*-180-*-*-*- tag_demospace = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c') -if TkWinfo.depth($root) == '1' +if TkWinfo.depth($root) == 1 tag_demo = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', 'underline'=>1) $tag_visited = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', @@ -206,21 +269,25 @@ txt.insert('end', "3. Buttons.\n", tag_demo, "demo-button") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. Checkbuttons (select any of a group).\n", tag_demo, "demo-check") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "5. Radiobuttons (select one of a group).\n", tag_demo, "demo-radio") +txt.insert('end', "5. Checkbuttons (if supported).\n", tag_demo, "demo-check2") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "6. Radiobuttons (if supported 'compound' option).\n", tag_demo, "demo-radio2") +txt.insert('end', "6. Radiobuttons (select one of a group).\n", tag_demo, "demo-radio") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "7. A 15-puzzle game made out of buttons.\n", tag_demo, "demo-puzzle") +txt.insert('end', "7. Radiobuttons (if supported 'compound' option).\n", tag_demo, "demo-radio2") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "8. Iconic buttons that use bitmaps.\n", tag_demo, "demo-icon") +txt.insert('end', "8. Radiobuttons (if supported).\n", tag_demo, "demo-radio3") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "9. Two labels displaying images.\n", tag_demo, "demo-image1") +txt.insert('end', "9. A 15-puzzle game made out of buttons.\n", tag_demo, "demo-puzzle") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "10. A simple user interface for viewing images.\n", tag_demo, "demo-image2") +txt.insert('end', "10. Iconic buttons that use bitmaps.\n", tag_demo, "demo-icon") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "11. A simple user interface for viewing images. (if supported)\n", tag_demo, "demo-image3") +txt.insert('end', "11. Two labels displaying images.\n", tag_demo, "demo-image1") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "12. Labelled frames (if supported)\n", tag_demo, "demo-labelframe") +txt.insert('end', "12. A simple user interface for viewing images.\n", tag_demo, "demo-image2") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "13. A simple user interface for viewing images. (if supported)\n", tag_demo, "demo-image3") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "14. Labelled frames (if supported)\n", tag_demo, "demo-labelframe") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -260,7 +327,9 @@ txt.insert('end', "3. Hypertext (tag bindings).\n", tag_demo, "demo-bind") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. A text widget with embedded windows.\n", tag_demo, "demo-twind") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "5. A search tool built with a text widget.\n", tag_demo, "demo-search") +txt.insert('end', "5. A text widget with embedded windows. (if supported)\n", tag_demo, "demo-twind2") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "6. A search tool built with a text widget.\n", tag_demo, "demo-search") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -278,7 +347,9 @@ txt.insert('end', "5. A ruler with adjustable tab stops.\n", tag_demo, "demo-rul txt.insert('end', " \n ", tag_demospace) txt.insert('end', "6. A building floor plan.\n", tag_demo, "demo-floor") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "7. A simple scrollable canvas.\n", tag_demo, "demo-cscroll") +txt.insert('end', "7. A building floor plan. (another way to create canvas items)\n", tag_demo, "demo-floor2") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "8. A simple scrollable canvas.\n", tag_demo, "demo-cscroll") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -350,7 +421,7 @@ end # args - Any number of names of variables. $showVarsWin = {} -def showVars (parent, *args) +def showVars1(parent, *args) if $showVarsWin[parent.path] begin $showVarsWin[parent.path].destroy @@ -385,11 +456,54 @@ def showVars (parent, *args) $showVarsWin[parent.path] = w end +def showVars2(parent, *args) + if $showVarsWin[parent.path] + begin + $showVarsWin[parent.path].destroy + rescue + end + end + $showVarsWin[parent.path] = TkToplevel.new(parent) {|w| + title "Variable values" + + TkLabelFrame.new(w, :text=>"Variable values:", + :font=>{:family=>'Helvetica', :size=>14}){|f| + args.each{|vnam,vbody| + TkGrid(TkLabel.new(f, :text=>"#{vnam}: ", :anchor=>'w'), + TkLabel.new(f, :textvariable=>vbody, :anchor=>'w'), + :padx=>2, :pady=>2, :sticky=>'w') + } + + f.grid(:sticky=>'news', :padx=>4) + f.grid_columnconfig(1, :weight=>1) + f.grid_rowconfig(100, :weight=>1) + } + TkButton.new(w, :text=>"OK", :width=>8, :default=>:active, + :command=>proc{w.destroy}){|b| + w.bind('Return', proc{b.invoke}) + w.bind('Escape', proc{b.invoke}) + + b.grid(:sticky=>'e', :padx=>4, :pady=>[6, 4]) + } + w.grid_columnconfig(0, :weight=>1) + w.grid_rowconfig(0, :weight=>1) + } +end + +if $tk_major_ver < 8 + alias showVars showVars1 +elsif $tk_major_ver == 8 && $tk_minor_ver < 5 + alias showVars showVars1 +else # ver >= 8.5 + alias showVars showVars2 +end + # invoke -- # This procedure is called when the user clicks on a demo description. # It is responsible for invoking the demonstration. # # Arguments: +# txt - Name of text widget # index - The index of the character that the user clicked on. def invoke (txt, index) @@ -399,7 +513,8 @@ def invoke (txt, index) txt.cursor('watch') Tk.update # eval `cat #{tag[5..-1]}.rb` - eval `cat #{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb` +# eval `cat #{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb` + eval IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join Tk.update # txt.cursor('xterm') txt.cursor(cursor) @@ -433,13 +548,13 @@ end # a demonstration and allows it to be edited and reinvoked. # # Arguments: -# w - The name of the demonstration's window, which can be +# demo - The name of the demonstration's window, which can be # used to derive the name of the file containing its code. -def showCode (demo) +def showCode1(demo) file = "#{demo}.rb" $code_window = nil unless defined? $code_window - if $code_window == nil || TkWinfo.exist?($code_window) == '0' + if $code_window == nil || TkWinfo.exist?($code_window) == false $code_window = TkToplevel.new(nil) f = TkFrame.new($code_window) TkButton.new(f) { @@ -516,16 +631,192 @@ def showCode (demo) fid.close end +def showCode2(demo) + file = "#{demo}.rb" + $code_window = nil unless defined? $code_window + if $code_window == nil || TkWinfo.exist?($code_window) == false + $code_window = TkToplevel.new(nil) + tf = TkFrame.new($code_window) + $code_text = TkText.new(tf, :font=>'Courier 10', :height=>30, + :wrap=>'word', :bd=>1, :setgrid=>true, + :highlightthickness=>0, :pady=>2, :padx=>3) + xscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)} + yscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)} + TkGrid($code_text, yscr, :sticky=>'news') + #TkGrid(xscr) + tf.grid_rowconfigure(0, :weight=>1) + tf.grid_columnconfigure(0, :weight=>1) + + bf = TkFrame.new($code_window) + + b_dis = TkButton.new(bf, :text=>'Dismiss', :default=>:active, + :command=>proc{ + $code_window.destroy + $code_window = nil + }, + :image=>$image['delete'], :compound=>:left) + b_prn = TkButton.new(bf, :text=>'Print Code', + :command=>proc{printCode($code_text, file)}, + :image=>$image['print'], :compound=>:left) + b_run = TkButton.new(bf, :text=>'Rerun Demo', + :command=>proc{eval($code_text.get('1.0','end'))}, + :image=>$image['refresh'], :compound=>:left) + + TkGrid('x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4]) + bf.grid_columnconfigure(0, :weight=>1) + + TkGrid(tf, :sticky=>'news') + TkGrid(bf, :sticky=>'ew') + $code_window.grid_columnconfigure(0, :weight=>1) + $code_window.grid_rowconfigure(0, :weight=>1) + + $code_window.bind('Return', proc{|win| + b_dis.invoke unless win.kind_of?(TkText) + }, '%W') + $code_window.bindinfo('Return').each{|cmd, arg| + $code_window.bind_append('Escape', cmd, arg) + } + else + $code_window.deiconify + $code_window.raise + end + + $code_window.title("Demo code: #{file}") + $code_window.iconname(file) + fid = open([$demo_dir, file].join(File::Separator), 'r') + $code_text.delete('1.0', 'end') + $code_text.insert('1.0', fid.read) + TkTextMarkInsert.new($code_text,'1.0') + fid.close +end + +if $tk_major_ver < 8 + alias showCode showCode1 +elsif $tk_major_ver == 8 && $tk_minor_ver < 5 + alias showCode showCode1 +else # ver >= 8.5 + alias showCode showCode2 +end + + +# printCode -- +# Prints the source code currently displayed in the See Code dialog. +# Much thanks to Arjen Markus for this. +# +# Arguments: +# txt - Name of text widget containing code to print +# file - Name of the original file (implicitly for title) + +def printCode(txt, file) + code = txt.get('1.0', 'end - 1c') + dir = '.' + dir = ENV['HOME'] if ENV['HOME'] + dir = ENV['TMP'] if ENV['TMP'] + dir = ENV['TEMP'] if ENV['TEMP'] + + fname = [dir, 'tkdemo-' + file].join(File::Separator) + open(fname, 'w'){|fid| fid.print(code)} + begin + case Tk::TCL_PLATFORM('platform') + when 'unix' + msg = `lp -c #{fname}` + unless $?.exitstatus == 0 + Tk.messageBox(:title=>'Print spooling failure', + :message=>'Print spooling probably failed: ' + msg) + end + when 'windows' + begin + printTextWin32(fname) + rescue => e + Tk.messageBox(:title=>'Print spooling failure', + :message=>'Print spooling probably failed: ' + + e.message) + end + when 'macintosh' + Tk.messageBox(:title=>'Operation not Implemented', + :message=>'Oops, sorry: not implemented yet!') + else + Tk.messageBox(:title=>'Operation not Implemented', + :message=>'Wow! Unknown platform: ' + + Tk::TCL_PLATFORM('platform')) + end + ensure + File.delete(fname) + end +end + +# printTextWin32 -- +# Print a file under Windows +# +# Arguments: +# filename - Name of the file +# +def printTextWin32(fname) + require 'win32/registry' + begin + app = Win32::Registry::HKEY_CLASSES_ROOT['.txt'] + pcmd = nil + Win32::Registry::HKEY_CLASSES_ROOT.open("#{app}\\shell\\print"){|reg| + pcmd = reg['command'] + } + rescue + app = Tk.tk_call('auto_execok', 'notepad.exe') + pcmd = "#{app} /p %1" + end + + pcmd.gsub!('%1', fname) + puts pcmd + cmd = Tk.tk_call('auto_execok', 'start') + ' /min ' + pcmd + + msg = `#{cmd}` + unless $?.exitstatus == 0 + fail RuntimeError, msg + end +end + # aboutBox # # Pops up a message box with an "about" message # def aboutBox Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', - 'message'=>"Ruby/Tk widget demonstration Ver.1.3.2-en\n\n( based on Tk 8.1 Copyright (c) 1996-1997 Sun Microsystems, Inc. )\n\nRunning Version :: Ruby#{VERSION}/Tk#{$tk_version}") + 'message'=>"Ruby/Tk widget demonstration Ver.1.4.3-en\n\n" + + "based on demos of Tk8.1 -- 8.5 " + + "( Copyright:: " + + "(c) 1996-1997 Sun Microsystems, Inc. / " + + "(c) 1997-2000 Ajuba Solutions, Inc. / " + + "(c) 2001-2003 Donal K. Fellows )\n\n" + + "Your Ruby & Tk Version ::\n" + + "Ruby#{RUBY_VERSION}(#{RUBY_RELEASE_DATE})[#{RUBY_PLATFORM}] / Tk#{$tk_patchlevel}#{(Tk::JAPANIZED_TK)? '-jp': ''}") end -################################ +######################################### +# start demos if given at command line +no_launcher = false +if ARGV[0] == '-n' + ARGV.shift + no_launcher = true if ARGV.size > 0 +end +ARGV.each{|cmd| + if cmd =~ /(.*).rb/ + cmd = $1 + end + eval IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join +} +if no_launcher + $root.withdraw # hide root window + Thread.start{ + loop do + count = 0 + $root.winfo_children.each{|w| + count += 1 if w.kind_of?(TkToplevel) + } + $root.destroy if count == 0 + end + } +end +######################################### +# start eventloop Tk.mainloop diff --git a/ext/tk/sample/demos-jp/README.1st b/ext/tk/sample/demos-jp/README.1st new file mode 100644 index 0000000000..60b278d7b6 --- /dev/null +++ b/ext/tk/sample/demos-jp/README.1st @@ -0,0 +1,20 @@ +このディレクトリには Ruby/Tk のデモスクリプトが収められています. + +'.rb' という拡張子を持っているファイルは,ランチャ─スクリプトで +ある 'widget' から呼び出されるサブスクリプトです.それぞれ独立に +は動きません.'widget' スクリプトから呼び出してください. + +もしランチャ─スクリプト 'widget' の起動と同時にいくつかのサブス +クリプトを起動したければ,そのサブスクリプトの名前を引数として与 +えてください. +( 例: /usr/local/bin/ruby widget button.rb entry1.rb text.rb ) +サブスクリプトの拡張子 '.rb' は省略することもできます. +( 例: /usr/local/bin/ruby widget button entry1 text ) + +もしランチャ─スクリプトのウィンドウが必要ない場合には,'-n' オ +プションを与えてください. +( 例: /usr/local/bin/ruby widget -n button.rb entry1.rb text.rb ) + +他のファイル (browse1 や hello など) は単独で動かすことが可能です. + + 2004/04/14 Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) diff --git a/ext/tk/sample/demos-jp/arrow.rb b/ext/tk/sample/demos-jp/arrow.rb index 3640798db1..70fe346b65 100644 --- a/ext/tk/sample/demos-jp/arrow.rb +++ b/ext/tk/sample/demos-jp/arrow.rb @@ -104,7 +104,8 @@ TkLabel.new($arrow_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', # frame 生成 $arrow_buttons = TkFrame.new($arrow_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $arrow_demo $arrow_demo = nil @@ -146,7 +147,7 @@ if TkWinfo.depth($arrow_canvas) > 1 $demo_arrowInfo.activeStyle = {'fill'=>'red', 'outline'=>'black', 'width'=>1} else $demo_arrowInfo.bigLineStyle = {'fill'=>'black', - 'stipple'=>'@'+[$demo_dir, 'images', 'grey.25'].join(File::Separator)} + 'stipple'=>'@'+[$demo_dir,'..','images','grey.25'].join(File::Separator)} $demo_arrowInfo.boxStyle = {'fill'=>'', 'outline'=>'black', 'width'=>1} $demo_arrowInfo.activeStyle = {'fill'=>'black','outline'=>'black','width'=>1} end diff --git a/ext/tk/sample/demos-jp/bind.rb b/ext/tk/sample/demos-jp/bind.rb index 1f221a6293..eebd62fc09 100644 --- a/ext/tk/sample/demos-jp/bind.rb +++ b/ext/tk/sample/demos-jp/bind.rb @@ -18,7 +18,8 @@ $bind_demo = TkToplevel.new {|w| # frame 生成 TkFrame.new($bind_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $bind_demo $bind_demo = nil diff --git a/ext/tk/sample/demos-jp/bitmap.rb b/ext/tk/sample/demos-jp/bitmap.rb index a400862881..644b960815 100644 --- a/ext/tk/sample/demos-jp/bitmap.rb +++ b/ext/tk/sample/demos-jp/bitmap.rb @@ -46,7 +46,8 @@ TkLabel.new($bitmap_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', # frame 生成 $bitmap_buttons = TkFrame.new($bitmap_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $bitmap_demo $bitmap_demo = nil diff --git a/ext/tk/sample/demos-jp/browse2 b/ext/tk/sample/demos-jp/browse2 index 304a5f547e..edad04dbcb 100644 --- a/ext/tk/sample/demos-jp/browse2 +++ b/ext/tk/sample/demos-jp/browse2 @@ -39,11 +39,11 @@ class Browse } # Set up bindings for the browser. - base.bind('Control-c', - proc{ - base.destroy + base.bind('Destroy', proc{ Browse::BROWSE_WIN_COUNTER.value = \ - Browse::BROWSE_WIN_COUNTER.to_i - 1}) + Browse::BROWSE_WIN_COUNTER.to_i - 1 + }) + base.bind('Control-c', proc{base.destroy}) list.bind('Double-Button-1', proc{TkSelection.get.each{|f| self.browse dir, f}}) end diff --git a/ext/tk/sample/demos-jp/button.rb b/ext/tk/sample/demos-jp/button.rb index 33247261f2..20f8cae299 100644 --- a/ext/tk/sample/demos-jp/button.rb +++ b/ext/tk/sample/demos-jp/button.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 $button_buttons = TkFrame.new($button_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $button_demo $button_demo = nil diff --git a/ext/tk/sample/demos-jp/check.rb b/ext/tk/sample/demos-jp/check.rb index 50c21fac0e..88e90c71d0 100644 --- a/ext/tk/sample/demos-jp/check.rb +++ b/ext/tk/sample/demos-jp/check.rb @@ -20,7 +20,7 @@ msg = TkLabel.new($check_demo) { font $font wraplength '4i' justify 'left' - text "下には 3 つのチェックボタンが表示されています。クリックするとボタンの選択状態が変わり、Tcl 変数にそのボタンの状態を示す値を設定します。現在の変数の値を見るには「変数参照」ボタンをクリックしてください。" + text "下には 3 つのチェックボタンが表示されています。クリックするとボタンの選択状態が変わり、Tcl 変数 ( TkVariable オブジェクトでアクセスできます ) にそのボタンの状態を示す値を設定します。現在の変数の値を見るには「変数参照」ボタンをクリックしてください。" } msg.pack('side'=>'top') @@ -32,7 +32,8 @@ sober = TkVariable.new(0) # frame 生成 TkFrame.new($check_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $check_demo $check_demo = nil @@ -61,6 +62,6 @@ TkFrame.new($check_demo) {|frame| # checkbutton 生成 [ TkCheckButton.new($check_demo, 'text'=>'ワイパー OK', 'variable'=>wipers), TkCheckButton.new($check_demo, 'text'=>'ブレーキ OK', 'variable'=>brakes), - TkCheckButton.new($check_demo, 'text'=>'ドライバー素面', 'variable'=>sober) + TkCheckButton.new($check_demo, 'text'=>'運転手 素面', 'variable'=>sober) ].each{|w| w.relief('flat'); w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')} diff --git a/ext/tk/sample/demos-jp/check2.rb b/ext/tk/sample/demos-jp/check2.rb new file mode 100644 index 0000000000..63d3bf9398 --- /dev/null +++ b/ext/tk/sample/demos-jp/check2.rb @@ -0,0 +1,107 @@ +# +# checkbutton widget demo2 (called by 'widget') +# + +# toplevel widget が存在すれば削除する +if defined?($check2_demo) && $check2_demo + $check2_demo.destroy + $check2_demo = nil +end + +# demo 用の toplevel widget を生成 +$check2_demo = TkToplevel.new {|w| + title("Checkbutton Demonstration 2") + iconname("check2") + positionWindow(w) +} + +# label 生成 +msg = TkLabel.new($check2_demo) { + font $font + wraplength '4i' + justify 'left' + text "下には4つのチェックボタンが表示されています。クリックするとボタンの選択状態が変わり、Tcl変数(TkVariableオブジェクトでアクセスできます)にそのボタンの状態を示す値を設定します。最初のボタンの状態は他の3つのボタンの状態にも依存して変化します。もし3つのボタンの一部だけにチェックが付けられている場合、最初のボタンはトライステート(3状態)モードでの表示を行います。現在の変数の値を見るには「変数参照」ボタンをクリックしてください。" +} +msg.pack('side'=>'top') + +# 変数生成 +safety = TkVariable.new(0) +wipers = TkVariable.new(0) +brakes = TkVariable.new(0) +sober = TkVariable.new(0) + +# frame 生成 +TkFrame.new($check2_demo) {|frame| + TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), + :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + TkButton.new(frame, :text=>'変数参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars($check2_demo, + ['safety', safety], ['wipers', wipers], + ['brakes', brakes], ['sober', sober]) + }), + TkButton.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'check2'}), + TkButton.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $check2_demo + $check2_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) +}.pack('side'=>'bottom', 'fill'=>'x') + + +# checkbutton 生成 +TkCheckButton.new($check2_demo, :text=>'安全性検査', :variable=>safety, + :relief=>:flat, :onvalue=>'all', :offvalue=>'none', + :tristatevalue=>'partial'){ + pack('side'=>'top', 'pady'=>2, 'anchor'=>'w') +} + +[ TkCheckButton.new($check2_demo, 'text'=>'ワイパー OK', 'variable'=>wipers), + TkCheckButton.new($check2_demo, 'text'=>'ブレーキ OK', 'variable'=>brakes), + TkCheckButton.new($check2_demo, 'text'=>'運転手 素面', 'variable'=>sober) +].each{|w| + w.relief('flat') + w.pack('side'=>'top', 'padx'=>15, 'pady'=>2, 'anchor'=>'w') +} + +# tristate check +in_check = false +tristate_check = proc{|n1,n2,op| + return if in_check + + in_check = true + begin + if n1 == safety + if safety == 'none' + wipers.value = 0 + brakes.value = 0 + sober.value = 0 + elsif safety == 'all' + wipers.value = 1 + brakes.value = 1 + sober.value = 1 + end + else + if wipers == 1 && brakes == 1 && sober == 1 + safety.value = 'all' + elsif wipers == 1 || brakes == 1 || sober == 1 + safety.value = 'partial' + else + safety.value = 'none' + end + end + ensure + in_check = false + end +} + +[wipers, brakes, sober, safety].each{|v| v.trace('w', tristate_check)} diff --git a/ext/tk/sample/demos-jp/clrpick.rb b/ext/tk/sample/demos-jp/clrpick.rb index 55cfd9c7c6..284611a774 100644 --- a/ext/tk/sample/demos-jp/clrpick.rb +++ b/ext/tk/sample/demos-jp/clrpick.rb @@ -22,7 +22,8 @@ TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', # frame 生成 TkFrame.new($clrpick_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $clrpick_demo $clrpick_demo = nil diff --git a/ext/tk/sample/demos-jp/colors.rb b/ext/tk/sample/demos-jp/colors.rb index f9a5983e75..c6128f9c00 100644 --- a/ext/tk/sample/demos-jp/colors.rb +++ b/ext/tk/sample/demos-jp/colors.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($colors_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $colors_demo $colors_demo = nil diff --git a/ext/tk/sample/demos-jp/cscroll.rb b/ext/tk/sample/demos-jp/cscroll.rb index 7f5ffa2f02..d128b63a7b 100644 --- a/ext/tk/sample/demos-jp/cscroll.rb +++ b/ext/tk/sample/demos-jp/cscroll.rb @@ -24,7 +24,8 @@ TkLabel.new($cscroll_demo, 'font'=>$font, 'wraplength'=>'4i', # frame 生成 $cscroll_buttons = TkFrame.new($cscroll_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $cscroll_demo $cscroll_demo = nil diff --git a/ext/tk/sample/demos-jp/ctext.rb b/ext/tk/sample/demos-jp/ctext.rb index 6d9355e2f8..4704b41411 100644 --- a/ext/tk/sample/demos-jp/ctext.rb +++ b/ext/tk/sample/demos-jp/ctext.rb @@ -30,7 +30,8 @@ TkLabel.new($ctext_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', # frame 生成 $ctext_buttons = TkFrame.new($ctext_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $ctext_demo $ctext_demo = nil diff --git a/ext/tk/sample/demos-jp/dialog1.rb b/ext/tk/sample/demos-jp/dialog1.rb index 5b578a981d..0d6181bfc6 100644 --- a/ext/tk/sample/demos-jp/dialog1.rb +++ b/ext/tk/sample/demos-jp/dialog1.rb @@ -34,5 +34,5 @@ when 0 when 1 print "あなたは「キャンセル」を押しましたね。\n" when 2 - showCode dialog1 + showCode 'dialog1' end diff --git a/ext/tk/sample/demos-jp/dialog2.rb b/ext/tk/sample/demos-jp/dialog2.rb index 4819f18a03..36b2356cc1 100644 --- a/ext/tk/sample/demos-jp/dialog2.rb +++ b/ext/tk/sample/demos-jp/dialog2.rb @@ -37,6 +37,6 @@ when 0 when 1 print "あなたは「キャンセル」を押しましたね。\n" when 2 - showCode dialog2 + showCode 'dialog2' end diff --git a/ext/tk/sample/demos-jp/entry1.rb b/ext/tk/sample/demos-jp/entry1.rb index 273b6728df..edf3b5f71d 100644 --- a/ext/tk/sample/demos-jp/entry1.rb +++ b/ext/tk/sample/demos-jp/entry1.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($entry1_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $entry1_demo $entry1_demo = nil diff --git a/ext/tk/sample/demos-jp/entry2.rb b/ext/tk/sample/demos-jp/entry2.rb index 7efac005f0..7d5740e663 100644 --- a/ext/tk/sample/demos-jp/entry2.rb +++ b/ext/tk/sample/demos-jp/entry2.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($entry2_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $entry2_demo $entry2_demo = nil diff --git a/ext/tk/sample/demos-jp/entry3.rb b/ext/tk/sample/demos-jp/entry3.rb index 9bf3f62097..f0e9bc868b 100644 --- a/ext/tk/sample/demos-jp/entry3.rb +++ b/ext/tk/sample/demos-jp/entry3.rb @@ -41,7 +41,7 @@ EOL TkFrame.new($entry3_demo){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') - TkButton.new(f, :text=>'了解', :width=>15, :command=>proc{ + TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $entry3_demo.destroy $entry3_demo = nil }).pack(:side=>:left, :expand=>true) @@ -161,6 +161,8 @@ def validatePhoneChange(widget, vmode, idx, char) widget.delete(idx) widget.insert(idx, $phoneNumberMap[char] || char) Tk.after_idle(proc{phoneSkipRight(widget, -1)}) + # Tk.update(true) # Don't work 'update' inter validation callback. + # It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). return true end return false diff --git a/ext/tk/sample/demos-jp/filebox.rb b/ext/tk/sample/demos-jp/filebox.rb index 1754596706..78ae50a45b 100644 --- a/ext/tk/sample/demos-jp/filebox.rb +++ b/ext/tk/sample/demos-jp/filebox.rb @@ -22,7 +22,8 @@ TkLabel.new($filebox_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', # frame 生成 TkFrame.new($filebox_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $filebox_demo $filebox_demo = nil diff --git a/ext/tk/sample/demos-jp/floor.rb b/ext/tk/sample/demos-jp/floor.rb index bb655d5b55..d9d17ee949 100644 --- a/ext/tk/sample/demos-jp/floor.rb +++ b/ext/tk/sample/demos-jp/floor.rb @@ -1595,7 +1595,8 @@ TkLabel.new($floor_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', # frame 生成 $floor_buttons = TkFrame.new($floor_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $floor_demo $floor_demo = nil diff --git a/ext/tk/sample/demos-jp/floor2.rb b/ext/tk/sample/demos-jp/floor2.rb new file mode 100644 index 0000000000..e5a8f53f2a --- /dev/null +++ b/ext/tk/sample/demos-jp/floor2.rb @@ -0,0 +1,1716 @@ +# +# floorDisplay widget demo 2 (called by 'widget') +# + +# floorDisplay2 -- +# Recreate the floorplan display in the canvas given by "w". The +# floor given by "active" is displayed on top with its office structure +# visible. +# +# Arguments: +# w - Name of the canvas window. +# active - Number of active floor (1, 2, or 3). + +def floorDisplay2(w,active) + return if $activeFloor2 == active + + w.delete('all') + $activeFloor2 = active + + # First go through the three floors, displaying the backgrounds for + # each floor. + + floor2_bg1(w,$floor2_colors['bg1'],$floor2_colors['outline1']) + floor2_bg2(w,$floor2_colors['bg2'],$floor2_colors['outline2']) + floor2_bg3(w,$floor2_colors['bg3'],$floor2_colors['outline3']) + + # Raise the background for the active floor so that it's on top. + + w.raise("floor#{active}") + + # Create a dummy item just to mark this point in the display list, + # so we can insert highlights here. + + w.create(TkcRectangle,0,100,1,101,'fill'=>'','outline'=>'','tags'=>'marker') + + # Add the walls and labels for the active floor, along with + # transparent polygons that define the rooms on the floor. + # Make sure that the room polygons are on top. + + $floorLabels2.clear + $floorItems2.clear + send("floor2_fg#{active}", w, $floor2_colors['offices']) + w.raise('room') + + # Offset the floors diagonally from each other. + + w.move('floor1', '2c', '2c') + w.move('floor2', '1c', '1c') + + # Create items for the room entry and its label. + w.create(TkcWindow, 600, 100, 'anchor'=>'w', 'window'=>$floor2_entry) + w.create(TkcText, 600, 100, 'anchor'=>'e', 'text'=>"部屋番号: ") + w['scrollregion'] = w.bbox('all') +end + +# newRoom2 -- +# This method is invoked whenever the mouse enters a room +# in the floorplan. It changes tags so that the current room is +# highlighted. +# +# Arguments: +# w - The name of the canvas window. + +def newRoom2(w) + id = w.find_withtag('current')[0] + $currentRoom2.value = $floorLabels2[id.id] if id != "" + Tk.update(true) +end + +# roomChanged2 -- +# This method is invoked whenever the currentRoom variable changes. +# It highlights the current room and unhighlights any previous room. +# +# Arguments: +# w - The canvas window displaying the floorplan. +# args - Not used. + +def roomChanged2(w,*args) + w.delete('highlight') + item = $floorItems2[$currentRoom2.value] + return if item == nil + new = TkcPolygon.new(w, *(w.coords(item))) + new.configure('fill'=>$floor2_colors['active'], 'tags'=>'highlight') + w.raise(new, 'marker') +end + +# floor2_bg1 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the background information for the first +# floor. +# +# Arguments: +# w - The canvas window. +# fill - Fill color to use for the floor's background. +# outline - Color to use for the floor's outline. + +def floor2_bg1(w,fill,outline) + w.create(TkcPolygon,347,80,349,82,351,84,353,85,363,92,375,99,386,104, + 386,129,398,129,398,162,484,162,484,129,559,129,559,133,725, + 133,725,129,802,129,802,389,644,389,644,391,559,391,559,327, + 508,327,508,311,484,311,484,278,395,278,395,288,400,288,404, + 288,409,290,413,292,418,297,421,302,422,309,421,318,417,325, + 411,330,405,332,397,333,344,333,340,334,336,336,335,338,332, + 342,331,347,332,351,334,354,336,357,341,359,340,360,335,363, + 331,365,326,366,304,366,304,355,258,355,258,387,60,387,60,391, + 0,391,0,337,3,337,3,114,8,114,8,25,30,25,30,5,93,5,98,5,104,7, + 110,10,116,16,119,20,122,28,123,32,123,68,220,68,220,34,221, + 22,223,17,227,13,231,8,236,4,242,2,246,0,260,0,283,1,300,5, + 321,14,335,22,348,25,365,29,363,39,358,48,352,56,337,70, + 344,76,347,80, 'tags'=>['floor1','bg'], 'fill'=>fill) + w.create(TkcLine,386,129,398,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,258,355,258,387, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,0,337,0,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,3,114,3,337, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,162,398,162, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,398,162,398,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,278,484,311, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,327,508,327, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,644,391,559,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,644,389,644,391, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,725,133,559,133, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,725,129,802,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,802,389,802,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,3,337,0,337, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,559,391,559,327, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,802,389,644,389, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,8,25,8,114, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,8,114,3,114, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,30,25,8,25, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,484,278,395,278, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,30,25,30,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,93,5,30,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,98,5,93,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,104,7,98,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,110,10,104,7, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,116,16,110,10, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,119,20,116,16, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,122,28,119,20, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,123,32,122,28, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,123,68,123,32, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,220,68,123,68, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,386,129,386,104, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,386,104,375,99, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,375,99,363,92, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,353,85,363,92, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,220,68,220,34, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,337,70,352,56, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,352,56,358,48, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,358,48,363,39, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,363,39,365,29, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,365,29,348,25, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,348,25,335,22, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,335,22,321,14, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,321,14,300,5, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,300,5,283,1, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,283,1,260,0, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,260,0,246,0, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,246,0,242,2, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,242,2,236,4, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,236,4,231,8, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,231,8,227,13, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,223,17,227,13, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,221,22,223,17, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,220,34,221,22, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,340,360,335,363, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,335,363,331,365, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,331,365,326,366, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,326,366,304,366, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,304,355,304,366, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,395,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,404,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,409,290,404,288, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,413,292,409,290, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,418,297,413,292, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,421,302,418,297, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,422,309,421,302, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,421,318,422,309, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,421,318,417,325, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,417,325,411,330, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,411,330,405,332, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,405,332,397,333, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,397,333,344,333, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,344,333,340,334, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,340,334,336,336, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,336,336,335,338, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,335,338,332,342, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,331,347,332,342, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,332,351,331,347, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,334,354,332,351, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,336,357,334,354, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,341,359,336,357, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,341,359,340,360, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,395,288,395,278, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,304,355,258,355, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,347,80,344,76, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,344,76,337,70, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,349,82,347,80, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,351,84,349,82, 'fill'=>outline, 'tags'=>['floor1','bg']) + w.create(TkcLine,353,85,351,84, 'fill'=>outline, 'tags'=>['floor1','bg']) +end + +# floor2_bg2 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the background information for the first +# floor. +# +# Arguments: +# w - The canvas window. +# fill - Fill color to use for the floor's background. +# outline - Color to use for the floor's outline. + +def floor2_bg2(w,fill,outline) + w.create(TkcPolygon,559,129,484,129,484,162,398,162,398,129,315,129, + 315,133,176,133,176,129,96,129,96,133,3,133,3,339,0,339,0,391, + 60,391,60,387,258,387,258,329,350,329,350,311,395,311,395,280, + 484,280,484,311,508,311,508,327,558,327,558,391,644,391,644, + 367,802,367,802,129,725,129,725,133,559,133,559,129, + 'tags'=>['floor2','bg'], 'fill'=>fill) + w.create(TkcLine,350,311,350,329, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,398,129,398,162, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,802,367,802,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,802,129,725,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,559,133,725,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,802,367,644,367, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,644,367,644,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,644,391,558,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,558,327,558,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,558,327,508,327, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,280,484,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,398,162,484,162, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,484,280,395,280, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,395,280,395,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,3,133,3,339, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,3,339,0,339, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,0,339,0,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,258,329,258,387, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,395,311,350,311, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,398,129,315,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,176,133,315,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,3,133,96,133, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,176,133,176,129, 'fill'=>outline, 'tags'=>['floor2','bg']) + w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor2','bg']) +end + +# floor2_bg3 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the background information for the first +# floor. +# +# Arguments: +# w - The canvas window. +# fill - Fill color to use for the floor's background. +# outline - Color to use for the floor's outline. + +def floor2_bg3(w,fill,outline) + w.create(TkcPolygon,159,300,107,300,107,248,159,248,159,129,96,129,96, + 133,21,133,21,331,0,331,0,391,60,391,60,370,159,370,159,300, + 'tags'=>['floor3','bg'], 'fill'=>fill) + w.create(TkcPolygon,258,370,258,329,350,329,350,311,399,311,399,129, + 315,129,315,133,176,133,176,129,159,129,159,370,258,370, + 'tags'=>['floor3','bg'], 'fill'=>fill) + w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,176,129,176,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,315,133,176,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,399,129,315,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,399,311,399,129, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,399,311,350,311, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,350,329,350,311, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,258,370,258,329, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,60,370,258,370, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,60,370,60,391, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,0,391,0,331, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,21,331,0,331, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,21,331,21,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,96,133,21,133, 'fill'=>outline, 'tags'=>['floor3','bg']) + w.create(TkcLine,107,300,159,300,159,248,107,248,107,300, + 'fill'=>outline, 'tags'=>['floor3','bg']) +end + +# floor2_fg1 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the foreground information for the first +# floor (office outlines and numbers). +# +# Arguments: +# w - The canvas window. +# color - Color to use for drawing foreground information. + +def floor2_fg1(w,color) + i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '101' + $floorItems2['101'] = i + w.create(TkcText,358,209, 'text'=>'101', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Pub Lift1' + $floorItems2['Pub Lift1'] = i + w.create(TkcText,323,223, 'text'=>'Pub Lift1', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Priv Lift1' + $floorItems2['Priv Lift1'] = i + w.create(TkcText,323,188, 'text'=>'Priv Lift1', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,42,389,42,337,1,337,1,389, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '110' + $floorItems2['110'] = i + w.create(TkcText,21.5,363, 'text'=>'110', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,59,389,59,385,90,385,90,337,44,337,44,389, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '109' + $floorItems2['109'] = i + w.create(TkcText,67,363, 'text'=>'109', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,51,300,51,253,6,253,6,300, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '111' + $floorItems2['111'] = i + w.create(TkcText,28.5,276.5, 'text'=>'111', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,98,248,98,309,79,309,79,248, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '117B' + $floorItems2['117B'] = i + w.create(TkcText,88.5,278.5, 'text'=>'117B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,51,251,51,204,6,204,6,251, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '112' + $floorItems2['112'] = i + w.create(TkcText,28.5,227.5, 'text'=>'112', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,6,156,51,156,51,203,6,203, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '113' + $floorItems2['113'] = i + w.create(TkcText,28.5,179.5, 'text'=>'113', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,85,169,79,169,79,192,85,192, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '117A' + $floorItems2['117A'] = i + w.create(TkcText,82,180.5, 'text'=>'117A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,77,302,77,168,53,168,53,302, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '117' + $floorItems2['117'] = i + w.create(TkcText,65,235, 'text'=>'117', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,51,155,51,115,6,115,6,155, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '114' + $floorItems2['114'] = i + w.create(TkcText,28.5,135, 'text'=>'114', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,95,115,53,115,53,168,95,168, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '115' + $floorItems2['115'] = i + w.create(TkcText,74,141.5, 'text'=>'115', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,87,113,87,27,10,27,10,113, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '116' + $floorItems2['116'] = i + w.create(TkcText,48.5,70, 'text'=>'116', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,89,91,128,91,128,113,89,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '118' + $floorItems2['118'] = i + w.create(TkcText,108.5,102, 'text'=>'118', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,178,128,178,132,216,132,216,91, + 163,91,163,112,149,112,149,128, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '120' + $floorItems2['120'] = i + w.create(TkcText,189.5,111.5, 'text'=>'120', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,79,193,87,193,87,169,136,169,136,192, + 156,192,156,169,175,169,175,246,79,246, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '122' + $floorItems2['122'] = i + w.create(TkcText,131,207.5, 'text'=>'122', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,138,169,154,169,154,191,138,191, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '121' + $floorItems2['121'] = i + w.create(TkcText,146,180, 'text'=>'121', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,99,300,126,300,126,309,99,309, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '106A' + $floorItems2['106A'] = i + w.create(TkcText,112.5,304.5, 'text'=>'106A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,128,299,128,309,150,309,150,248,99,248,99,299, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '105' + $floorItems2['105'] = i + w.create(TkcText,124.5,278.5, 'text'=>'105', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,174,309,174,300,152,300,152,309, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '106B' + $floorItems2['106B'] = i + w.create(TkcText,163,304.5, 'text'=>'106B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,176,299,176,309,216,309,216,248,152,248,152,299, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '104' + $floorItems2['104'] = i + w.create(TkcText,184,278.5, 'text'=>'104', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,138,385,138,337,91,337,91,385, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '108' + $floorItems2['108'] = i + w.create(TkcText,114.5,361, 'text'=>'108', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,256,337,140,337,140,385,256,385, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '107' + $floorItems2['107'] = i + w.create(TkcText,198,361, 'text'=>'107', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,300,353,300,329,260,329,260,353, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Smoking' + $floorItems2['Smoking'] = i + w.create(TkcText,280,341, 'text'=>'Smoking', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,314,135,314,170,306,170,306,246,177,246,177,135, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '123' + $floorItems2['123'] = i + w.create(TkcText,245.5,190.5, 'text'=>'123', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,217,248,301,248,301,326,257,326,257,310,217,310, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '103' + $floorItems2['103'] = i + w.create(TkcText,259,287, 'text'=>'103', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,396,188,377,188,377,169,316,169,316,131,396,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '124' + $floorItems2['124'] = i + w.create(TkcText,356,150, 'text'=>'124', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,397,226,407,226,407,189,377,189,377,246,397,246, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '125' + $floorItems2['125'] = i + w.create(TkcText,392,217.5, 'text'=>'125', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,399,187,409,187,409,207,474,207,474,164,399,164, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '126' + $floorItems2['126'] = i + w.create(TkcText,436.5,185.5, 'text'=>'126', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,409,209,409,229,399,229,399,253, + 486,253,486,239,474,239,474,209, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '127' + $floorItems2['127'] = i + w.create(TkcText,436.5,'231', 'text'=>'127', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,501,164,501,174,495,174,495,188, + 490,188,490,204,476,204,476,164, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'MShower' + $floorItems2['MShower'] = i + w.create(TkcText,488.5,'184', 'text'=>'MShower', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,497,176,513,176,513,204,492,204,492,190,497,190, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Closet' + $floorItems2['Closet'] = i + w.create(TkcText,502.5,190, 'text'=>'Closet', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,476,237,476,206,513,206,513,254,488,254,488,237, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'WShower' + $floorItems2['WShower'] = i + w.create(TkcText,494.5,230, 'text'=>'WShower', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,486,131,558,131,558,135,724,135,724,166, + 697,166,697,275,553,275,531,254,515,254, + 515,174,503,174,503,161,486,161, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '130' + $floorItems2['130'] = i + w.create(TkcText,638.5,205, 'text'=>'130', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,308,242,339,242,339,248,342,248, + 342,246,397,246,397,276,393,276, + 393,309,300,309,300,248,308,248, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '102' + $floorItems2['102'] = i + w.create(TkcText,367.5,278.5, 'text'=>'102', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,397,255,486,255,486,276,397,276, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '128' + $floorItems2['128'] = i + w.create(TkcText,441.5,265.5, 'text'=>'128', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,510,309,486,309,486,255,530,255, + 552,277,561,277,561,325,510,325, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '129' + $floorItems2['129'] = i + w.create(TkcText,535.5,293, 'text'=>'129', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,696,281,740,281,740,387,642,387, + 642,389,561,389,561,277,696,277, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '133' + $floorItems2['133'] = i + w.create(TkcText,628.5,335, 'text'=>'133', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,742,387,742,281,800,281,800,387, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '132' + $floorItems2['132'] = i + w.create(TkcText,771,334, 'text'=>'132', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,800,168,800,280,699,280,699,168, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '134' + $floorItems2['134'] = i + w.create(TkcText,749.5,224, 'text'=>'134', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,726,131,726,166,800,166,800,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '135' + $floorItems2['135'] = i + w.create(TkcText,763,148.5, 'text'=>'135', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,340,360,335,363,331,365,326,366,304,366, + 304,312,396,312,396,288,400,288,404,288, + 409,290,413,292,418,297,421,302,422,309, + 421,318,417,325,411,330,405,332,397,333, + 344,333,340,334,336,336,335,338,332,342, + 331,347,332,351,334,354,336,357,341,359, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Ramona Stair' + $floorItems2['Ramona Stair'] = i + w.create(TkcText,368,323, 'text'=>'Ramona Stair', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,30,23,30,5,93,5,98,5,104,7,110,10,116,16,119,20, + 122,28,123,32,123,68,220,68,220,87,90,87,90,23, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'University Stair' + $floorItems2['University Stair'] = i + w.create(TkcText,155,77.5, 'text'=>'University Stair', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,282,37,295,40,312,49,323,56,337,70,352,56, + 358,48,363,39,365,29,348,25,335,22,321,14, + 300,5,283,1,260,0,246,0,242,2,236,4,231,8, + 227,13,223,17,221,22,220,34,260,34, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Plaza Stair' + $floorItems2['Plaza Stair'] = i + w.create(TkcText,317.5,28.5, 'text'=>'Plaza Stair', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,220,34,260,34,282,37,295,40,312,49, + 323,56,337,70,350,83,365,94,377,100, + 386,104,386,128,220,128, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = 'Plaza Deck' + $floorItems2['Plaza Deck'] = i + w.create(TkcText,303,81, 'text'=>'Plaza Deck', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,257,336,77,336,6,336,6,301,77,301,77,310,257,310, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '106' + $floorItems2['106'] = i + w.create(TkcText,131.5,318.5, 'text'=>'106', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + i = TkcPolygon.new(w,146,110,162,110,162,91,130,91,130,115,95,115, + 95,128,114,128,114,151,157,151,157,153,112,153, + 112,130,97,130,97,168,175,168,175,131,146,131, + 'fill'=>'', 'tags'=>['floor1','room']) + $floorLabels2[i.id] = '119' + $floorItems2['119'] = i + w.create(TkcText,143.5,133, 'text'=>'119', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor1','label']) + w.create(TkcLine,155,191,155,189, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,96,129,96,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,169,176,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,176,247,176,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,376,246,376,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,307,247,307,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,147,129,176,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,202,133,176,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,352,258,387, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,0,337,0,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,3,114,3,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,237,52,273, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,189,52,225, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,140,52,177, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,395,306,395,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,531,254,398,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,475,178,475,238, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,502,162,398,162, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,398,129,398,188, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,408,208,475,208, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,278,484,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,327,508,327, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,644,391,559,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,644,389,644,391, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,514,205,475,205, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,496,189,496,187, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,149,725,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,129,802,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,802,389,802,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,739,167,802,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,0,337,9,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,58,337,21,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,43,391,43,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,105,337,75,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,91,387,91,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,154,337,117,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,139,387,139,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,227,337,166,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,337,251,337, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,328,302,328, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,302,355,302,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,395,311,302,311, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,484,278,395,278, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,395,294,395,278, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,473,278,473,275, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,473,256,473,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,533,257,531,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,553,276,551,274, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,698,276,553,276, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,559,391,559,327, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,802,389,644,389, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,741,314,741,389, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,698,280,698,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,707,280,698,280, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,802,280,731,280, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,741,280,741,302, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,698,167,727,167, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,725,137,725,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,514,254,514,175, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,496,175,514,175, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,502,175,502,162, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,475,166,475,162, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,496,176,496,175, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,491,189,496,189, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,491,205,491,189, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,487,238,475,238, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,487,240,487,238, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,487,252,487,254, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,315,133,304,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,256,133,280,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,247,270,247, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,307,247,294,247, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,214,133,232,133, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,217,247,217,266, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,217,309,217,291, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,217,309,172,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,154,309,148,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,175,300,175,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,151,300,175,300, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,151,247,151,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,237,78,265, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,286,78,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,106,309,78,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,130,309,125,309, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,99,309,99,247, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,127,299,99,299, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,127,309,127,299, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,155,191,137,191, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,137,169,137,191, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,171,78,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,78,190,78,218, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,86,192,86,169, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,86,192,78,192, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,301,3,301, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,286,52,301, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,252,3,252, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,203,3,203, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,3,156,52,156, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,8,25,8,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,63,114,3,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,75,114,97,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,108,114,129,114, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,129,114,129,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,52,114,52,128, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,132,89,88,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,88,25,88,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,88,114,88,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,218,89,144,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,147,111,147,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,162,111,147,111, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,162,109,162,111, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,162,96,162,89, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,218,89,218,94, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,218,89,218,119, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,8,25,88,25, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,258,337,258,328, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,129,96,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,302,355,258,355, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,386,104,386,129, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,377,100,386,104, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,365,94,377,100, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,350,83,365,94, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,337,70,350,83, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,337,70,323,56, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,312,49,323,56, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,295,40,312,49, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,282,37,295,40, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,260,34,282,37, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,253,34,260,34, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,386,128,386,104, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall']) + w.create(TkcLine,113,152,113,129, 'fill'=>color, 'tags'=>['floor1','wall']) +end + +# floor2_fg2 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the foreground information for the second +# floor (office outlines and numbers). +# +# Arguments: +# w - The canvas window. +# color - Color to use for drawing foreground information. + +def floor2_fg2(w,color) + i = TkcPolygon.new(w,748,188,755,188,755,205,758,205,758,222, + 800,222,800,168,748,168, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '238' + $floorItems2['238'] = i + w.create(TkcText,774,195, 'text'=>'238', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,726,188,746,188,746,166,800,166,800,131,726,131, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '237' + $floorItems2['237'] = i + w.create(TkcText,763,148.5, 'text'=>'237', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,497,187,497,204,559,204,559,324,641,324, + 643,324,643,291,641,291,641,205,696,205, + 696,291,694,291,694,314,715,314,715,291, + 715,205,755,205,755,190,724,190,724,187, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '246' + $floorItems2['246'] = i + w.create(TkcText,600,264, 'text'=>'246', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,694,279,643,279,643,314,694,314, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '247' + $floorItems2['247'] = i + w.create(TkcText,668.5,296.5, 'text'=>'247', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,232,250,308,250,308,242,339,242,339,246, + 397,246,397,255,476,255,476,250,482,250,559,250, + 559,274,482,274,482,278,396,278,396,274,232,274, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '202' + $floorItems2['202'] = i + w.create(TkcText,285.5,260, 'text'=>'202', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,53,228,53,338,176,338,233,338,233,196, + 306,196,306,180,175,180,175,169,156,169, + 156,196,176,196,176,228, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '206' + $floorItems2['206'] = i + w.create(TkcText,143,267, 'text'=>'206', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,277,6,277,6,338,51,338, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '212' + $floorItems2['212'] = i + w.create(TkcText,28.5,307.5, 'text'=>'212', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,557,276,486,276,486,309,510,309,510,325,557,325, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '245' + $floorItems2['245'] = i + w.create(TkcText,521.5,300.5, 'text'=>'245', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,560,389,599,389,599,326,560,326, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '244' + $floorItems2['244'] = i + w.create(TkcText,579.5,357.5, 'text'=>'244', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,601,389,601,326,643,326,643,389, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '243' + $floorItems2['243'] = i + w.create(TkcText,622,357.5, 'text'=>'243', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,688,316,645,316,645,365,688,365, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '242' + $floorItems2['242'] = i + w.create(TkcText,666.5,340.5, 'text'=>'242', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,802,367,759,367,759,226,802,226, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = 'Barbecue Deck' + $floorItems2['Barbecue Deck'] = i + w.create(TkcText,780.5,296.5, 'text'=>'Barbecue Deck', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,755,262,755,314,717,314,717,262, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '240' + $floorItems2['240'] = i + w.create(TkcText,736,288, 'text'=>'240', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,755,316,689,316,689,365,755,365, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '241' + $floorItems2['241'] = i + w.create(TkcText,722,340.5, 'text'=>'241', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,755,206,717,206,717,261,755,261, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '239' + $floorItems2['239'] = i + w.create(TkcText,736,233.5, 'text'=>'239', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,695,277,643,277,643,206,695,206, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '248' + $floorItems2['248'] = i + w.create(TkcText,669,241.5, 'text'=>'248', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,676,135,676,185,724,185,724,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '236' + $floorItems2['236'] = i + w.create(TkcText,700,160, 'text'=>'236', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,675,135,635,135,635,145,628,145,628,185,675,185, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '235' + $floorItems2['235'] = i + w.create(TkcText,651.5,160, 'text'=>'235', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,626,143,633,143,633,135,572,135, + 572,143,579,143,579,185,626,185, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '234' + $floorItems2['234'] = i + w.create(TkcText,606,160, 'text'=>'234', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,557,135,571,135,571,145,578,145, + 578,185,527,185,527,131,557,131, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '233' + $floorItems2['233'] = i + w.create(TkcText,552.5,158, 'text'=>'233', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,476,249,557,249,557,205,476,205, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '230' + $floorItems2['230'] = i + w.create(TkcText,516.5,227, 'text'=>'230', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,476,164,486,164,486,131,525,131,525,185,476,185, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '232' + $floorItems2['232'] = i + w.create(TkcText,500.5,158, 'text'=>'232', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,476,186,495,186,495,204,476,204, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '229' + $floorItems2['229'] = i + w.create(TkcText,485.5,195, 'text'=>'229', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,474,207,409,207,409,187,399,187,399,164,474,164, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '227' + $floorItems2['227'] = i + w.create(TkcText,436.5,185.5, 'text'=>'227', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,399,228,399,253,474,253,474,209,409,209,409,228, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '228' + $floorItems2['228'] = i + w.create(TkcText,436.5,231, 'text'=>'228', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,397,246,397,226,407,226,407,189,377,189,377,246, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '226' + $floorItems2['226'] = i + w.create(TkcText,392,217.5, 'text'=>'226', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,377,169,316,169,316,131,397,131,397,188,377,188, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '225' + $floorItems2['225'] = i + w.create(TkcText,356.5,150, 'text'=>'225', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,234,198,306,198,306,249,234,249, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '224' + $floorItems2['224'] = i + w.create(TkcText,270,223.5, 'text'=>'224', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,270,179,306,179,306,170,314,170,314,135,270,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '223' + $floorItems2['223'] = i + w.create(TkcText,292,157, 'text'=>'223', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,268,179,221,179,221,135,268,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '222' + $floorItems2['222'] = i + w.create(TkcText,244.5,157, 'text'=>'222', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,177,179,219,179,219,135,177,135, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '221' + $floorItems2['221'] = i + w.create(TkcText,198,157, 'text'=>'221', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,299,327,349,327,349,284,341,284,341,276,299,276, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '204' + $floorItems2['204'] = i + w.create(TkcText,324,301.5, 'text'=>'204', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,234,276,297,276,297,327,257,327,257,338,234,338, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '205' + $floorItems2['205'] = i + w.create(TkcText,265.5,307, 'text'=>'205', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,256,385,256,340,212,340,212,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '207' + $floorItems2['207'] = i + w.create(TkcText,234,362.5, 'text'=>'207', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,210,340,164,340,164,385,210,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '208' + $floorItems2['208'] = i + w.create(TkcText,187,362.5, 'text'=>'208', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,115,340,162,340,162,385,115,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '209' + $floorItems2['209'] = i + w.create(TkcText,138.5,362.5, 'text'=>'209', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,89,228,89,156,53,156,53,228, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '217' + $floorItems2['217'] = i + w.create(TkcText,71,192, 'text'=>'217', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,89,169,97,169,97,190,89,190, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '217A' + $floorItems2['217A'] = i + w.create(TkcText,93,179.5, 'text'=>'217A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,89,156,89,168,95,168,95,135,53,135,53,156, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '216' + $floorItems2['216'] = i + w.create(TkcText,71,145.5, 'text'=>'216', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,179,51,135,6,135,6,179, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '215' + $floorItems2['215'] = i + w.create(TkcText,28.5,157, 'text'=>'215', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,227,6,227,6,180,51,180, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '214' + $floorItems2['214'] = i + w.create(TkcText,28.5,203.5, 'text'=>'214', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,51,275,6,275,6,229,51,229, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '213' + $floorItems2['213'] = i + w.create(TkcText,28.5,252, 'text'=>'213', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,114,340,67,340,67,385,114,385, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '210' + $floorItems2['210'] = i + w.create(TkcText,90.5,362.5, 'text'=>'210', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,59,389,59,385,65,385,65,340,1,340,1,389, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '211' + $floorItems2['211'] = i + w.create(TkcText,33,364.5, 'text'=>'211', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,393,309,350,309,350,282,342,282,342,276,393,276, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '203' + $floorItems2['203'] = i + w.create(TkcText,367.5,292.5, 'text'=>'203', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,99,191,91,191,91,226,174,226,174,198, + 154,198,154,192,109,192,109,169,99,169, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '220' + $floorItems2['220'] = i + w.create(TkcText,132.5,208.5, 'text'=>'220', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = 'Priv Lift2' + $floorItems2['Priv Lift2'] = i + w.create(TkcText,323,188, 'text'=>'Priv Lift2', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = 'Pub Lift 2' + $floorItems2['Pub Lift 2'] = i + w.create(TkcText,323,223, 'text'=>'Pub Lift 2', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '218' + $floorItems2['218'] = i + w.create(TkcText,136,149.5, 'text'=>'218', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '219' + $floorItems2['219'] = i + w.create(TkcText,132.5,180, 'text'=>'219', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, + 'fill'=>'', 'tags'=>['floor2','room']) + $floorLabels2[i.id] = '201' + $floorItems2['201'] = i + w.create(TkcText,358,209, 'text'=>'201', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor2','label']) + w.create(TkcLine,641,186,678,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,350,757,367, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,634,133,634,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,634,144,627,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,572,133,572,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,572,144,579,144, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,129,398,162, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,174,197,175,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,175,197,175,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,206,757,221, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,727,189,725,189, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,747,167,802,167, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,747,167,747,189, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,755,189,739,189, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,769,224,757,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,802,224,802,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,802,129,725,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,725,189,725,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,725,186,690,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,676,133,676,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,627,144,627,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,629,186,593,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,579,144,579,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,526,129,526,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,540,186,581,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,528,186,523,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,511,186,475,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,496,190,496,186, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,496,205,496,202, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,475,205,527,205, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,205,539,205, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,205,558,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,249,475,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,662,206,642,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,695,206,675,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,695,278,642,278, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,642,291,642,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,695,291,695,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,716,208,716,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,206,716,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,221,757,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,793,224,802,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,262,716,262, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,716,220,716,264, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,716,315,716,276, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,315,703,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,325,757,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,757,367,644,367, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,689,367,689,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,647,315,644,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,659,315,691,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,600,325,600,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,627,325,644,325, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,644,391,644,315, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,615,325,575,325, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,644,391,558,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,563,325,558,325, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,391,558,314, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,327,508,327, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,275,484,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,558,302,558,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,275,484,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,475,208,408,208, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,188,398,162, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,162,484,162, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,475,162,475,254, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,254,475,254, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,484,280,395,280, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,395,311,395,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,307,197,293,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,278,197,233,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,233,197,233,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,307,179,284,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,233,249,278,249, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,269,179,269,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,220,179,220,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,155,191,110,191, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,90,190,98,190, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,98,169,98,190, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,133,52,165, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,214,52,177, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,226,52,262, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,274,52,276, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,234,275,234,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,226,339,258,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,211,387,211,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,214,339,177,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,3,133,3,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,165,339,129,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,117,339,80,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,68,339,59,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,0,339,46,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,0,339,0,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,258,329,258,387, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,395,311,350,311, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,176,133,315,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,3,133,96,133, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,66,387,66,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,115,387,115,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,163,387,163,339, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,234,275,276,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,288,275,309,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,321,275,341,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,375,275,395,275, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,376,245,376,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,245,340,224, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,293,250,307,250, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,271,179,238,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,226,179,195,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,174,169,176,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,162,169,90,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,96,169,96,129, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,175,227,90,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,90,190,90,227, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,179,3,179, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,228,3,228, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,52,276,3,276, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,110,191,110,169, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,155,189,155,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor2','wall']) + w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor2','wall']) +end + +# floor2_fg3 -- +# This method represents part of the floorplan database. When +# invoked, it instantiates the foreground information for the third +# floor (office outlines and numbers). +# +# Arguments: +# w - The canvas window. +# color - Color to use for drawing foreground information. + +def floor2_fg3(w,color) + i = TkcPolygon.new(w,89,228,89,180,70,180,70,228, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '316' + $floorItems2['316'] = i + w.create(TkcText,79.5,204, 'text'=>'316', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,115,368,162,368,162,323,115,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '309' + $floorItems2['309'] = i + w.create(TkcText,138.5,345.5, 'text'=>'309', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,164,323,164,368,211,368,211,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '308' + $floorItems2['308'] = i + w.create(TkcText,187.5,345.5, 'text'=>'308', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,256,368,212,368,212,323,256,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '307' + $floorItems2['307'] = i + w.create(TkcText,234,345.5, 'text'=>'307', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,244,276,297,276,297,327,260,327,260,321,244,321, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '305' + $floorItems2['305'] = i + w.create(TkcText,270.5,301.5, 'text'=>'305', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,251,219,251,203,244,203,244,219, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '324B' + $floorItems2['324B'] = i + w.create(TkcText,247.5,211, 'text'=>'324B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,251,249,244,249,244,232,251,232, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '324A' + $floorItems2['324A'] = i + w.create(TkcText,247.5,240.5, 'text'=>'324A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,223,135,223,179,177,179,177,135, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '320' + $floorItems2['320'] = i + w.create(TkcText,200,157, 'text'=>'320', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,114,368,114,323,67,323,67,368, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '310' + $floorItems2['310'] = i + w.create(TkcText,90.5,345.5, 'text'=>'310', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,23,277,23,321,68,321,68,277, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '312' + $floorItems2['312'] = i + w.create(TkcText,45.5,299, 'text'=>'312', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,23,229,68,229,68,275,23,275, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '313' + $floorItems2['313'] = i + w.create(TkcText,45.5,252, 'text'=>'313', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,68,227,23,227,23,180,68,180, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '314' + $floorItems2['314'] = i + w.create(TkcText,40.5,203.5, 'text'=>'314', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,95,179,95,135,23,135,23,179, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '315' + $floorItems2['315'] = i + w.create(TkcText,59,157, 'text'=>'315', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,99,226,99,204,91,204,91,226, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '316B' + $floorItems2['316B'] = i + w.create(TkcText,95,215, 'text'=>'316B', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,91,202,99,202,99,180,91,180, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '316A' + $floorItems2['316A'] = i + w.create(TkcText,95,191, 'text'=>'316A', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,97,169,109,169,109,192,154,192,154,198, + 174,198,174,226,101,226,101,179,97,179, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '319' + $floorItems2['319'] = i + w.create(TkcText,141.5,209, 'text'=>'319', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,65,368,58,368,58,389,1,389,1,333,23,333,23,323,65,323, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '311' + $floorItems2['311'] = i + w.create(TkcText,29.5,361, 'text'=>'311', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '318' + $floorItems2['318'] = i + w.create(TkcText,132.5,180, 'text'=>'318', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '317' + $floorItems2['317'] = i + w.create(TkcText,136,149.5, 'text'=>'317', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,274,194,274,221,306,221,306,194, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '323' + $floorItems2['323'] = i + w.create(TkcText,290,207.5, 'text'=>'323', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,306,222,274,222,274,249,306,249, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '325' + $floorItems2['325'] = i + w.create(TkcText,290,235.5, 'text'=>'325', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,263,179,224,179,224,135,263,135, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '321' + $floorItems2['321'] = i + w.create(TkcText,243.5,157, 'text'=>'321', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,314,169,306,169,306,192,273,192, + 264,181,264,135,314,135, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '322' + $floorItems2['322'] = i + w.create(TkcText,293.5,163.5, 'text'=>'322', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = 'Pub Lift3' + $floorItems2['Pub Lift3'] = i + w.create(TkcText,323,223, 'text'=>'Pub Lift3', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = 'Priv Lift3' + $floorItems2['Priv Lift3'] = i + w.create(TkcText,323,188, 'text'=>'Priv Lift3', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,350,284,376,284,376,276,397,276,397,309,350,309, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '303' + $floorItems2['303'] = i + w.create(TkcText,373.5,292.5, 'text'=>'303', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,272,203,272,249,252,249,252,230, + 244,230,244,221,252,221,252,203, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '324' + $floorItems2['324'] = i + w.create(TkcText,262,226, 'text'=>'324', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,299,276,299,327,349,327,349,284,341,284,341,276, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '304' + $floorItems2['304'] = i + w.create(TkcText,324,301.5, 'text'=>'304', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '301' + $floorItems2['301'] = i + w.create(TkcText,358,209, 'text'=>'301', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,397,246,377,246,377,185,397,185, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '327' + $floorItems2['327'] = i + w.create(TkcText,387,215.5, 'text'=>'327', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,316,131,316,169,377,169,377,185,397,185,397,131, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '326' + $floorItems2['326'] = i + w.create(TkcText,365.5,150, 'text'=>'326', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,308,251,242,251,242,274,342,274,342,282,375, 282, + 375,274,397,274,397,248,339,248,339,242,308,242, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '302' + $floorItems2['302'] = i + w.create(TkcText,319.5,261, 'text'=>'302', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + i = TkcPolygon.new(w,70,321,242,321,242,200,259,200,259,203,272,203, + 272,193,263,180,242,180,175,180,175,169,156,169, + 156,196,177,196,177,228,107,228,70,228,70,275,107,275, + 107,248,160,248,160,301,107,301,107,275,70,275, + 'fill'=>'', 'tags'=>['floor3','room']) + $floorLabels2[i.id] = '306' + $floorItems2['306'] = i + w.create(TkcText,200.5,284.5, 'text'=>'306', 'fill'=>color, + 'anchor'=>'c', 'tags'=>['floor3','label']) + w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,396,247,399,247, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,399,129,399,311, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,202,243,202, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,251,231,243,231, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,220,251,220, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,250,243,202, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,155,197,155,190, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,110,192,110,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,155,192,110,192, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,176,197,176,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,69,280,69,274, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,276,69,276, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,69,262,69,226, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,228,69,228, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,179,75,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,69,179,69,214, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,220,90,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,204,90,202, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,203,100,203, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,187,90,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,90,227,176,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,100,179,100,227, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,100,179,87,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,96,179,96,129, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,162,169,96,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,173,169,176,169, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,195,179,226,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,224,133,224,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,264,179,264,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,238,179,264,179, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,207,273,193, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,235,273,250, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,224,273,219, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,193,307,193, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,222,307,222, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,384,247,376,247, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,247,376,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,283,366,283, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,376,283,376,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,399,275,376,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,341,275,320,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,308,275,298,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,322,243,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,243,275,284,275, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,322,226,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,212,370,212,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,214,322,177,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,163,370,163,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,165,322,129,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,84,322,117,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,71,322,64,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,115,322,115,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,66,322,66,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,52,322,21,322, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,331,0,331, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,21,331,21,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,96,133,21,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,315,133,176,133, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,315,129,399,129, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,399,311,350,311, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,322,258,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,60,370,258,370, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,60,370,60,391, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,0,391,0,331, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,307,250,307,242, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall']) + w.create(TkcLine,258,250,243,250, 'fill'=>color, 'tags'=>['floor3','wall']) +end + +# Below is the "main program" that creates the floorplan demonstration. + +# toplevel widget が存在すれば削除する +if defined?($floor2_demo) && $floor2_demo + $floor2_demo.destroy + $floor2_demo = nil +end + +# demo 用の toplevel widget を生成 +$floor2_demo = TkToplevel.new {|w| + title("Floorplan Canvas Demonstration 2") + iconname("Floorplan2") + positionWindow(w) + geometry('+20+20') + minsize(100,100) +} + +# label 生成 +TkLabel.new($floor2_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', + 'text'=>"このウィンドウにはディジタルエクイップメント社のウェスタンリサーチラボラトリ (DECWRL) の間取りが書かれたキャンバス widget が入っています。これは 3階建てで、常にそのうちの1階分が選択、つまりその間取りが表示されるようになっています。ある階を選択するには、その上でマウスの左ボタンをクリックしてください。マウスが選択されている階の上を動くと、その下にある部屋の色が変わり、部屋番号が「部屋番号:」エントリに表示されます。また、エントリに部屋番号を書くとその部屋の色が変わります。"){ + pack('side'=>'top') +} + +# frame 生成 +$floor2_buttons = TkFrame.new($floor2_demo) {|frame| + TkButton.new(frame) { + #text '了解' + text '閉じる' + command proc{ + tmppath = $floor2_demo + $floor2_demo = nil + tmppath.destroy + } + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'コード参照' + command proc{showCode 'floor2'} + }.pack('side'=>'left', 'expand'=>'yes') +} +$floor2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# 変数設定 +$floorLabels2 = {} +$floorItems2 = {} + +# canvas 設定 +if $tk_version =~ /^4\.[01]/ + $floor2_canvas_frame = TkFrame.new($floor2_demo,'bd'=>2,'relief'=>'sunken', + 'highlightthickness'=>2) + $floor2_canvas = TkCanvas.new($floor2_canvas_frame, + 'width'=>900, 'height'=>500, 'borderwidth'=>0, + 'highlightthickness'=>0) {|c| + TkScrollbar.new($floor2_demo, 'orient'=>'horiz', + 'command'=>proc{|*args| c.xview(*args)}){|hs| + c.xscrollcommand(proc{|first,last| hs.set first,last}) + pack('side'=>'bottom', 'fill'=>'x') + } + TkScrollbar.new($floor2_demo, 'command'=>proc{|*args| c.yview(*args)}){|vs| + c.yscrollcommand(proc{|first,last| vs.set first,last}) + pack('side'=>'right', 'fill'=>'y') + } + } + $floor2_canvas_frame.pack('side'=>'top','fill'=>'both', 'expand'=>'yes') + $floor2_canvas.pack('expand'=>'yes', 'fill'=>'both') + +else + TkFrame.new($floor2_demo) {|f| + pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') + + h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal') + v = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'vertical') + + TkFrame.new(f, 'bd'=>2, 'relief'=>'sunken') {|f1| + $floor2_canvas = TkCanvas.new(f1, 'width'=>900, 'height'=>500, + 'borderwidth'=>0, + 'highlightthickness'=>0) { + xscrollcommand(proc{|first,last| h.set first,last}) + yscrollcommand(proc{|first,last| v.set first,last}) + pack('expand'=>'yes', 'fill'=>'both') + } + grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, + 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') + } + + v.grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, + 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') + h.grid('padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, + 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') + + TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0) + TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0) + + pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1) + + v.command(proc{|*args| c.yview(*args)}) + h.command(proc{|*args| c.xview(*args)}) + } +end + +# Create an entry for displaying and typing in current room. + +$currentRoom2 = TkVariable.new +$floor2_entry = TkEntry.new($floor2_canvas, 'width'=>10, 'relief'=>'sunken', + 'bd'=>2, 'textvariable'=>$currentRoom2) + +# Choose colors, then fill in the floorplan. + +$floor2_colors = {} +if TkWinfo.depth($floor2_canvas) > 1 + $floor2_colors['bg1'] = '#a9c1da' + $floor2_colors['outline1'] = '#77889a' + $floor2_colors['bg2'] = '#9ab0c6' + $floor2_colors['outline2'] = '#687786' + $floor2_colors['bg3'] = '#8ba0b3' + $floor2_colors['outline3'] = '#596673' + $floor2_colors['offices'] = 'Black' + $floor2_colors['active'] = '#c4d1df' +else + $floor2_colors['bg1'] = 'white' + $floor2_colors['outline1'] = 'black' + $floor2_colors['bg2'] = 'white' + $floor2_colors['outline2'] = 'black' + $floor2_colors['bg3'] = 'white' + $floor2_colors['outline3'] = 'black' + $floor2_colors['offices'] = 'Black' + $floor2_colors['active'] = 'black' +end + +$activeFloor2 = '' +floorDisplay2 $floor2_canvas,3 + +# Set up event bindings for canvas: + +$floor2_canvas.itembind('floor1', '1', proc{floorDisplay2 $floor2_canvas,1}) +$floor2_canvas.itembind('floor2', '1', proc{floorDisplay2 $floor2_canvas,2}) +$floor2_canvas.itembind('floor3', '1', proc{floorDisplay2 $floor2_canvas,3}) +$floor2_canvas.itembind('room', 'Enter', proc{newRoom2 $floor2_canvas}) +$floor2_canvas.itembind('room', 'Leave', proc{$currentRoom2.value = ''}) +$floor2_canvas.bind('2', proc{|x,y| $floor2_canvas.scan_mark x,y}, '%x %y') +$floor2_canvas.bind('B2-Motion', + proc{|x,y| $floor2_canvas.scan_dragto x,y}, '%x %y') +$floor2_canvas.bind('Destroy', proc{$currentRoom2.unset}) +$currentRoom2.value = '' +$currentRoom2.trace('w',proc{roomChanged2 $floor2_canvas}) diff --git a/ext/tk/sample/demos-jp/form.rb b/ext/tk/sample/demos-jp/form.rb index 35baeed46b..fe456d3943 100644 --- a/ext/tk/sample/demos-jp/form.rb +++ b/ext/tk/sample/demos-jp/form.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top', 'fill'=>'x') # frame 生成 TkFrame.new($form_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $form_demo $form_demo = nil diff --git a/ext/tk/sample/demos-jp/hscale.rb b/ext/tk/sample/demos-jp/hscale.rb index 4333239c73..37d215435c 100644 --- a/ext/tk/sample/demos-jp/hscale.rb +++ b/ext/tk/sample/demos-jp/hscale.rb @@ -24,7 +24,8 @@ msg.pack('side'=>'top') TkFrame.new($hscale_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc { tmppath = $hscale_demo $hscale_demo = nil diff --git a/ext/tk/sample/demos-jp/icon.rb b/ext/tk/sample/demos-jp/icon.rb index 9b39d33847..3180787dac 100644 --- a/ext/tk/sample/demos-jp/icon.rb +++ b/ext/tk/sample/demos-jp/icon.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($icon_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $icon_demo $icon_demo = nil @@ -44,15 +45,16 @@ TkFrame.new($icon_demo) {|frame| # image 生成 flagup = \ -TkBitmapImage.new('file'=>[$demo_dir, - 'images','flagup.bmp'].join(File::Separator), +TkBitmapImage.new('file'=>[$demo_dir,'..', + 'images','flagup.xbm'].join(File::Separator), 'maskfile'=>\ - [$demo_dir,'images','flagup.bmp'].join(File::Separator)) + [$demo_dir,'..','images','flagup.xbm'].join(File::Separator)) flagdown = \ -TkBitmapImage.new('file'=>[$demo_dir, - 'images','flagdown.bmp'].join(File::Separator), +TkBitmapImage.new('file'=>[$demo_dir,'..', + 'images','flagdown.xbm'].join(File::Separator), 'maskfile'=>\ - [$demo_dir,'images','flagdown.bmp'].join(File::Separator)) + [$demo_dir,'..', + 'images','flagdown.xbm'].join(File::Separator)) # 変数生成 letters = TkVariable.new @@ -61,13 +63,15 @@ letters = TkVariable.new TkFrame.new($icon_demo, 'borderwidth'=>10){|w| TkFrame.new(w) {|f| TkRadioButton.new(f){ - bitmap '@' + [$demo_dir,'images','letters.bmp'].join(File::Separator) + bitmap '@' + [$demo_dir,'..', + 'images','letters.xbm'].join(File::Separator) variable letters value 'full' }.pack('side'=>'top', 'expand'=>'yes') TkRadioButton.new(f){ - bitmap '@' + [$demo_dir,'images','noletter.bmp'].join(File::Separator) + bitmap '@' + [$demo_dir,'..', + 'images','noletter.xbm'].join(File::Separator) variable letters value 'empty' }.pack('side'=>'top', 'expand'=>'yes') @@ -82,7 +86,8 @@ TkFrame.new($icon_demo, 'borderwidth'=>10){|w| }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') TkCheckButton.new(w) { - bitmap '@' + [$demo_dir,'images','letters.bmp'].join(File::Separator) + bitmap '@' + [$demo_dir,'..', + 'images','letters.xbm'].join(File::Separator) indicatoron 0 selectcolor 'SeaGreen1' }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') diff --git a/ext/tk/sample/demos-jp/image1.rb b/ext/tk/sample/demos-jp/image1.rb index bfe47c47af..3d47f844e5 100644 --- a/ext/tk/sample/demos-jp/image1.rb +++ b/ext/tk/sample/demos-jp/image1.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($image1_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $image1_demo $image1_demo = nil @@ -44,10 +45,10 @@ TkFrame.new($image1_demo) {|frame| # image 生成 image1a = \ -TkPhotoImage.new('file'=>[$demo_dir, +TkPhotoImage.new('file'=>[$demo_dir,'..', 'images','earth.gif'].join(File::Separator)) image1b = \ -TkPhotoImage.new('file'=>[$demo_dir, +TkPhotoImage.new('file'=>[$demo_dir,'..', 'images','earthris.gif'].join(File::Separator)) # label 生成 diff --git a/ext/tk/sample/demos-jp/image2.rb b/ext/tk/sample/demos-jp/image2.rb index 07f9b17ebe..e2e2a2b036 100644 --- a/ext/tk/sample/demos-jp/image2.rb +++ b/ext/tk/sample/demos-jp/image2.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($image2_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $image2_demo $image2_demo = nil @@ -43,7 +44,7 @@ TkFrame.new($image2_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # 変数生成 -$dirName = TkVariable.new([$demo_dir,'images'].join(File::Separator)) +$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator)) # image 生成 $image2a = TkPhotoImage.new diff --git a/ext/tk/sample/demos-jp/image3.rb b/ext/tk/sample/demos-jp/image3.rb index 84257a2b32..d42650f45f 100644 --- a/ext/tk/sample/demos-jp/image3.rb +++ b/ext/tk/sample/demos-jp/image3.rb @@ -20,29 +20,29 @@ $image3_demo = TkToplevel.new {|w| } # -def loadDir(w) +def loadDir3(w) w.delete(0,'end') Dir.glob([$dirName,'*'].join(File::Separator)).sort.each{|f| w.insert('end',File.basename(f)) } end -# selectAndLoadDir -- +# selectAndLoadDir3 -- # This procedure pops up a dialog to ask for a directory to load into # the listobx and (if the user presses OK) reloads the directory # listbox from the directory named in the demo's entry. # # Arguments: # w - Name of the toplevel window of the demo. -def selectAndLoadDir(w, lbox) +def selectAndLoadDir3(w, lbox) dir = Tk.chooseDirectory(:initialdir=>$dirName, :parent=>w, :mustexist=>true) if dir.length > 0 $dirName.value = dir - loadDir(lbox) + loadDir3(lbox) end end -def loadImage(w,x,y) +def loadImage3(w,x,y) $image3a.file([$dirName, w.get("@#{x},#{y}")].join(File::Separator)) end @@ -59,7 +59,8 @@ msg.pack('side'=>'top') # frame TkFrame.new($image3_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $image3_demo $image3_demo = nil @@ -75,7 +76,7 @@ TkFrame.new($image3_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # variable -$dirName = TkVariable.new([$demo_dir,'images'].join(File::Separator)) +$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator)) # image begin @@ -96,16 +97,16 @@ image3_lbx = TkListbox.new(image3_ff, :width=>20, :height=>10) { yscrollbar(TkScrollbar.new(image3_ff).pack(:side=>:left, :fill=>:y, :expand=>true)) insert(0, *(%w(earth.gif earthris.gif teapot.ppm))) - bind('Double-1', proc{|x,y| loadImage(self, x, y)}, '%x %y') + bind('Double-1', proc{|x,y| loadImage3(self, x, y)}, '%x %y') } image3_ent = TkEntry.new(image3_df, :width=>30, :textvariable=>$dirName){ pack(:side=>:left, :fill=>:both, :padx=>'2m', :pady=>'2m', :expand=>true) - bind('Return', proc{loadDir(image3_lbx)}) + bind('Return', proc{loadDir3(image3_lbx)}) } TkButton.new(image3_df, :pady=>0, :padx=>'2m', :text=>"ディレクトリ選択", - :command=>proc{selectAndLoadDir(image3_ent, image3_lbx)}) { + :command=>proc{selectAndLoadDir3(image3_ent, image3_lbx)}) { pack(:side=>:left, :fill=>:y, :padx=>[0, '2m'], :pady=>'2m') } diff --git a/ext/tk/sample/demos-jp/images/earth.gif b/ext/tk/sample/demos-jp/images/earth.gif deleted file mode 100644 index 3ae4a9ce01..0000000000 Binary files a/ext/tk/sample/demos-jp/images/earth.gif and /dev/null differ diff --git a/ext/tk/sample/demos-jp/images/face.bmp b/ext/tk/sample/demos-jp/images/face.bmp deleted file mode 100644 index 03d829f4d1..0000000000 --- a/ext/tk/sample/demos-jp/images/face.bmp +++ /dev/null @@ -1,173 +0,0 @@ -#define face_width 108 -#define face_height 144 -#define face_x_hot 48 -#define face_y_hot 80 -static char face_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, - 0x20, 0x80, 0x24, 0x05, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x88, - 0x24, 0x20, 0x80, 0x24, 0x00, 0x00, 0x00, 0x10, 0x80, 0x04, 0x00, 0x01, - 0x00, 0x01, 0x40, 0x0a, 0x09, 0x00, 0x92, 0x04, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x40, 0x12, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x84, - 0x24, 0x40, 0x22, 0xa8, 0x02, 0x14, 0x84, 0x92, 0x40, 0x42, 0x12, 0x04, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x52, 0x11, 0x00, 0x12, 0x00, - 0x40, 0x02, 0x00, 0x20, 0x00, 0x08, 0x00, 0xaa, 0x02, 0x54, 0x85, 0x24, - 0x00, 0x10, 0x12, 0x00, 0x00, 0x81, 0x44, 0x00, 0x90, 0x5a, 0x00, 0xea, - 0x1b, 0x00, 0x80, 0x40, 0x40, 0x02, 0x00, 0x08, 0x00, 0x20, 0xa2, 0x05, - 0x8a, 0xb4, 0x6e, 0x45, 0x12, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10, 0x02, - 0xa8, 0x92, 0x00, 0xda, 0x5f, 0x10, 0x00, 0x10, 0xa1, 0x04, 0x20, 0x41, - 0x02, 0x00, 0x5a, 0x25, 0xa0, 0xff, 0xfb, 0x05, 0x41, 0x02, 0x04, 0x00, - 0x00, 0x08, 0x40, 0x80, 0xec, 0x9b, 0xec, 0xfe, 0x7f, 0x01, 0x04, 0x20, - 0x90, 0x02, 0x04, 0x00, 0x08, 0x20, 0xfb, 0x2e, 0xf5, 0xff, 0xff, 0x57, - 0x00, 0x04, 0x02, 0x00, 0x00, 0x20, 0x01, 0xc1, 0x6e, 0xab, 0xfa, 0xff, - 0xff, 0x05, 0x90, 0x20, 0x48, 0x02, 0x00, 0x04, 0x20, 0xa8, 0xdf, 0xb5, - 0xfe, 0xff, 0xff, 0x0b, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x04, 0xe0, - 0xbb, 0xef, 0xff, 0xff, 0x7f, 0x01, 0x00, 0x04, 0x48, 0x02, 0x00, 0x20, - 0x80, 0xf4, 0x6f, 0xfb, 0xff, 0xff, 0xff, 0x20, 0x90, 0x40, 0x02, 0x00, - 0x00, 0x04, 0x08, 0xb8, 0xf6, 0xff, 0xff, 0xdf, 0xbe, 0x12, 0x45, 0x10, - 0x90, 0x04, 0x90, 0x00, 0x22, 0xfa, 0xff, 0xff, 0xff, 0xbb, 0xd7, 0xe9, - 0x3a, 0x02, 0x02, 0x00, 0x04, 0x90, 0x80, 0xfe, 0xdf, 0xf6, 0xb7, 0xef, - 0xbe, 0x56, 0x57, 0x40, 0x48, 0x09, 0x00, 0x04, 0x00, 0xfa, 0xf5, 0xdf, - 0xed, 0x5a, 0xd5, 0xea, 0xbd, 0x09, 0x00, 0x00, 0x40, 0x00, 0x92, 0xfe, - 0xbf, 0x7d, 0xb7, 0x6a, 0x55, 0xbf, 0xf7, 0x02, 0x11, 0x01, 0x00, 0x91, - 0x00, 0xff, 0xff, 0xaf, 0x55, 0x55, 0x5b, 0xeb, 0xef, 0x22, 0x04, 0x04, - 0x04, 0x00, 0xa4, 0xff, 0xf7, 0xad, 0xaa, 0xaa, 0xaa, 0xbe, 0xfe, 0x03, - 0x20, 0x00, 0x10, 0x44, 0x80, 0xff, 0x7f, 0x55, 0x12, 0x91, 0x2a, 0xeb, - 0xbf, 0x0b, 0x82, 0x02, 0x00, 0x00, 0xd1, 0x7f, 0xdf, 0xa2, 0xa4, 0x54, - 0x55, 0xfd, 0xfd, 0x47, 0x08, 0x08, 0x00, 0x21, 0xe4, 0xff, 0x37, 0x11, - 0x09, 0xa5, 0xaa, 0xb6, 0xff, 0x0d, 0x80, 0x00, 0x00, 0x04, 0xd0, 0xff, - 0x4f, 0x44, 0x20, 0x48, 0x55, 0xfb, 0xff, 0x27, 0x11, 0x02, 0x40, 0x40, - 0xe2, 0xfb, 0x15, 0x11, 0x4a, 0x55, 0x4a, 0x7d, 0xf7, 0x0f, 0x00, 0x00, - 0x04, 0x08, 0xf8, 0xdf, 0x52, 0x44, 0x01, 0x52, 0xb5, 0xfa, 0xff, 0x0f, - 0x49, 0x02, 0x00, 0x02, 0xe9, 0xf6, 0x0a, 0x11, 0xa4, 0x88, 0x4a, 0x6d, - 0xff, 0x5f, 0x00, 0x00, 0x10, 0x20, 0xf0, 0x2f, 0x21, 0x44, 0x10, 0x52, - 0xb5, 0xfa, 0xff, 0x0f, 0x44, 0x04, 0x80, 0x08, 0xf8, 0xab, 0x8a, 0x00, - 0x81, 0xa4, 0xd4, 0xd6, 0xfe, 0x2f, 0x00, 0x00, 0x04, 0x40, 0xb5, 0x2d, - 0x21, 0x08, 0x04, 0x90, 0xaa, 0xfa, 0xff, 0x1f, 0x11, 0x01, 0x00, 0x04, - 0xf0, 0x57, 0x0a, 0x22, 0x40, 0x4a, 0xda, 0x5e, 0xfb, 0x1f, 0x40, 0x00, - 0x40, 0x20, 0xba, 0x95, 0x90, 0x00, 0x01, 0xa0, 0xaa, 0xea, 0xff, 0x5f, - 0x02, 0x02, 0x00, 0x01, 0xe8, 0x57, 0x05, 0x00, 0x00, 0x12, 0xd5, 0xfe, - 0xfd, 0x1f, 0x48, 0x00, 0x04, 0x48, 0x7a, 0x95, 0x08, 0x02, 0x10, 0x40, - 0xaa, 0x55, 0xf7, 0x1f, 0x00, 0x09, 0x20, 0x00, 0xf8, 0x57, 0x22, 0x10, - 0x00, 0x28, 0xa9, 0xfa, 0xff, 0x5f, 0x02, 0x00, 0x00, 0x49, 0xdd, 0x29, - 0x01, 0x00, 0x80, 0x80, 0xaa, 0xd7, 0xff, 0x0f, 0x10, 0x00, 0x08, 0x00, - 0xf8, 0x96, 0x08, 0x00, 0x00, 0x20, 0x54, 0xfa, 0xee, 0x3f, 0x81, 0x04, - 0x40, 0x24, 0xfe, 0x55, 0x82, 0x00, 0x00, 0x82, 0xd2, 0xad, 0xff, 0x0f, - 0x08, 0x00, 0x04, 0x80, 0x6c, 0x97, 0x00, 0x00, 0x02, 0x20, 0xa9, 0xf6, - 0xdf, 0x5f, 0x00, 0x02, 0x20, 0x09, 0xfa, 0x49, 0x12, 0x00, 0x20, 0x84, - 0x54, 0xdb, 0xfe, 0x1f, 0x91, 0x00, 0x00, 0x00, 0xf8, 0x2b, 0x00, 0x20, - 0x00, 0x40, 0xa4, 0xf6, 0xbb, 0x1f, 0x04, 0x00, 0x44, 0x92, 0x7e, 0x95, - 0x02, 0x00, 0x00, 0x89, 0xaa, 0xdd, 0xff, 0x1f, 0x20, 0x09, 0x10, 0x00, - 0xf4, 0x57, 0x20, 0x01, 0x08, 0x20, 0xa9, 0x76, 0xff, 0x5f, 0x02, 0x00, - 0x00, 0x21, 0xfc, 0x4a, 0x05, 0x00, 0x01, 0x80, 0x54, 0xdb, 0xff, 0x1e, - 0x08, 0x02, 0x04, 0x08, 0xf9, 0x2b, 0x00, 0x00, 0x40, 0x28, 0xd2, 0xf6, - 0xff, 0xbf, 0x80, 0x00, 0x90, 0x00, 0xbc, 0x92, 0x08, 0x10, 0x00, 0x82, - 0x54, 0xdb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x44, 0xf9, 0x55, 0x02, 0x01, - 0x00, 0x20, 0xaa, 0xbd, 0xfd, 0x3f, 0x08, 0x04, 0x04, 0x10, 0xf4, 0x2a, - 0x01, 0x00, 0x22, 0x80, 0xd4, 0xf6, 0xff, 0x5f, 0x82, 0x00, 0x40, 0x02, - 0xf8, 0x55, 0x20, 0x00, 0x00, 0x50, 0x6a, 0xdf, 0xfe, 0x3f, 0x00, 0x00, - 0x00, 0x48, 0xe9, 0x4a, 0x05, 0x08, 0x00, 0xa5, 0xd5, 0xf5, 0xff, 0x3f, - 0x10, 0x01, 0x10, 0x01, 0xb0, 0xab, 0x92, 0x02, 0x40, 0xf8, 0xbf, 0xde, - 0xfe, 0x5f, 0x02, 0x04, 0x04, 0x48, 0xfa, 0xd4, 0x6f, 0x20, 0x84, 0xef, - 0xff, 0xfb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xed, 0xbf, 0x0b, - 0xa1, 0x7e, 0xff, 0xbf, 0xfd, 0x5f, 0x04, 0x01, 0x20, 0x49, 0xd2, 0xfb, - 0xfe, 0x55, 0xd4, 0xff, 0xff, 0xf6, 0xff, 0x07, 0x00, 0x04, 0x00, 0x00, - 0xc0, 0xaa, 0xfb, 0x2b, 0xa2, 0xfe, 0xff, 0xdf, 0xee, 0x1f, 0x91, 0x00, - 0x82, 0xa4, 0xa4, 0xf5, 0xff, 0x57, 0xd5, 0xff, 0xbf, 0xfd, 0xff, 0x4d, - 0x00, 0x00, 0x20, 0x00, 0x88, 0x5b, 0xff, 0x2f, 0x69, 0xff, 0xff, 0xdb, - 0xfe, 0x1f, 0x24, 0x02, 0x00, 0x49, 0xa2, 0xd6, 0xff, 0x5f, 0xea, 0xff, - 0x7f, 0x7f, 0x7f, 0x0d, 0x00, 0x00, 0x10, 0x00, 0x40, 0xab, 0xf7, 0xbb, - 0xf0, 0xdf, 0xff, 0xd5, 0xff, 0xbf, 0x82, 0x04, 0x42, 0x24, 0x91, 0xd5, - 0xaa, 0xae, 0xd4, 0xaa, 0x52, 0x7b, 0xff, 0x15, 0x08, 0x00, 0x00, 0x01, - 0x04, 0x55, 0xd5, 0x55, 0x70, 0x5b, 0x75, 0xdd, 0xdf, 0x1f, 0x40, 0x00, - 0x08, 0x48, 0xa0, 0x4a, 0xa9, 0x56, 0xea, 0x56, 0xad, 0x6a, 0x7d, 0x9b, - 0x04, 0x01, 0x00, 0x02, 0x42, 0x2a, 0xd5, 0xaa, 0xa8, 0xaa, 0xaa, 0xfa, - 0xdf, 0x2f, 0x10, 0x04, 0x22, 0x48, 0x08, 0x45, 0x2a, 0x15, 0x68, 0x55, - 0x55, 0xd7, 0x76, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x40, 0x2a, 0x80, 0xa0, - 0xb2, 0x09, 0x48, 0xb9, 0xdf, 0x17, 0x22, 0x01, 0x00, 0x24, 0x45, 0x8a, - 0x24, 0x4a, 0x54, 0x51, 0x91, 0xf6, 0x6e, 0x4b, 0x00, 0x04, 0x90, 0x00, - 0x80, 0x52, 0x00, 0x20, 0x69, 0x05, 0xa4, 0xaa, 0xff, 0x1e, 0x48, 0x00, - 0x02, 0x92, 0x08, 0x05, 0x81, 0x94, 0xd4, 0x92, 0x40, 0xfd, 0xb6, 0x8b, - 0x00, 0x01, 0x40, 0x00, 0x82, 0x54, 0x00, 0x48, 0x68, 0x05, 0x90, 0xa4, - 0xef, 0x06, 0x24, 0x00, 0x08, 0x12, 0x10, 0x05, 0x00, 0x10, 0xb5, 0x01, - 0x42, 0xfb, 0xbf, 0x43, 0x00, 0x09, 0x00, 0x40, 0x81, 0xa8, 0x08, 0x4a, - 0xaa, 0x96, 0x90, 0xac, 0x6d, 0x15, 0x22, 0x00, 0x20, 0x09, 0x04, 0x15, - 0x80, 0x28, 0xdc, 0x01, 0x24, 0xfb, 0xbf, 0x01, 0x80, 0x04, 0x09, 0x00, - 0x40, 0x48, 0x02, 0x45, 0xb2, 0x2e, 0x41, 0x6d, 0xef, 0x05, 0x11, 0x00, - 0x40, 0x52, 0x02, 0x15, 0x29, 0x2a, 0xac, 0x42, 0x54, 0xfb, 0x3b, 0x51, - 0x84, 0x00, 0x08, 0x00, 0x20, 0x54, 0x80, 0x05, 0xb5, 0x3d, 0xa2, 0xb6, - 0xdf, 0x00, 0x20, 0x04, 0x20, 0x49, 0x89, 0xa8, 0x6a, 0x29, 0xac, 0xd6, - 0x54, 0xff, 0x3f, 0x84, 0x00, 0x01, 0x04, 0x10, 0x00, 0x94, 0xa8, 0x56, - 0xda, 0x5f, 0xab, 0xd5, 0x1e, 0x10, 0x48, 0x00, 0x90, 0x82, 0x48, 0xa8, - 0xb2, 0xac, 0xfd, 0x55, 0xd5, 0xfe, 0x9f, 0x80, 0x00, 0x0a, 0x02, 0x08, - 0x02, 0x55, 0x5a, 0x75, 0xff, 0xaf, 0xb6, 0xf7, 0x2d, 0x12, 0x92, 0x00, - 0x10, 0x20, 0x10, 0xa8, 0x54, 0xd5, 0xbf, 0x5d, 0xad, 0xdd, 0x0f, 0x00, - 0x00, 0x04, 0x40, 0x09, 0x84, 0xa8, 0xaa, 0x5a, 0xed, 0xeb, 0x6a, 0xff, - 0x9f, 0xa4, 0x24, 0x01, 0x02, 0xa0, 0x20, 0x50, 0x55, 0xd5, 0xbe, 0xae, - 0xad, 0xfd, 0x16, 0x00, 0x10, 0x04, 0x20, 0x0a, 0x08, 0xb4, 0xaa, 0x95, - 0xaa, 0x7b, 0xb7, 0xdb, 0x5f, 0x92, 0x04, 0x01, 0x84, 0x20, 0x21, 0x51, - 0xd5, 0x2a, 0xa9, 0xee, 0xd5, 0xfe, 0x0d, 0x00, 0x20, 0x04, 0x10, 0x00, - 0x08, 0x50, 0xe9, 0xd7, 0xd4, 0xfb, 0xb5, 0xff, 0x9f, 0x24, 0x09, 0x01, - 0x42, 0x4a, 0xa2, 0x64, 0xd5, 0x55, 0x7b, 0x7f, 0xda, 0x7d, 0x4f, 0x00, - 0x20, 0x04, 0x00, 0x80, 0x00, 0xa0, 0x2a, 0x13, 0x84, 0x6a, 0x55, 0xff, - 0x1d, 0x48, 0x8a, 0x00, 0x94, 0x24, 0x8a, 0xc8, 0xaa, 0x42, 0x20, 0x5d, - 0xf5, 0xff, 0x5f, 0x01, 0x00, 0x02, 0x01, 0x00, 0x20, 0xa2, 0x4a, 0x1a, - 0x82, 0x56, 0xda, 0xbd, 0x3f, 0x92, 0x92, 0x00, 0x90, 0x92, 0x00, 0x40, - 0x95, 0x6a, 0xf4, 0x55, 0x6d, 0xff, 0xd6, 0x00, 0x00, 0x0a, 0x04, 0x20, - 0x14, 0x49, 0x4b, 0xaa, 0xaa, 0x56, 0xf5, 0xff, 0xbf, 0xab, 0xa4, 0x00, - 0x20, 0x89, 0x40, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xde, 0xbf, 0xeb, 0x03, - 0x00, 0x02, 0x04, 0x02, 0x0a, 0x10, 0x2b, 0x2a, 0x55, 0x5b, 0xf5, 0xff, - 0xd7, 0x2f, 0x92, 0x00, 0x10, 0x28, 0x21, 0x01, 0x56, 0x95, 0xa0, 0x56, - 0xdf, 0xef, 0xea, 0x87, 0x40, 0x0a, 0x42, 0x41, 0x00, 0x90, 0xaa, 0x52, - 0xb6, 0xad, 0xfa, 0xff, 0xd5, 0x2f, 0x14, 0x00, 0x00, 0x04, 0x95, 0x04, - 0xaa, 0xac, 0x55, 0x6b, 0xff, 0xb7, 0xea, 0x9f, 0x40, 0x02, 0x28, 0x51, - 0x00, 0x40, 0x58, 0xd5, 0xda, 0xd6, 0x6e, 0x7f, 0xf9, 0x3f, 0x12, 0x04, - 0x02, 0x04, 0x49, 0x25, 0x55, 0xaa, 0x77, 0xab, 0xff, 0x2b, 0xfd, 0x3f, - 0x48, 0x01, 0x20, 0x41, 0x00, 0x00, 0x58, 0xa9, 0xda, 0xea, 0xfd, 0xaf, - 0xfa, 0xff, 0x02, 0x04, 0x08, 0x14, 0x29, 0x49, 0x52, 0x55, 0x55, 0x55, - 0xff, 0x8d, 0xfe, 0x3f, 0xa8, 0x00, 0x02, 0x41, 0x00, 0x02, 0xa0, 0xa2, - 0xaa, 0xea, 0xff, 0x53, 0xfd, 0xff, 0x02, 0x04, 0x50, 0x04, 0x25, 0xa8, - 0x54, 0x49, 0x52, 0xb5, 0xbf, 0x8a, 0xfe, 0xff, 0xa9, 0x08, 0x04, 0x50, - 0x80, 0x02, 0xa1, 0x2a, 0x95, 0xea, 0xff, 0xa1, 0xff, 0xff, 0x03, 0x02, - 0x90, 0x02, 0x09, 0x08, 0x44, 0x49, 0x52, 0xbd, 0x7f, 0xca, 0xff, 0xff, - 0x2b, 0x09, 0x04, 0x48, 0x40, 0x82, 0x90, 0x56, 0xa9, 0xf6, 0xbf, 0xd0, - 0xff, 0xff, 0x47, 0x00, 0x50, 0x02, 0x15, 0x11, 0x40, 0x95, 0xaa, 0xfd, - 0x2f, 0xe9, 0xff, 0xff, 0x8f, 0x0a, 0x84, 0x50, 0x40, 0x84, 0x14, 0xaa, - 0x6a, 0xff, 0x5f, 0xf2, 0xff, 0xff, 0x7f, 0x00, 0x10, 0x02, 0x09, 0x10, - 0x40, 0x7d, 0xf7, 0xff, 0x0b, 0xfc, 0xff, 0xff, 0xaf, 0x02, 0x84, 0x50, - 0x42, 0x85, 0x12, 0xd0, 0xdd, 0xff, 0xa7, 0xf2, 0xff, 0xff, 0xff, 0x04, - 0x00, 0x0a, 0x08, 0x10, 0x48, 0xf8, 0xff, 0xff, 0x0a, 0xfe, 0xff, 0xff, - 0x7f, 0x03, 0xa4, 0x80, 0xa2, 0x8a, 0x02, 0x68, 0xff, 0xff, 0x52, 0xfd, - 0xff, 0xff, 0xff, 0x07, 0x00, 0x2a, 0x08, 0x20, 0x28, 0xdc, 0xff, 0x5f, - 0x05, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x92, 0x40, 0x22, 0x09, 0x02, 0xea, - 0xfb, 0xaf, 0x48, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x12, 0x81, 0xa0, - 0x48, 0x9c, 0x6e, 0x93, 0xa2, 0xff, 0xff, 0xff, 0xff, 0x07, 0xa8, 0x40, - 0x28, 0x0a, 0x02, 0x74, 0xb5, 0x45, 0x81, 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x02, 0x0a, 0x81, 0x20, 0x08, 0xae, 0xaa, 0x90, 0xe8, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0x90, 0x40, 0x28, 0x88, 0x12, 0x58, 0x15, 0x50, 0xd0, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x44, 0x0a, 0x41, 0x21, 0x08, 0xae, 0x04, 0x14, - 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40, 0x14, 0x88, 0x04, 0xba, - 0x02, 0x28, 0xe8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x15, 0x41, 0x21, - 0x05, 0xad, 0x00, 0x05, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40, - 0x24, 0x8a, 0x0e, 0x36, 0x00, 0x0a, 0xf4, 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x42, 0x25, 0x90, 0xd0, 0x8b, 0xc2, 0x41, 0x05, 0xfc, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0x10, 0x08, 0x05, 0xe8, 0x8e, 0x58, 0x80, 0x02, 0xfa, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x4a, 0x20, 0xa8, 0xba, 0x0b, 0x2b, 0x51, 0x01, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x8a, 0x02, 0xe8, 0xaf, 0x84, - 0x90, 0x04, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x52, 0x21, 0x54, 0xbf, - 0x1f, 0x15, 0xa5, 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x08, - 0x01, 0xfa, 0xb6, 0xa4, 0x52, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x4a, 0xa2, 0x54, 0xef, 0x5f, 0x4b, 0xa4, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0x80, 0x10, 0x82, 0xfe, 0xbf, 0x92, 0x52, 0x42, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x12, 0x42, 0xa8, 0xbf, 0x1f, 0x24, 0x80, 0xa0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28, 0x8a, 0xf7, 0x37, 0x80, - 0x52, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x82, 0xe0, 0xff, - 0x1f, 0x00, 0x20, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28, - 0xca, 0xff, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x10, 0x42, 0xf0, 0xfd, 0x1b, 0x00, 0x50, 0xf0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0xa4, 0x10, 0xc5, 0xff, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x00, 0x22, 0xf8, 0xff, 0x0e, 0x00, 0x00, 0xf0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xaa, 0x88, 0xe2, 0xff, 0x0f, 0x10, - 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x25, 0xfa, 0xff, - 0x0f, 0x01, 0x11, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xfb, - 0xfb, 0xff, 0x7f, 0x5d, 0xd5, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f}; diff --git a/ext/tk/sample/demos-jp/images/flagdown.bmp b/ext/tk/sample/demos-jp/images/flagdown.bmp deleted file mode 100644 index 55abc51825..0000000000 --- a/ext/tk/sample/demos-jp/images/flagdown.bmp +++ /dev/null @@ -1,27 +0,0 @@ -#define flagdown_width 48 -#define flagdown_height 48 -static char flagdown_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe1, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04, - 0x00, 0x00, 0x03, 0x00, 0x06, 0x06, 0x00, 0x80, 0x01, 0x00, 0x06, 0x07, - 0x00, 0xc0, 0x1f, 0x00, 0x87, 0x07, 0x00, 0xe0, 0x7f, 0x80, 0xc7, 0x07, - 0x00, 0x70, 0xe0, 0xc0, 0xe5, 0x07, 0x00, 0x38, 0x80, 0xe1, 0x74, 0x07, - 0x00, 0x18, 0x80, 0x71, 0x3c, 0x07, 0x00, 0x0c, 0x00, 0x3b, 0x1e, 0x03, - 0x00, 0x0c, 0x00, 0x1f, 0x0f, 0x00, 0x00, 0x86, 0x1f, 0x8e, 0x07, 0x00, - 0x00, 0x06, 0x06, 0xc6, 0x05, 0x00, 0x00, 0x06, 0x00, 0xc6, 0x05, 0x00, - 0x00, 0x06, 0x00, 0xc6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00, - 0x7f, 0x06, 0x00, 0x06, 0xe4, 0xff, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00, - 0x00, 0x06, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x06, 0x00, - 0x00, 0x06, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00, - 0x00, 0x06, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00, - 0x00, 0xfe, 0xff, 0x2f, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x27, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0xf7, 0xbf, 0x8e, 0xfc, 0xdf, 0xf8, 0x9d, 0xeb, 0x9b, 0x76, 0xd2, 0x7a, - 0x46, 0x30, 0xe2, 0x0f, 0xe1, 0x47, 0x55, 0x84, 0x48, 0x11, 0x84, 0x19}; diff --git a/ext/tk/sample/demos-jp/images/flagup.bmp b/ext/tk/sample/demos-jp/images/flagup.bmp deleted file mode 100644 index 6eb0d846a3..0000000000 --- a/ext/tk/sample/demos-jp/images/flagup.bmp +++ /dev/null @@ -1,27 +0,0 @@ -#define flagup_width 48 -#define flagup_height 48 -static char flagup_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xef, 0x6a, 0x00, - 0x00, 0x00, 0xc0, 0x7b, 0x75, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x6a, 0x00, - 0x00, 0x00, 0x30, 0x60, 0x75, 0x00, 0x00, 0x00, 0x18, 0xe0, 0x7f, 0x00, - 0x00, 0x00, 0x0c, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x06, 0xe0, 0x04, 0x00, - 0x00, 0x00, 0x03, 0xe0, 0x04, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00, - 0x00, 0xc0, 0x1f, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x7f, 0xe0, 0x07, 0x00, - 0x00, 0x70, 0xe0, 0xe0, 0x05, 0x00, 0x00, 0x38, 0x80, 0xe1, 0x04, 0x00, - 0x00, 0x18, 0x80, 0xf1, 0x04, 0x00, 0x00, 0x0c, 0x00, 0xfb, 0x04, 0x00, - 0x00, 0x0c, 0x00, 0xff, 0x04, 0x00, 0x00, 0x86, 0x1f, 0xee, 0x04, 0x00, - 0x00, 0x06, 0x06, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0xe6, 0x04, 0x00, - 0x00, 0x06, 0x00, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x66, 0x04, 0x00, - 0x7f, 0x56, 0x52, 0x06, 0xe4, 0xff, 0x00, 0x76, 0x55, 0x06, 0x04, 0x00, - 0x00, 0x56, 0x57, 0x06, 0x04, 0x00, 0x00, 0x56, 0x55, 0x06, 0x06, 0x00, - 0x00, 0x56, 0xd5, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00, - 0x54, 0x06, 0x00, 0xc6, 0x54, 0x55, 0xaa, 0x06, 0x00, 0x66, 0xaa, 0x2a, - 0x54, 0x06, 0x00, 0x36, 0x55, 0x55, 0xaa, 0x06, 0x00, 0xbe, 0xaa, 0x2a, - 0x54, 0xfe, 0xff, 0x6f, 0x55, 0x55, 0xaa, 0xfc, 0xff, 0xa7, 0xaa, 0x2a, - 0x54, 0x01, 0x88, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a, - 0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a, - 0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a, - 0x54, 0x55, 0x8d, 0x50, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa8, 0xaa, 0x2a, - 0x54, 0x55, 0x95, 0x54, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, - 0x54, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/ext/tk/sample/demos-jp/images/gray25.bmp b/ext/tk/sample/demos-jp/images/gray25.bmp deleted file mode 100644 index b234b3cb0b..0000000000 --- a/ext/tk/sample/demos-jp/images/gray25.bmp +++ /dev/null @@ -1,6 +0,0 @@ -#define grey_width 16 -#define grey_height 16 -static char grey_bits[] = { - 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, - 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, - 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44}; diff --git a/ext/tk/sample/demos-jp/images/grey.25 b/ext/tk/sample/demos-jp/images/grey.25 deleted file mode 100644 index b234b3cb0b..0000000000 --- a/ext/tk/sample/demos-jp/images/grey.25 +++ /dev/null @@ -1,6 +0,0 @@ -#define grey_width 16 -#define grey_height 16 -static char grey_bits[] = { - 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, - 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, - 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44}; diff --git a/ext/tk/sample/demos-jp/images/grey.5 b/ext/tk/sample/demos-jp/images/grey.5 deleted file mode 100644 index 37688893f0..0000000000 --- a/ext/tk/sample/demos-jp/images/grey.5 +++ /dev/null @@ -1,6 +0,0 @@ -#define grey_width 16 -#define grey_height 16 -static char grey_bits[] = { - 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, - 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, - 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa}; diff --git a/ext/tk/sample/demos-jp/images/letters.bmp b/ext/tk/sample/demos-jp/images/letters.bmp deleted file mode 100644 index 0f12568d1a..0000000000 --- a/ext/tk/sample/demos-jp/images/letters.bmp +++ /dev/null @@ -1,27 +0,0 @@ -#define letters_width 48 -#define letters_height 48 -static char letters_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, - 0x00, 0xfa, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x3a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2e, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0x21, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, - 0xa0, 0x03, 0x00, 0x00, 0x70, 0x21, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, - 0xa0, 0x1f, 0x00, 0x00, 0x50, 0x21, 0x20, 0x00, 0x00, 0x00, 0x70, 0x21, - 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x21, - 0xfa, 0x01, 0x00, 0x80, 0x0b, 0x21, 0x02, 0x00, 0x00, 0x80, 0x0a, 0x21, - 0xba, 0x01, 0x00, 0x80, 0x0a, 0x21, 0x02, 0x00, 0x00, 0x80, 0x0b, 0x21, - 0x3a, 0x00, 0x00, 0x00, 0x08, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x21, - 0x02, 0xc0, 0xfb, 0x03, 0x08, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x3f, - 0x02, 0xc0, 0xbd, 0x0f, 0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x01, - 0x02, 0xc0, 0x7f, 0x7b, 0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x01, - 0x02, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, - 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/ext/tk/sample/demos-jp/images/noletter.bmp b/ext/tk/sample/demos-jp/images/noletter.bmp deleted file mode 100644 index 5774124efe..0000000000 --- a/ext/tk/sample/demos-jp/images/noletter.bmp +++ /dev/null @@ -1,27 +0,0 @@ -#define noletters_width 48 -#define noletters_height 48 -static char noletters_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, - 0x00, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x7f, 0x00, - 0x00, 0x3e, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x01, - 0x80, 0x07, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0xe0, 0x07, - 0xe0, 0x01, 0x00, 0x00, 0xf0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x0e, - 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x1e, 0x1c, - 0x38, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x38, 0x00, 0x00, 0x80, 0x07, 0x38, - 0x3c, 0xfc, 0xff, 0xff, 0x7f, 0x78, 0x1c, 0x04, 0x00, 0xe0, 0x41, 0x70, - 0x1c, 0x04, 0x00, 0xf0, 0x40, 0x70, 0x1c, 0x74, 0x00, 0x78, 0x4e, 0x70, - 0x0e, 0x04, 0x00, 0x3c, 0x4a, 0xe0, 0x0e, 0x74, 0x03, 0x1e, 0x4a, 0xe0, - 0x0e, 0x04, 0x00, 0x0f, 0x4e, 0xe0, 0x0e, 0x04, 0x80, 0x07, 0x40, 0xe0, - 0x0e, 0x04, 0xf8, 0x0f, 0x40, 0xe0, 0x0e, 0x04, 0xe0, 0x01, 0x40, 0xe0, - 0x0e, 0x04, 0xf8, 0x00, 0x40, 0xe0, 0x0e, 0x04, 0x78, 0x00, 0x40, 0xe0, - 0x0e, 0x04, 0xfc, 0xf3, 0x40, 0xe0, 0x1c, 0x04, 0x1e, 0x00, 0x40, 0x70, - 0x1c, 0x04, 0x0f, 0x00, 0x40, 0x70, 0x1c, 0x84, 0x07, 0x00, 0x40, 0x70, - 0x3c, 0xfc, 0xff, 0xff, 0x7f, 0x78, 0x38, 0xe0, 0x01, 0x00, 0x00, 0x38, - 0x38, 0xf0, 0x00, 0x00, 0x00, 0x38, 0x70, 0x78, 0x00, 0x00, 0x00, 0x1c, - 0xf0, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x1e, 0x00, 0x00, 0x00, 0x0e, - 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x07, 0x00, 0x00, 0x80, 0x07, - 0x80, 0x07, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x01, - 0x00, 0x3e, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x7f, 0x00, - 0x00, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00}; diff --git a/ext/tk/sample/demos-jp/images/pattern.bmp b/ext/tk/sample/demos-jp/images/pattern.bmp deleted file mode 100644 index df31baf789..0000000000 --- a/ext/tk/sample/demos-jp/images/pattern.bmp +++ /dev/null @@ -1,6 +0,0 @@ -#define foo_width 16 -#define foo_height 16 -static char foo_bits[] = { - 0x60, 0x06, 0x90, 0x09, 0x90, 0x09, 0xb0, 0x0d, 0x4e, 0x72, 0x49, 0x92, - 0x71, 0x8e, 0x8e, 0x71, 0x8e, 0x71, 0x71, 0x8e, 0x49, 0x92, 0x4e, 0x72, - 0xb0, 0x0d, 0x90, 0x09, 0x90, 0x09, 0x60, 0x06}; diff --git a/ext/tk/sample/demos-jp/images/teapot.ppm b/ext/tk/sample/demos-jp/images/teapot.ppm deleted file mode 100644 index 78afefbf82..0000000000 --- a/ext/tk/sample/demos-jp/images/teapot.ppm +++ /dev/null @@ -1,56 +0,0 @@ -P6 -256 256 -255 -\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[7 eOLjQLmSMoTMnSMlRMhPL_9 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nSMtVMzYN~[N~[N\N\O\O]O]O]O]O\O\O}[NyYNtVM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\G-wXN}[N]O^O_O`O`O`O`OaOaOaOaOaOaOaOaO`O_O^O\N \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aMLyYN_OaPbPcPcPdPdPdPdPdPdPdPdPdPePePePePePdPcP_OpUM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\wXN_OdPfPgQhQhQiQiQiQiQiQjQjQjQjQjQjQjQjQjQjQiQfP`O\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\NCJiQLbPhQkQmRnRoRoRoRoRoRoRoRoRpRpSqSqSrSrSrSqSoRjQ]O\KK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\fOLrUMcPlRqStSuTwTxTxTyTyTzTzUzUzUzUzUyTxTwTtSmRaOhPL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\a0 cNLqUM\OfQpSwVzV|V}VVVVW[ew螽gqTfQ{ZNYIK9\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\O1{G#JkRMqUMtVNiSv\dbzZvUuTsSqSnRjQeP^OrUMHh>!T4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\G-V5wE"~I#M%U+e7l:g2b*a(`(^(])^-]1S,qC$`9 R3G-\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\@)J/i>!pA"tD"wF$yH&xH&tE$wE#yG%}M+T4S5mE*Z7!K/B*;'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aOoR{UVX<(F-a: e!j@#k@$h>"df-^(Z'W&T&N>)F-J/b; g>#nD(jB&c y< u: r9 o7 l6 -j5 -h4 -g3 -5$D,K/b; h>"wM1tK.e="a<#cA,U8&E-<(9&.!a0 b1 c1     - -+3#@)46G<:HMCIXHK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\U*vT~X{Yk+W&N$|> u: p8 k5 -f3 -a0 _/ ]. [- I\*_(LkRMmSMmSMnSMnSMD,R3W5mA"|O0|P1j?"c!a: X/K%&4$+2F=;HPEJL&\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\lRxTsTd)O$w; m6 -g3 -a0 Z- \/ T*Q(Hm8kRMmSMnTMoTMpTMpUM15G15G05G04G04GpUMpTM5^9 d!Y0W+]. s=M$dPlR\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\oTMoRdPvE"V+K%A 99F['qUMtVM99H:9H:9H:9H:9H:9H:9H:9H:9H:9H99H99H99H99H99H99H:9H;:H>;HB=HPDJ\JKmSMwXN|ZNy[瓲u{WyU]btUnRhQaO{ZNvWNtVMvXNwXNyYNzYN{ZN|ZN}[N}[N~[N~[N~[N~[N~[N~[N~[N}[N}[N{ZNzYNxXNL$f3 -I$L&P(U*\. J#\OjQ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\kRaOo9 -L&C!:4f3 -X&pUMuWMwXNxXN<:H<:H<:H<:H<;H<;H<;H<;H=;H=;H=;H=;H>;H>;H?HG@ILBIREJ[JKcNLjQLpRuTzU~VWXcse{VvTpSkRgQbP_O^O]O\O\O\O\O]O]O]O]O]O]O]O]O]O]O]O\O\O~\N}[N|ZNxXNT%H$G#K%Q(W+zG#nTMiQ\\\\\\\\\\\\dOLrUMuWNwXNyYN{ZN}[N{ZNwXNsVM \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`OcPnA"M&@ 8F#m6 -W&rVMvWNyYNzYN|ZN}[N}[N>HE?IG@IIAIKBIODJSFJWHKhQlRpRb(i*n+|7|6r,q+p-l+g)b(sSpSlRiQgQePcPaPaO`O`O_O_O_O_O_O_O_O_O_O_O^O^O^O^O]O]O\O~[N{ZNT%F#B!Y,L&U*~I#^O`O\\\\cNLrUMzYN\O^O`ObPcPdPePfPfPfQfQfQePcPaP~[N\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\fPsVM^/ C!7 -Q%tVMwXNzYN|ZN}[N\N\O\O]O]O]O]OA=HB=HB=HB>HC>HC>ID?IE?IF@IG@IIAIKBIcPdPePgQiQlRnR\'d)i*m+s/s/o+n+l*i*g)c(_(qSoRmRkQiQgQfPePdPcPbPbPbPaPaPaOaOaO`O`O`O`O`O`O_O_O^O^O]O\O}[NQD"?D"K%_/ kRLfPODJSFJ_ObPcPePfQgQiQjQkRlRmRnRnRoRoRoRnRmRlRiQeP_O\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\B+ePI#L&90y< PxXN{ZN}[N\N\O]O]O^O^O^O_O_O_O_O`O`O`O`OaOaPbPbPcPdPePfPgQhQiQkRmRZ'_(e)h)k*n,n,m*l*j*f)e)c(_(]'pRnRmRkRjQiQgQgQfPePdPdPdPcPcPcPbPbPbPbPbPaPaPaOaO`O`O_O_O^O]O_(@ B!I$B!N'w=eP`LKbNLeOLkRmRnRoRpSqSrSsStStStSuSuStStSsSrSpSmRjQbPjQL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\bPpTME"5M$tVM{ZN}[N\O]O^O^O_O_O_O`O`O`O`OaOaPaPbPbPbPcPcPdPdPePfPgQhQiQjQkRlRmRZ'`(d)g)gj*j*i*i*g)d)c(a(_(\'pRoRnRmRkRjQiQiQhQgQgQfPePePePdPdPdPcPcPcPcPcPbPbPbPbPaPaO`O_O^O\NQ@ <G#_LKcPlSMnTMpUMsVMtSuTvTwTwTxTxTwTwTvTuTtSsSqSpSoRnRkRhQbPeOL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\wXN\NJ%01JvWN}[N\O]O^O_O_O`O`O`OaOaPaPbPbPbPbPcPcPdPdPdPePePfQgQgQhQiQjQkQlRmRY&]'`(c(e)c\\\]]^a(`(^'['['oRnRmRlRkRkQjQiQiQhQgQgQgQfQfPePePePePdPdPdPdPdPcPcPcPbPbPaPaO`O]OOG#7F#uWM^OwXNxXNzYN{ZN|ZNyTyTxTwTuTsSpSmRjQgQdPbPaPaPbPcPePcP|ZN\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[JKbP^/ 1 01|> wXN}[N]O^O_O`O`OaOaPaPbPbPbPcPcPcPcPdPdPdPePePfPfQgQgQhQhQiQjQkQkRlRmRY&]'`(b([gihfdecU_(]'['Z'nRnRmRmRlRkRkQjQjQiQiQhQhQgQgQgQfQfQfPfPePePePePePdPdPdPcPcPbPbP`O^OD -4M&dPnSM|[N|[O|[OzZOxXNrSnRhQcP^OvXNiQL^KKRFJMCJJAIKBISFJ\JKnSMxYN_O\OaMK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\B!qUMaPC!/00a0 uWN}[N]O_O`O`OaPaPbPbPcPcPcPcPdPdPdPePePePfPfQfQgQgQhQhQiQiQjQjQkRlRlRX&['^'`(Zdfigdcca_T\'['Z'Y&nRmRmRlRlRkRkQjQjQjQiQiQhQhQhQhQgQgQgQgQfQfQfQfPfPePePePdPdPcPbPaO^Ox< :aP]Oj8sVMmSMfOL^KKUGJIAIQEJ?IeZY638*  B\\\\\,  4 .G1!\TUrsVM{ZN`MK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[JKyYNbP/0N$]O_O`ObPbPcPcPdPdPdPePePePfPfPfQfQgQgQgQgQhQhQhQiQiQiQjQjQkQkRkRlROZ'\'^'Vabei!fba`_]\Z['Z'Y&QmRmRmRlRlRlRkRkRkQkQjQjQjQjQiQiQiQiQiQhQhQhQhQhQhQgQgQgQgQfQfPdPcPW&dPaPrUM - B\\\\\\\\\\%7!!C*F#P) {dYzep\OgPL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SFJ`LKvWNaPm6 - X,uWM]O`ObPcPdPdPdPePePfPfPfQfQgQgQgQgQgQhQhQhQiQiQiQiQjQjQjQkQkQkRlRlRZ'\']'_`abei"ea`__]\\YZ'Z'Z'mRmRmRlRlRlRlRlRkRkRkRkQkQjQjQjQjQjQjQiQiQiQiQiQiQiQhQhQhQgQgQfQdP_Oq8 gQ`OuWMT%\\\\\\\\\\ B B!!T,c5FT3~q^OfOL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\XHK_LKsVM`OcP S%]ObPcPdPePePfPfQfQgQgQgQgQgQhQhQhQhQiQiQiQiQiQjQjQjQjQkQkRkRlRlRlR\']'^'V`abfi"ea`__]\\RZ'Z'['mRmRmRmRmRlRlRlRlRlRlRkRkRkRkRkQkQjQjQjQjQjQjQjQjQjQjQiQiQiQhQgQePSq8 aOgQ`OtVMX&\\\\\\\\\\ B B B l@!{AL$Y'afPaO]KK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ODJ[JKaMKqUM\OcP^OvE"]OaPdPePfPfQgQgQgQhQhQhQhQhQiQiQiQiQiQjQjQjQjQjQkQkQkRkRkRlRlRlRlR^'^'_(Waacg i"ea`__^\\R['[']'mRmRmRmRmRmRmRlRlRlRlRlRlRlRlRlRlRkRkRkRkRkRkRkRkRkQkQkQjQjQiQhQePW&M&oTMiQeP_OtVMmSMdOL\\\\\\\\\ B B B JZ'_(kQiQ`OSFJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\TFJ\JKcNLlRMzYN`OePzZN \N`OdPfQgQgQhQhQhQiQiQiQiQiQiQjQjQjQjQjQjQkQkQkRkRkRlRlRlRlRlRlRmRa(`(`([abdh!i"da`__^]]S\']'_(nRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRlRlRlRlRlRlRlRlRlRlRlRlRlRkRkQiQePt: kQhQcP]OtVMlSMa2 -\\\\\\\\\ B B -$5 `(e)nRjQ^OJAI\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\XIK^KKdNLhPLuWM]ObPfQeP -m6 -`OcPfQhQhQiQiQjQjQjQjQjQjQjQkQkQkQkRkRkRkRlRlRlRlRlRlRlRmRmRmRmRg)c(c(b(Vcei!i!db``__^Q]'_(`(f)nRnRnRnRnRnRnRnRnRnRnRnRnRmRmRmRmRmRmRmRmRmRnRmRmRnRmRmRmRmRkRhQGa0 bPmRjQfQaP}[NrUMmSML$\\\\\\\\ B B -#C, 8&H.Z7 pRjQ{ZN\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\QEJ[JK`LKdNLhQLqUM{ZN_OcPgQhQ -bPePhQiQjQjQkQkQkRkRkRlRlRlRlRlRlRlRlRlRlRmRmRmRmRmRmRmRmRmRnRnRj*g)e)d)dXghecbbbU`(a(a(c(i*oRoRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRoRoRoRoRoRoRoRoRoRoRoRoRnRmRjQQ%Z- jQnRlRhQdP_OuWMpTMnSMkRLa: \\\\\\\ B B&D2 -@*S6#G@IPDJhQmSM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\VGJ]KKbMLeOLiQLlRMvWN\OaOePhQjQgQoTMgQiQkQlRlRlRmRmRmRmRmRmRmRmRmRmRmRmRmRmRnRnRnRnRnRnRnRnRnRnRnRnRl*l+j+g)f)e)d)e)e)e)e)f)i*s0s.oRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRpRpRpRpRpRpSpSpSqSqSqSqSpSqSpSnRlRIhQpRoRmRiQePaP\OsVMpTMnTMlRMX)\\\\\\\ B%C)D$;J/[8"LBITGJYIKWHK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\NCJYIK_LKcNLgPLjQLlRMpUMzYN^ObPePhQkQlRfQ- hQjQlRmRnRnRnRnRnRnRnRnRnRnRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRpRpRpRpy-w-w-y.{-upSpSpSpSpSpSpSpSpSpSpSpSpSpSpSqSqSqSqSqSqSqSqSqSrSrSrSrSrSrSrSsSrSqSoRiQiQqSqSpRmRjQgQcP_O{ZNtVMpUMoTMmSMjQL_9 \\\\\ B "C(D#*A$[<)dI\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SFJ[JKaMKeOLhPLkRLmSMoTMuWM}[N_ObPePhQkRmRnRkR!-EkRmRnRoRpRpRpSpSpSpSpSpSpSpRpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSrSrSrSrSrSrSrSrSrSrSsSsSsSsStStStStStSuStSsSrSnRoRsSsSrSpRmRjQgQdPaO\OyYNuWMqUMoTMnSMkRLo8 -\\\\\ B'D+E$(1 J/jH1NCJUGJYIKUGJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\XHK]KKbNLfOLiQLkRMmSMoTMqUMxXN\N_ObPfPhQkQmRoRpSpRhQmRoRpSqSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSsSsSsSsSsSsSsSsSsSsSsSsStStStSuSuSuTuTuTuTuTvTwTvTvTuTtSmRtSuTuStSrSpRmRkQhQePaP^O\N{ZNvXNqUMpTMnSMlRMP%\\\\ B#C*E$.E- .!G$Y:%d<"SFJYIKZIKNCJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\PDJZIK_LKdNLgPLjQLlRMnSMpTMqUMuWMyYN\O`OcPfPhQjQmRoRqSrSrSrSmRrSsStStStStStStStStStStStStStStStSsSsSsSsSsSsSsSsSsStStStStStStStStStStStStStStStStSuSuSuTuTvTvTvTvTvTwTwTwTwTxTxTxTyTyUxU\'qSvTwTwTvTuTtTrSoRmRkQhQePbP`O^O\O|ZNxXNtVMpTMoTMmSMjQLh7\\\ B(D"-E*1F, 4#K)pL5PEJWHK[JKXHK:9H\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\UGJ\JKaMLeOLhPLkRLmSMoTMpUMrVMvWNyYN|ZN]O`OcPePhQjQlRnRpSqSsStSuStSsSmR^/ vTvTvTwTwTwTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTwTwTwTwTwTwTwTxTxTxTxTxTxTxTyTyTzUzU{U{V|VgQrSwTxTyUyUzVyVxVvUtTqSoSmRjQhQePcPbP`O_O]O}[NyYNuWMpUMoTMmSMkRL}H#\\ &D -E(1F/!2#8 W7"iA&UGJ[JK\JKREJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\MCIXIK^KKcNLfOLiQLkRMmSMoTMqUMsVMwXNzYN}[N\O^O`ObPePgQjQkRmRoRqSrStSuSvTvTwTwTuTsSlR_(yTyTyTyTyTyTyTyTyTyTxTxTxTxTxTxTyTyTyTyTyTyTyTyTyTyTyTyTyTyTyTzTzTzU{U{U{U|U|U}V~VWYiQrSwTyTzU|V}XZ]]]~[zYwWtUqSnSlRjQgQfPePcPbP`O_O]O~\NzZNvXNqUMoTMnSMlRMiQLg=!\ -!C+E'0F.4F7%8%U/lG.SFJZIK]KKZIKB=H\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\REJZJK`LKdNLgPLjQLlRMnSMpTMqUMtWMxXN{ZN~[N]O^O`OaObPdPgQiQkQlRnRpSrSsStTuTvTwTxTyTyTyTyTyTxTvTrSnRhQ|U|U|U|U|U|U|U|U|U|U|U|U|U|U}U}U}U}U}U}U}U~U~U~V~VVWXa(lRrSvTyTzU|U~VX[_djmnlhd_{[vWsUpSnRkRiQhQgQfQePdPbPaO_O^O\O|ZNxXNsVMpTMnTMmSMjQLC B)D&/F-3F47G6%>" Y7 kA$YIK]KK^KKSFJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\VGJ\KKbMLeOLhPLkRLmSMnTMpTMrUMuWNyYN|ZN\N]O_O`OaPbPcPePfPhQjQlRnRoSqTsTuUvUwVxVyVyUzUzU{U{U{U|U|U|U|U|U{U{U{UzUzTyTyTxTwTvTvTvTvTwTwTwTxTyTzTzU{U{U|U|U}UVWY\_dlu脾|讒鍖遶覈网{sld^yZuWqUoSlRkRjQiQhQgQfQePdPcPaP`O^O]O}[NyYNuWMpTMoTMmSMkRLgPL&D#.E,3F46G;'<(D"iB(VGJ]KK`LK[JKB>H\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\NCJYIK^LKcNLfOLiQLkRMmSMoTMqUMsVMvXNzYN}[N\O^O_O`OaPcPdPePfQgQhQiQkRmSoTrUtWwYzZ}\]^^^^\ZYX~W~W~V~V~V~V~U~U~U~UUUVVVVVVVWWXZ[^adint茖z遘鶩餘薊燹~vmf`z[vXrUpToSnSlRkRkRjQiQhQfQePdPcPbP`O_O]O~[NzYNvWNpTMoTMnSMkRMhQLo7 ,2F36G99HC+@ ]8 nA"\JK`ML_LKSFJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SFJ[JK`LKdNLgPLjQLlRMnSMpTMqUMtVMwXNzZN}[N]O^O_OaObPcPdPePfQgQhQiQjRlRmSoUrWvZ{]afjnqssrqomjgca^\[YXWWWVVWWWXY[\_aehmqv筺z腓}螂覃覈薑絅|wrmhc~^yZvXtWsVqUpToSnSmRlRkRjQiQhQgQfPePcPbPaO_O^O\N{ZNwXNsVMoTMnSMlRMiQL~I#26G99G?IQ2P+XHK_LLfQOcNLXIK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\制qSyT~V`鍮v]qSLG|> g3 -S)?*%.hQhQeP`OuWM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\SFJ[JK`LKdNLgPLjQLlRMnSMoTMqUMsVMwXNzYN}[N\O^O_O`OaPbPdPePfPgQhQiQjRkRlSnTpVsXvZz^bgmsz泙礬茘蟄鰢鬠茗紲爐|wqlgb_\}Z{XzWyVyUxUxUxTxTxUxUxUyVyVyWzW{X{Y|Z}[}[}\~\~]~]}]|\{\z[yZwYvXtWsVrUpToSnSmRlRkRjQiQhQgQfQePdPcPbP`O_O]O~[NzZNvWNrUMoTMmSMlRMiQLeOLJAIJ(h>!]KKfQOgQN_LKD>I\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\iQtSyT{UYe鎰u|\Z'LD -|> ePoRqSoRmRjQeP^OhPL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\WHJ\KKaMLeOLhPLjQLlRMnSMpTMqUMtVMwXNzZN}[N]O^O_O`ObPcPdPePfQgQhQiQjRkRmSnTqVsXw[{_chntz泪礬膈蟄蟄螫腴筵滷|vpkfb_\}Y{XzWyVxUxUxTxTxTxUxUxUxUyVyVzWzX{Y|Y|Z}[}[}\}\}\}\|\{[zZyZwYvXtWsVrUpToSnSmRlRkRjQiQhQgQfQePdPcPbP`O_O^O\N{ZNwXNsVMoTMnSMlRMiQLfOLJ(V.]KKePNkUQcNLQEJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\]OmRqSrStSvTwTxU{Wbqxo -KrSvTwTvTuTsSqSnRkQgQ`OuWNY,\\\\\\\\\\\\\\\\\\\\\\\\\\NCJYIK^KKbNLfOLhQLkRLmSMoTMpUMrUMuWMxXN{ZN~[N]O^O_OaObPcPdPePfQgQhQiQjRkRmSoTqVtXw[|_dintz泪礬膃藪螫薛罟礑漓{upjfb^\|Y{XzVyVxUxUxTxTxTxUxUxUxUyVyVyWzW{X{Y|Z|Z|[}[}\}\|\|[{[zZxYwXvXtWsVrUpToSnSmRlRkRjQjQiQhQgQfPdPcPbPaO_O^O\O|ZNxXNtVMoTMnSMlRMjQLgPLzG#\JKcOMoXUgPMZIK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\fPgQgQhQiQkQlRnRpRqSsStS:"r<zYNsSyT|U~W^egeaz[tVpSmRkQgQbPzYNkRL\\\\\\\\\\\\\\\\\\\\\\\\\RFJZJK`LKcNLfPLiQLkRMmSMoTMqUMrVMvWNyYN|ZN\N]O^O`OaObPcPdPePfQgQhQiQjRlRmSoUqVtYx\|`diou{泪礬膃藪藪茗紿皃沺ztojea^~[|Y{XzVyVxUxUxTxTxTxTxUxUxUxVyVyWzWzX{Y{Y|Z|Z|[|[|[|[{[z[yZxYwXvWtWsVrUpToSnSmRlRkRkRjQiQhQgQfPePdPbPaP`O^O]O}[NyYNuWNqUMnSMlSMkRLhPLcNLbNLpYVlUP`LK>;H\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\jQ`O{ZN^'^'`(e)h)k*o+b(nRyT~UXdw魄餔荅}vme}_x[y\x[tWqTmRjQgQbP}[NlRM\\\\\\\\\\\\\\\\\\\\\\\\VGJ\JKaMKdNLgPLjQLlRMnSMpTMqUMsVMvXNzYN|[N\O]O_O`OaPbPcPdPePfQgQhQiQjRlSmSoUrWuYx\|`djou{泪礬罨茘茘腴紿瓮~ytojea^~[|Y{WzVyVxUxUxTxTxTxTxUxUxUxUxVyVyWzXzX{Y{Z{Z|Z|[|[{[{[zZyZxYwXuWtVsVrUpToSnSmRlRkRkRjQiQhQgQfQePdPcPaP`O^O]O~[NzYNvWNrUMnSMmSMkRLiQLeOLoXUu]XdOLKBI\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\:9H\NhQ}\uUsTtTtSqSnRnRnRlRjQiQhQhQgQfQePePhQkRmSpUtXuYsWqUmSjQgQBS%jQL\\\\\\\\\\\\\\\\\\\\\\LBIXHK^KKbMLeOLhPLjRLlSMnSMpTMqUMtVMwXNzYN}[N\O^O_O`OaPbPcPePfPfQgQhQiRkRlSnTpUrWuYy]}`ejpv{泙皋罠膃膃罠筥爐~xsniea^~[|Y{WyVyVxUxUxTwTwTwTxTxUxUxUxVyVyWzWzXzY{Y{Z{Z{Z{Z{ZzZyZyYxYvXuWtVsUrUpToSnSmRlRlRkRjQiQhQgQfQePdPcPaP`O_O]O\N{ZNwXNsVMnSMmSMkRMiQLfOL_LKhQMUGJ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ (6BFP>=DKHMqjktrwf`~kcndqesete{w`v[\N_OcPfPiQjRlSoTqVqVoTlRiQ^`OQ%hPL\\\\\\\\\\\\\\\\\\\\\QEJZIK_LKcNLfOLiQLkRLmSMoTMpUMrUMuWMxXN{ZN~[N]O^O_O`OaPcPdPePfPgQhQiQjRkRlSnTpUrWuZy]}aekpv{泙皋紵罠罠紿皃滷}xrmida]~[|YzWyVyUxUxUwTwTwTwTwTxUxUxUxUxVyVyWzXzXzYzY{Y{Z{ZzZzZyYxYwXvXuWtVsUrUpToSnSmSmRlRkRjQiQhQgQfQePdPcPbP`O_O]O\O|ZNxXNtVMoTMmSMlRMjQLgPLbML[JK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\%5 (6$/79CEEKjgkrc_{uf{w_q]O`OcPfQhQjRlRnToTnTkRhQdP]'Q%\\\\\\\\\\\\\\\\\\\\\UGJ[JK`MKdNLgPLiQLkRMmSMoTMqUMrUMuWNxXN{ZN~[N]O^O_O`ObPcPdP['d)gQhQiQjRkRlSnTpUrWvZy]~afkpv{櫃瓰筴紵紵筥瓮沺|wrmhd`]}[|YzWyVxUxUxUwTwTwTwTwTwUwUxUxUxVxVyWyWyXzXzYzYzYzYzYyYyYxYwXvWuWtVsUqUpToSnSmSmRlRkRjQiQhQgQfQePdPcPbPaO_O^O\O|[NxYNtWMpUMmSMlRMjQLgPLcNLA;=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\#*6+.8;:AHEJmgjd\]pe}xcw^p^OaPePgQiQlRmSnTmSjRgQh*X&M$\\\\\\\\\\\\\\\\\\\C+WHJ]KKaMLdOLgPLjQLlRMnSMoTMqUMrVMvWNyYN|ZN\N]O^O_OaObPcPY&_(c(gQhQiQjRkRlSnTpVsXvZz^~bfkpv{檻爨礬筴筴皈爐{vqlgc`]}Z{YzWyVxUxUwUwTwTwTwTwTwTwUwUxUxVxVxVyWyWyXyXyYzYyYyYyYxYwXwXvWuVtVrUqUpToSnSmSmRlRkRjQiQhQgQfQePdPcPbPaO_O^O\O}[NyYNuWNqUMmSMlRMjQLhPLdNL\1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\+.775;ICFphhztre}yavZ]OaPePgQiQkRlSnTlSiQq.b*S%zG#\\\\\\\\\\\\\\\\\\MCJXHK^KKbMLeOLhPLjRLlSMnSMpTMqUMsVMvWNyYN|ZN\N]O^O`OaObPU&\'a(g)r/hQiQjRkRmSnTpVsXv[z^~bfkpv{棕爨皋礙礙瓲泯~yupkgc_]}Z{XzWyVxUxUwTwTwTwTwTwTwTwUwUwUxUxVxVxWyWyWyXyXyXyYyYxXxXwXvWuWtVsVrUqTpToSnSmRmRlRkRjQiQhQgQfQePdPcPbPaO`O^O]O}[NzYNvWNrUMmSMlRMjQLhQLeOL_LK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\,)/ZTVXONuqod}ybs]OaPePgQiQkRlRlSkRhQg*\(Q%`LK\\\\\\\\\\\\\\\\\ B B_LKcNLfOLiQLkRLmSMoTMpTMrUMtVMwXNzYN}[N\O]O_O`OaOQ%Y&^'b(i*{8hQiQjRkRmSnTqVsXv[z^~bfkpv{暸潺瓰皈瓲爐蘗}xtojfb_\}Z{XzWyVxUxUwTwTwTwTwTwTwTwTwUwUwUxVxVxVxWxWyWyXyXxXxXxXwXwWvWuWtVsUrUqTpToSnSmRmRlRkRjQiQhQgQgQfPdPcPbPaP`O^O]O~[N{ZNvXNrVMnSMlRMjRLhQLeOLaML+O+O\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\HFLXQRTJH~pmla}zcttTaPdPgQiQjRlRlSjR|:e*V&N$\\\\\\\\\\\\\\\\\ B B`LKdNLgPLiQLkRMmSMoTMpUMrUMtVMwXNzYN}[N\O]O_O`OaPW&['_(d)l,@t.iQjRkRmSoUqVsXw[z^bgkpuz~據泙爛爨爛泯{wsnjfb_~\|Z{XyWyVxUwUwTwTwTwTwTwTwTwTwUwUwUwUwVxVxVxWxWxWxWxXxXwXwWvWuWuVtVsUrUqTpToSnSmRlRlRkRjQiQhQhQgQfPdPcPbPaP`O^O]O~[N{ZNwXNsVMoTMlRMjRLiQLfOLbML+O+O+O+O\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\6./fZXeVRHAIZIKiQLuWMtUaOdPgQjQkRlRkRiQn/b,R%rC"\\\\\\\\\\\\"Fx"Fx!Fx!Fx B B BdNLgPLjQLlRMmSMoTMqUMrUMtWMwXNzZN}[N\O^O_O`OS%X&\'a(g+s2{9j*iQjRkSmSoUqVsXw[z^bgkpuy}棧泙澆泯檗~zvrmiea^~\|ZzXyWxVxUwUwTwTwTwTwTwTwTwTwTwUwUwUwUwVwVxVxWxWwWwWwWwWvWvWuVtVsUsUrTqTpToSnSmRlRlRkRjQiQhQgQgQfPePcPbPaP`O_O]O~\N{ZNxXNsVMoTMlRMjRLiQLfPLbNL +O+O+P+P+P\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\@89dWT@IIAI\JKlRMyYN^OcPgQiQkRlRkRiRt3d-S%I#\\\:^:^:^:^:^:^:^:^:^"Fx"Fx B B B BeOLhPLjRLlSMnSMpTMqUMrVMuWMxXN{ZN~[N]O^O_OS%W&['^(k2i+{:gQhQiQjRkSmToUqVtYw[{_bfkotx|~曄曄~{wsokgc`]}[{YzXyVxVwUwUwTwTvTvTvTvTvTvTvTvTvUvUvUwUwUwVwVwVwVvVvVvVuVuVtVtUsUrUqTpTpSoSnSmRlRlRkRjQiQhQgQgQfPePdPbPaP`O_O]O\N|ZNxYNtWMpTMlRMjRLiQLgPLcNL_LK+P+P+P,P,P,P,P,PNr\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\]QNl\VG@IMCI_LKoTM|ZN`OdPgQjQkRlRkRhQh*^,P%X3:_:_:_:_:_:_:_:_:^:^:^:^"Fx B B B BfOLiQLkRLmSMnTMpTMqUMrVMuWNxYN{ZN~[N]O^OP%U&X&['`)n4n/j*gQhQiQjRkSmToUqWtYw[z^~bfjosw{}~|yvrnjfc`]}[{YzWxVxUwUwTwTvTvTvTvTvTvTvTvTvTvTvUvUvUvUvUvVvVvVvVvVuVuVuVtUsUrUrTqTpToSoSnSmRlRkRkRjQiQhQgQgQfPePdPbPaP`O_O]O\N|ZNyYNuWMpUMlRMjQLiQLgPLdNL_LK,P,P,P,P,PNrNrNrNrNrNr\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aSOD>IJAIQEJbNLrUM~[NaOePhQjQkRlRjRs0e,T&K$;_;_;_;_;_;_;_:_:_:_:_:_:_ B B B BgPLiQLkRLmSMoTMpTMqUMsVMuWNxYN{ZN~[N]OM$S%V&Y&\'e-j/z:fQgQhQiRjRkSmToUqWtYw[z^~bfjnrvy|~~~}{xtqmieb_~\|Z{YyWxVxUwUwTvTvTvTvTvTvTvTvTvTvTvTvTvUvUvUvUvUvUvVvVuVuVuVtUsUsUrUqTqTpSoSnSnRmRlRkRkRjQiQhQgQgQfPePdPbPaP`O_O]O\O|ZNyYNuWMqUMlSMjQLhQLfPLdNL_LK,P,PNrNrNrNrNrNrNrNsNsNsNs\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\dUOG@IMCITFJeOLtWM]ObPfPiQkRlRkRiQj,c/P%[JK;_;_;_;_;_;_;_;_;_;_;_;_ B B B BgPLiQLkRMmSMoTMpTMqUMsVMvWNyYN{ZN~[N|H#Q%T%W&Z']'m5f*v5fQgQhQiRjRkSmToUqWsYv[z^~beinquxz|}|{yvsolhea_~\|ZzXyWxVwUwUvTvTvTvTvTvTvTvTvTvTvTvTvTvTvUvUvUuUuUuUuUuUtUtUtUsUrUrTqTpTpSoSnSmRmRlRkRjRjQiQhQgQfQfPePcPbPaP`O_O^O\O|ZNyYNuWNqUMmSMjQLhQLfPLdNL`LKNrNrNrNrNrNsNsNsNsOsOsOsOsOsOs\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\2#TB3REJVGJ`LKpTM}[NaOePiQkRlRlRhQe)^.P%^8 #Gy#Gy#Gy#Gy#Gy#Gy#Gy#Gy * B B B B BjQLlRMnSMoTMpUMrUMsVMxF#M$Q%S%U&W&Y&['a+s;g+dPePfQgQhQiQjRkSlSnUpVrXuZx]{_~beiknprssrqomkheb`~^|[{ZyXxWwVvUvUvTuTuTuTuTuTuTuTuTuTuTtTtTtTtTtTtTtTtTsTsTsTsTrTrTrTqTqSpSpSoSnSnRmRlRlRkRjQjQiQhQgQgQfPePdPcPbPaO`O^O]O\N|ZNxXNuWMqUMmSMhPLgPLeOLcNL`LKZIK,P,P,QOsOsOtOtOtOtPtPtPtPtPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\vvvvvvvww=a=a=a#Gy#Gy#Gy#Gy#Gy#Gy#Gy#GymYPODJUGJXIKeOLtWM]OcPgQjQlRmRkRp.g0T&N$]8 #Gy#Gy#Gy#Gy#Gy#Gy#Gy * B B B B BjQLlRMnSMoTMpUMrUMv>L$P%R%T%V&X&Z'\'f0m5q3dPePfQgQgQhQjRkSlSnTpVrXtZw\z_}adgjlnpqqpomkigda_}]|[zYyXxWwVvUvUuTuTuTuTuTuTuSuStStStStStTtTtTtTtTsTsTsTsTsTrTrTrTqTqSpSpSoSoSnSmRmRlRlRkRjQjQiQhQgQfQfPePdPcPbPaO`O^O]O~\N{ZNxXNuWMqUMiQLgPLfOLeOLbNL_LKZIK,Q,Q,Q,Q,QOtPtPtPtPtPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\vvvvwwwwwwww=a=a=a=a=a#Gz#Gz#Gz#Gz#Gz#Gz#GzgUOS=2RFJWHJ[JKlRMzYN`OePiQkRmRlRiQh*h4R%N$^9 [JK#Gy#Gy#Gy#Gy#Gy * B B B B BjQLlRMnSMoTMpUMI#L$O$Q%S%U&W&X&Z'](l5f,t5dPePfPfQgQhQiRkRlSmToVqWtYv[y^|acfhklnnonmkigec`~^|\{ZyYxWwVvUvUuTuTuTuTuTtStStStStStStStStStStSsSsTsTsTsTrTrTrTrSqSqSpSpSoSoSnSnRmRmRlRkRkRjQiQiQhQgQfQePePdPcPbP`O_O^O]O~[N{ZNxXNtVMqUMhPLgPLfOLdNLbML_LKbE6,Q,Q,Q,Q-Q-Q-QPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\@dwwwwwwwwwwwwww=a=a=a=a=a=a=a#Hz#Gz#Gz#Gz#Gz#Gz#GzmYPPDJUGJYIKbMLqUM\NbPfQjQlRmRlRp,e+\+R%N$b; ]8 [7 XHKO+N1L/L/L/K/K/ eb>b>b>b>b>b>b>b=b=b=b=b=b=b=b=bYEUGJYIK_LKnSM|ZN`OePiQlRmRmRiQg*j4W'R%Q%h>!g=!f=!db>b>b>b>b>b>b$Hz$Hz$Hz$Hz$Hz>b>b>b>b>bgVOS=2RFJWHK[JKeOLsVM]ObPgQjQlRmRlRr/g*h2U&S%R%Q%Q%P%[']'`(b(d)f)g)i*j*I#Z'Z'Z'Z'Z'['['\']'_)d,d)q3bPcPdPePfQfQgQhQiRkSlSmUoVqWsYu[x]z^|`~bdeffffedba~_}^{\zZyYwXwWvVuUuUtTtTtTtStStSsSsSsSsSsSsSsSsSsSsSrSrSrSrSrSqSqSqSpSpSpSoSoSoRnRnRmRmRlRkRkRjQjQiQhQhQgQfQePdPcPcPbP`O_O^O]O\N|ZNyYNuWNrUMnSMjQLdNLcNLaMK_LK[JK`D6PtPtPtPtPtPuPuPuPuQuQuQuQuQuQu-Q-Q-Q-R-R-R-R-R-R-R-R-R.R.RRvRvRv~~~~\\\\\\\\\\\\\\\\\\\\\\\\\\\@e@e@e@eAeAeAeAeAeAeAeAeAeAeAexxxxxxxyy>b>b>b$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>b>b>b>b>bYDb>b>b>bQ@:R<2fL@WHJZJKaMKoTM|ZN`OePiQlRmRmRjRo-i-h0`)]']'`(b(d)f)h)j*k*m*n+p+q+r,]']']'^'_(_(`(`(b)c)i.`OaPbPcPdPePfQgQhQiRjRkSlTnUoVqWsYuZw\y]{_|`}a~bbbba~`}_|^{]z[yZxYwXvWuVuUtUtTtTsTsSsSsSsSsSsSsSsSsSrSrSrSrSrSrSrSqSqSqSqSpSpSpSoSoRoRnRnRmRmRlRlRkRkRjQjQiQhQhQgQfQePdPdPcPbPaO`O_O]O\O}[NzYNwXNtVMpTMlRMhPLcNLaMK_LK]KKbR]C5PuPuPuQuQuQuQuQuQuQuQuQuQuQuQuQuQvQvQv-R-R.R.R.RRvRvRvRvRvRvRvUUUUUUUUUU\\\\\\\\\\\\\\\\\\\\\\AeAeAeAeAeAeAeAeAeAeAeAeAeAeAeAeAeyyyAfAfAf$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>b>b>b>bWD3TFJXHK[JKfOLsVM]ObPgQjQlRmRmRkRm,i,j/d+c)c(e)f)h*j*l*n+o+q+r+s,t,K$^(_(_(`(a(a)b)d*f+m1`OaPbPcPdPePfQfQgQhRiRkSlTmToVpWrXtYv[w\y]z^{_|`}`}`}`}_|^{^{\z[yZxYwXvWuVtUtUtTsTsTsSsSsSsSsSrSrSrSrSrSrSrSrSrSrSqSqSqSqSqSpSpSpSoSoRoRnRnRmRmRmRlRlRkRjQjQiQiQhQgQfQfPePdPcPbPaP`O_O^O]O\N|ZNyYNvWNsVMoTMkRLgPLbML`LK^KK\JK~aR[B5PuQuQuQuQuQuQuQuQuQuQuQuQuQuQvQvQvRvRvRvRvRvRvRvRvRvRvRvRvRvUUUUUUUUUUUUU\\\\\\\\\\\\\\\\\\\\AeAeAeAeAeAeAeAeAeAeAeAeAeAfAfAfyAfAfAfAfAfBf$H{$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>c>c>b>bO?:[E|aRZA5-QQuQuQuQuQuQuQuQuQuQuQvQvQvQvRvRvRvRv.R.R.R.RRvRvRvRvRvRwVVVVVVVVVVVVVVVV\\\\\\\\\\\\\\\\\\AeAeAeAeAeAeAeAfAfAfAfAfyyyzzzBfBfBfBfBf$H{$H{$H{$H{$H{$H{$H{$H{$H{$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>c>c>c>cVC^C6W@5-Q-QQuQuQuQuQuQuQvQvQvQvRvRvRvRv.R.R.R.R.R.R.R.R.RRvRwRwRwぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶ\\\\\\\\\\\\\\\\AfAfAfAfAfAfAfAfzzzzzzzzzzzBfBfBfBf$I{$I{$I{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$Hz$Hz$Hz$Hz$Hz YE\C6T>4-Q-Q-Q-RQuQuQvQvQvQvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.RRwSwぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶEiEiEi\\\\\\\\\\\\\\AfAfBfBfBfzzzzzzzzzzzzzzzBfBfBf$I{$I{$I{$I{$I{$I{$I{$I{$I{$I{$I{$H{$H{$H{$H{?c?c?c?c$H{$H{$H{SB;R<2zbVUGJXIK[JK[JKuWN\OaPfPiQlRmRnSnSpT99w2w0v/v.x/z0z0|1~235688m4o7q8u;s9s8j0]O^O_O`OaPbPcPdPePfQfQgQhRiRjSkSlTnUoVpVqWrXsYtYuYuZuZvZvYuYuXuXtWtVsVsUsUrTrTrTrSqSqSqSqSqSqSqSqSqSqSqSqSqSqSpSpSpSpRpRoRoRoRoRnRnRnRmRmRmRlRlRkRkRjQjQiQiQhQgQgQfQePePdPcPbPaP`O_O^O]O\O}[NzYNwXNtVMqUMnSMiQLeOL`LK]KKmP?kN?|aSZA5P<4-R-R-R-R-R-RQvRvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.RぷぷぷぷぷぷぷぷぷぷぷぷぷぷぷぷEiEiEiEiEiEiEi\\\\\\\\\\\\Bfzzzzzzzzzzzzz{{{{{{BfBfBf%I{$I{$I{$I{$I{$I{$I{$I{$I{$I{$I{?c?c?c?c?c?c?c?c?c$H{$H{$H{jXP^H=}dXUGJXHKZIKkRLwXN]ObPfQiQkRmRnSpTqUrU;>?<9;==>ADHKEr:t;t;t`KA-R-R-R.R.R.R.RRvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.REiEiEiEiEiEiプププププププEiEiEiEiEiEiEiEiEiEiEiEiEiEiEiEi\\\\\\\\zz{{{{{{{{{{{{{{{{{{{|CgCg%I{%I{%I{@d@d@d@d@d@d@d@d@d@d@d@d?d?d?d?d?d?d$I{$I{dUPYEXG@-R.R.R.RRvRvRvRvRvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.R.R.SEiEiEiEjEjEjEjEjプププEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEiEiEi\\\\\\{{{{{{{{{{{{{{|||||||||Cg@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d?d$I{$I{RA;P<3zcXnVIuh~pdNLpUMwzZvSePgQjQlRmRoSpTuVvWxY|\_dghiklRFk4g1d-b+_(Z'}[N\O]O^O_O`OaPbPcPcPdPeQfQgQgQhRiRjRkSkSlTmTnTnUoUoUpUpUpUpUpUpTpTpTpTpSpSoSoSoSoSoSoSoRoRoRoRoRoRoRoRoRoRoRoRoRnRnRnRnRnRmRmRmRlRlRlRkRkRkQjQjQiQiQhQhQgQgQfPePePdPcPbPbPaO`O_O^O]O~\N|[NzYNwXNtVMpUMpYoXzWBuUBgVlP@jO@|bUx`TcMB3!.RRvRvRvRvRvRvRvRvRvRvRwRwRw.R.R.R.R.R.R.R.R.R.S.S.SEjEjEjEjEjEjEjEjEjωωEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEj\\\\Bg{{{{{{{||||||||||||CgCgCgCg|〉@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d%I{;0/SB;R=4fODpXLxkrvbzx{[ldPgQiQjQlRnRpSqTrTtUwW{Z}\|\}\~]]}+~6d.a+_)^(\'zYN|ZN~\N]O^O_O_O`OaPbPcPdPdPeQfQgQgQhRiRjRjSkSlSlTmTmTnTnTnToToToToToToSoSoSoSoSoSoSoRoRoRoRoRoRoRoRoRoRoRoRnRnRnRnRnRnRmRmRmRmRlRlRlRlRkRkQjQjQjQiQiQhQhQgQgQfQePePdPcPbPbPaO`O_O^O]O\N}[NzZNxXNuWMrUMrZpY|XCxVCsTBmQAkOA~cVzaU`I>\IARvRvRvRvRvRvRvRvRvRvRwRwRwSwSwSwSw.R.R.R.R.R.S.S.S.SFjFjFjFjFjFjFjFjωωωωωωFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFj\\Bg{||||||||||||||CgCgCgCgCgCgCgCg}〉@e@e@e@e@e@e@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d%I{<1/J82^I@gQFqYNxlsvc{dy{\wUiePgQhQkQmRmRnRoSpSrTtUtUtUtUtUtUt.L&](['Z'Y&xYN{ZN}[N\N]O^O_O`OaOaPbPcPdPePeQfQgQgQhRiRiRjRkSkSlSlSmSmSmSnSnSnSnSnSnSnSnSnSnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRmRmRmRmRmRlRlRlRlRkRkRkQjQjQiQiQiQhQhQgQfQfPePePdPcPbPbPaO`O_O^O]O\O}[N{ZNxYNvWNsVMs[rZ~ZDnYkYqSBkPAiOA|cVbK?\G>NB?RvRvRvRvRvRvRvRvRwRwRwSwSwSwSwSwSwSwSw.S.S.S.S.S.SFjFjFjFjFjFjωωωωωωωωωωωFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjCgCg||||||||||〉|〉CgCgCgCgCgCgCgCgCgCgCgCg}〉AeAeAe@e@e@e@e@e@e@e@e@d@d@d@d@d@d@d@d@d@d%I{@d@d<1/H72\I@ePGpYNxmtvc{ezupwUuQePgQiQjQjQlRmRnRnRoRoRoRoRoRgb; Z'Y&W&S%vXNyYN{ZN~[N\O]O^O_O`OaOaPbPcPdPdPeQfQgQgQhQiRiRjRjRkSkSlSlSlSlSmSmSmSmSmSmRmRmRmRmRmRnRnRnRnRnRnRnRnRnRnRmRmRmRmRmRmRmRmRlRlRlRlRkRkRkQjQjQjQiQiQhQhQgQgQfQfPePdPdPcPbPbPaO`O_O^O]O\O}[N{ZNyYNvXNtVMu\]E[EoZmZkYnRBjOB}cVdL@`I?XGARvRvRvRvRvRvRwRwRwRwSwSwSwSwSwSwSwSwSwSwSw.S.S.S.S/SFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjCgCg|||〉|〉|〉|〉|〉CgCgCgCgCgCgCgCgCgCgCgCgChChChChCh}AeAeAeAeAeAeAeAeAe@e@e@e@e@e@e@e@d%I{%I{%I{%I{%I{@d@d<10F61o]Vye]oexmuud{e}d|atpluQdPePfQgQiQjQjQjQjQjQkQkQkQ_9 X&V&T%rUMuWMwXNzYN|ZN~[N\O]O^O_O`OaObPbPcPdPdPeQfQfQgQhQhRiRiRjRjRkRkRkRlRlRlRlRlRlRlRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRlRlRlRlRlRkRkRkRkQjQjQjQiQiQiQhQhQgQgQfQfPePdPdPcPbPbPaO`O_O^O]O\O~[N{ZNyYNwXNtVMrUM^F]Fq\o[lZqTDfX}dWeMAbK@O=6NB@RvRvRvRvRwRwRwRwSwSwSwSwSwSwSwSwSwSwSwSwSxSxSx/S/SFjFjFjзззззззззззззззззззFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjззззCgCgCg}〉}〉}〉CgCgCgCgCgCgCgCgChChChChChChChChChChDhDhDh~AeAeAeAeAeAeAeAeAeAeAeAeAe%I{%I{%I{%I{%I{%I{%I{%I{%I{@d@dE:9D61m\Vwe]lXOuaXk_z||e|c|`z]yXnlkidPePfPfPfPfPfPfPfP[7 U&T%P%pTMsVMuWMxXNzYN|ZN~[N\O]O^O_O`OaObPbPcPdPdPePeQfQgQgQhQhQiRiRjRjRjRkRkRkRkRkRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRkRkRkRkQkQjQjQjQiQiQiQhQhQgQgQfQfPePePdPdPcPbPbPaO`O_O^O]O\O~[N|ZNyYNwXNuWMrUM`G^Gr]|ZFxXFtVEgY~eY{cXbLA[H?REA.R.RRvRwRwRwSwSwSwSwSwSwSwSwSwSwSwSwSxSxSxSxTxTxTxзззззззззззззззззззззззззFjFjFjFjFjFjFjFjFjFjFjззззззCgCg}〉}〉CgCgCgCgChChChChChChChChChDhDhDhDhDhDhDhDhDhDh~AeAeAeAeAeAeAeAeAe%I|%I|%I|%I{%I{%I{%I{%I{%I{%I{%I{%I{%I{%I{@e@eB99B51k[Vud]iWPr_Wye]y|}|e|cw{^z\yZpxWwUwUwUwUllllkD(S%P%nSMoTMqUMsVMvWNxXNzYN|ZN~[N\O]O^O_O`OaOaPbPcPcPdPePeQfQfQgQgQhQhQiQiRiRjRjRjRjRkRkRkRkRkRkRkRlRlRlRlRlRlRlRlRlRlRlRlRkRkRkRkRkQkQkQjQjQjQjQiQiQiQhQhQgQgQgQfQfPePePdPcPcPbPaPaO`O_O^O]O\O~[N|ZNyYNwXNuWMrUMw_v_t^~\GzYGvWFj[fZ|dYybX\I@VGB5/2.R.R.R.RSwSwSwSwSwSwSwSwSwSwSwSwSxSxSxSxTxTxTxTxFkFkFkFkиииииииииииииииииииииииFkFkFkFkFkFkFkFkииииииии}〉}〉}《}《ChChChChChChChDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDh~UAeAeAeAeAe%J|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I{%I{%I{%I{%I{%I{@e@e<68?31gYVpa\bRMjYTq`Zj`z}}|{zxwz^tsssrrrrh2O$L$mSMnSMnTMoTMtVMvWNxXNzYN|ZN~[N\O]O^O_O`OaOaPbPcPcPdPdPePeQfQfQgQgQhQhQhQiQiQiQiQjQjQjQjQjQkQkQkQkRkRkRkRkRkRkRkRkRkQkQkQkQjQjQjQjQjQjQiQiQiQhQhQhQgQgQgQfQfPePePdPdPcPbPbPaP`O`O_O^O]O\O~[N|ZNyYNwXNtWMz`y`w`u_]I|[HwXGl\i[}eZycYr_WjZU;23.R.R.R.R.R.R.RSwSwSwSwSwSwSwSwSxSxSxTxTxTxTx/S/SGkGkGkGkGkGkGkGkGkGk}}}}~DhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhUAf%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I{%I{AeAeAe?89H=:?YUY`QGfVLudXjeitlm{po|qp}rp~rpsqsqtqr_=1+xJ)o[~[F\G^H_I`IkRLlRMnSMpTMrVMuWMwXNyYN{ZN}[N~\N\O]O^O_O_O`O`OaPbPbPcPcPcPdPdPePePePfPfQfQfQgQgQgQgQgQgQgQhQhQhQhQhQhQhQhQhQgQgQgQgQgQgQfQfQfQfPePePePdPdPdPcPcPbPbPaPaO`O_O_O^O]O\O~\N}[N{ZNyYNwXNuWMiOhOgOeOzeydwdtcrbtYKjTIaOG[KFj]Y^UU?;@.R.R.S.S.S.S.S.S/S/S/S/S/S/S/S/S/S/S/S/S/S/S/SGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGlGlGlGlGlGlGlGlGlGlGlGlGlUUUUUUUUDhDhDhDhDiDiDiDiDiぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶEiEi&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|AfAeAe%J|%J|%J|%I|%I|%I|%I|#-#%.()1MEAQIEUMI]SL]TM=4.1+(=.#6,&5( 1%"lYn[p\r]]H_I`JwaybkRLmSMpTMrUMtVMvWNxXNzYN|ZN}[N\N]O]O^O_O_O`OaOaPaPbPbPcPcPdPdPdPePePePePfPfPfQfQfQfQfQgQgQgQgQgQgQgQgQfQfQfQfQfQfPfPePePePePdPdPdPcPcPcPbPbPaPaO`O_O_O^O]O]O\O}[N|ZNzYNxXNvWNggghPfP|fzfxevdscsYLiTK_NHYKFh\Z]UV=;@.R.S.S.S.S.S.S/S/S/S/S/S/S/STxTxTxTxTx/S/S/S/SGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlUUUUUUVVDiDiDiDiDiDiぶぶぶぶぶぶぶぶぶぶぶぶぶぶぶぷぷぷぷEi&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|BfBfAfAfAfAfAf%J|%J|%J|%J|%J|%J|%I|%I|%I|, -+,!.! "`E6iYlZo\q]s^^Jvawbyczd{e}foTMqUMsVMuWNwXNyYN{ZN|ZN~[N\O]O]O^O_O_O`O`OaOaPbPbPcPcPcPdPdPdPdPePePePePePePePePfPfPfPfPfPfPfPePePePePePePePdPdPdPdPcPcPcPbPbPaPaO`O`O_O_O^O]O]O\O~[N|[N{ZNyYNwXNiiiihhRfQdQbPwfx]Opdkbtd_m`]OEDG?A;:@.S.S.S.S.S/S/S/S/S/S/S/S/STxTxTxTxTxTxTxTxTy/SGlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlVVVVぶぶぶぶぶEiぶぶぶぶぶぶぶぶぶぶぶぶぷぷぷぷプププBgBgBgBgBg&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|BfBfBfBfBfBfBfBfBfAfAf%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|%I| -+,YA5jPBpSDl[o]q^t`_Kwbycze{f}ghilSrVMtWMvWNxXNyYN{ZN|[N~[N\O]O]O^O_O_O`O`O`OaPaPbPbPbPcPcPcPcPdPdPdPdPdPdPdPdPePePePePePdPdPdPdPdPdPdPcPcPcPcPbPbPbPaPaO`O`O`O_O^O^O]O]O\O~[N|[N{ZNyYNxXNjjjjjjhSgSeRcR|`Qsfoe}jcrd`k_]LCDC=@,,3(4F(4F.S.S/S/S/S/S/S/S/STxTxTxTxTxTxTxTxTxTyTyTyHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlChChぶぶぶぶぶEiEiEiぶぶぶぶぶぶぷぷぷぷCgCgCgCgCgCgCgCgCgCgCgCgBgBg&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|BfBfBfBfBfBfBfBfBfBfBfBfBfBfBf&J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|#5H71O;3V?4iOBoSDsVFo]{[I^K`LbNdO{f}g~hjkTmUoVqWrWwXNxXNzYN{ZN}[N~[N\O]O]O^O^O_O_O`O`O`OaOaPaPbPbPbPbPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPbPbPbPbPaPaPaO`O`O_O_O_O^O^O]O\O\N~[N|ZN{ZNyYNoToToTnTllljUiThTfTcSvirgnfyidqdah^^HBD?<@)+3OZkMYk(5F(5F(5F/S/S/S/S/STxTxTxTxTxTxTxTxTyTyTyTyUyHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlDhDhDhCh&K}&K}&K}&K}&K}&K}ChChCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCg&J|&J|&J|&J|&J|&J|BgBgBgBfBfBfBfBfBfBfBfBfBfBfBfBfBfBfBf&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|A99N?;L:2T>4gNBlRDk\n^z[J~^LaNcOdPfQgRhTjUlVnWpXrXsYqqrrrsz[z[z[{[{[{ZrqqppoyVxVxUwTwTaPbPbPbPbPbPbPbPbPbPbPbPbPbPaPaPaPaPaOaO`O`O`O_O_O^O^O^O]O]O\O~\N}[N|ZNzYNpTpUpUpUoVoVnVmVlVkVjVhVfU~cUujqh~mfugdkaad\^E@D98?$(2minffm^blV^lMYk(5F(5F/STxTxTxTxTxTxTxTxTxTyTyTyUyUyHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}ChChChChChChChCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCg&J|CgCgCgCgCgBgBgBgBgBgBgBfBfBfBfBfBfBfBfBfBfBfBfBf&J|&J|&J|&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|%J|AeAe;GY<68I=:I82Q=4XA6~fZj\m^p`|]L`NcPeQgSjlmnoXqYrZt[rsstttz]{]{]{\{\{\{[srrqppyWonmllkkaOaOaOaOaOaOaO`O`O`O`O`O`O_O_O_O_O^O^O]O]O]O\O~\N}[N|ZNllmqVqVqVpWpWoWnnnnn~neWxltkpiykfodcf_`JDG@>C*,5$1MYktr~tstmolinadmX_lNZkMZkTxTxTxTxTxTxTxTyTyTyUyUyUyHlHlHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhChChChChChChChCgCgCgCgCgCgCgCgCgCgCg&J}&J}&J}CgCgCgCgCgCgCgCgCgCgBgBgBgBgBgBgBfBfBfBfBfBfBfBfBf&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|AfAfAfAf;GY;GY;GY1'!D:9N?;N;3]I?zdYh[l^oascuebQdRfTlmnopqrsv]w]uuuuv{^{^|^|]|]{\{\{[{[zZzZyYyXxXonnmmuTuStStStRsRsQ_O_O_O^O^O^O^O^O]O]O]OrSrSrSkllmmmnnqWqXqXooppppp}o{cXv`Vp]U}nishfhaba\_DAF::B$)4MYkMYkMYktctq\QPPIKFDI;>H/8GMZkTxTxTxTxTyTyTyUyUyUyHmHmHmImImImImImImImImImImImImImImImImImImImImImImIm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDhDhChChChChChChChChCgCg&K}&K}&K}&K}&J}&J}CgCgCgCgCgCgCgCgCgCgCgCgCgCgBgBgBgBgBgBgBfBfBfBfBfBf&J|&J|&J|&J|&J|&J|BfBfBfBfBfBf;HY;HY;GY;GY;GY;GY;,#I=:H82YF?^JA|e[j]n`qctewgyi|k~lnopqssu]v^w^x_y_z_z_{_wwvvvuut{\{\z[zZyZyYxXpowWvVvVuUuUuTtTlkkkkkksTrTrTrTrTrUrUrVnnnoooppqYqqrrrrqgZ{dYvaXp^WiYU`TRVNOb]aEBH<+[NL^SQWNNKFJ?AI2:HTxTyTyTyUyUyUyUyUyImImImImImImImImImImImImImImImImImImImIm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDhDhDhDhDhDhDhCh&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}CgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgBgBgBgBgBgBgBfBfBf&J|&J|BfBfBfBfBfBfBfBfBf;HY;HY;HY;HY;HY;HY;GY3("D::B41RB=YG@wcZ}g\k_nbrdug}aRdTgViXkYqrstp^q^w`x`y`z`za{axxwwwvvvuutssrrqqppoovWnnnnnnmtVsVsVsVsVsWsWsXsXpppsYsYrZr[r\q\p]ttssh\{e[vbYo^XhZV`USXPQNJMECJRS[47A+((MYkMYkMYkMZk(5F(5F(5FOHJT=+YML_SRZQQMGJABI2:H/TUyUyUyUyUyUyImImImImImImImImImImImIm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDhDhDhDhDh'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}CgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgBgBgBgBg&J|&J|BfBfBfBfBfBfBfBfBf;HY;HY;HY;HY;HY;HY>DM>DM;HY89<:+#9&B52I94ZHAxd[}g^k`ncrey_R}bTeVgXiYk[l\n]o^vvvawaxaybzb{b{axx|a|a|`{`{_{_{^z^uttssrrwZwZvYvYvYuXuXuXuXpppppppqqtZt[s\s\s]r]r^q^p^o^n^l^j^h]{f\ub[n^YgZW_UTWPQOKOEEKST]JNY>=?JJIMYkMYk(5F(5F(5F(5F(5F)5G)5GK=4S<*XMLbWVYPPLGJ@AI/T/TUyUyUyImImImImImImImImImImImIm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}ChChCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCg&J|&J|&J|&J|&J|BgBgBgBfBfBfBfBfBf;HY;HY;HY;HY;HY;HYCIR>DMCIR;HYCIR.$0"8&?*G/V=+w[F{g^kanXMs\Px_S{bU~dWfYhZj\l]m^vwxyyzzzzz{b{b{b{b{a{a{`{`z_z_z^uy]y]x]x\w\w[w[v[v[v[v[rrrsssstuut^s_s_r_r`q`p`wvvu~twd]sb[l^ZeYW]TUUORLJOYYaRU^JOZ>>@!$)RXaMYk39B-3<-3<(5F)5G)5G)5G)5G)5GFDJK9*^K=YONg\\TLMIFJ:>I0T0TImImImInInInInInInInInInInIn'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DiDiDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}ChChChChChCgCgCgCgCgCgCgCgCgCgCg&J}&J}&J}&J}&J|&J|&J|&J|&J|BgBgBgBgBgBfBfEM>EMCIR;HY;HYCIRCIR)6&8&@*H0I1!\B0}_JhTKjM8q[Pt]Sw`U{cW~eYg[i\k^m_vwxyzz{{{{{zdzdzczczcyyyxxxwwwww_w_w_vvvvwwwwwwxxxxxxxxwv~v|tysvrh\YcXX[TUSNRIHOUXaNS^JFE>>A')+"%(4:C(5F(5F3:B3:B-3<-3<)5G)5G)5G)5G)5G)5GE:4O:*TKLbXWcZZPIKDCJImImImImInInInInInInJnJnJnJnJnJn'K~'K~'K~'K~'K~'K~'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhChChChChChChCgCgCgCg&K}&K}&J}&J}&J}&J}&J}&J}&J}&J}&J|&J|&J|CgCgCgBgBgBgEMCIRCIRCIR888DGNCJRCIRBBB(0 8&<)G0M5"X@0z^KbFkUlXPp[Rs^TvaVzcX}fZg\i]uvwxyzz{{vevewewe||{{{{{{zzzzzyvbvbvbububuctctcsbscrcqcyyyxxww|uytvs~sqyooslmVQTOLR[\dQU`KHHAAD:<@68; &Z`i-4<%');AJ4:C4:C4:C-4<)5G)5G)5G)5G)6G)6G@84H8-N?5YPQmccoghd`dInInInInInInJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJn'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~EiEiEiEi'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhChChCh&K}&K}&K}&K}&K}&K}&K}&K}&J}&J}&J}&J}&J}&J}&J}&J}&J}CgCgCgCgB9;>68;Z`iZ`iMZk)5G4:C-4<4:C4:C-4<;BJ)5G)6G)6G)6G)6G)6GC6-L;.leg{{ypqhbeVYcJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJn'L~'L~'L~'L~'L~'L~'K~'K~'K~EiEiEiEiEiEiEiEi'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDh'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&J}&J}&J}&J}&J}&J}CgCgCg<535=AG=?D?AD==1(B3)B2&F4'E4)gTGlXJs^OzcTzaPqfethgvjhbVTcWUdXVeYWfZXg[Yh\Zi]Zi][j^\usususts~tt~tt}tt|st{stut~tt|sszrsyqrwpquoqsmpqloXTXTQWPOULLSSJEA<:=99757335./2113)+.'),)+.8:="(3@QJMPV\eT[cNZlNZlZ`iZ`iZ`iZ`iSYbY`h4;C.4=)6GCPaCPaCPaCPaCPaEQbZOGa_emhknfgeaeJnJnJnJnJnJnJoJoJoJoJoJoJoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoиииEjEiEiEiEi'L~'L~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K}'K}'K}'K}'K}'K}'K}DiDiDiDiDhDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}&K}$.>=I[=I[2)>0&A2'C3(I8-^OFbRHfUJjXMq^RwcVzfYfRDfQCdN@zdTqijrjksklrklrklrklqjmpjmpjmojmojmnimmimkhliflscYm`Xg\VbYT^VRE>;A<:>98:77645:873220/0,-/)+.*,/#%( &15;5BSKKKJMP]dlU[dNZlNZlZ`iTZcZaiZaiZ`iZ`iSZbLS[V]eDPbDPbDPbDPbDPbDPbWMF^^dieirkeaeJoJoJoJoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoGk'L~'L~'L~'L~'L~'L~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~EiEiEiEiEiDiDiDiDiDi'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}%/> ,>=I[=I[ ,> ,>#)2(.7#)2(.7#)2#)2#)2#)2(.7(.7(.767@D>A214$+3#%("$'###""""""&&&888888cB*}\I@!%+%!5*$:/(;0)<1*>3+@4+>1(bUKN@6OA6L=3QB8M?4_RKaTLbUMcVNcVNcVObVOaVOaUO`UO_UO^UO^TO\SOYRNWPNUOMWPKYSOWRN;63953:76755333,/2'),%(+"%(!' "&,KXi04:JMP]_b^emU[dNZlNZlT[cU[dU[dU[d[ajW]fDPbDPbDPbDPbDPbDPbnSw|mqjKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpGkGkGkGkGkGk'L~'L~'L~'L~'K~'K~'K~EiEiEiEiEiEiEiEiEiEiEiEiDiDi'K}'K}'K}'K}HlHlHlHlHlHlHlHl'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}*2? ->=I[=I[ ,> ,> ,>#)2#)2#)2(.7(.7#)2#)2(.7(.7(.7(.7/28:79G@A<89',4#%(#%(######""""""8888888887'vS:jW;) - -&3#.$-% .% .& /&!,#,#@70A71XNHXNHWNHWNHZRLYQLYQLXQLWQLWPLUOLSNLQMKOLJMJJ0//.-.,,-&(+"(!' 15;6CT37=MMMKMP^ad_enY`hNZlNZlU\dV\eDQbDQbDQbDQbDQbMUcyl|oiKoKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpGkGkGkGkGkGkGkGkGkHlHlHlHlHlHlHlHlHlHlHlHlHl'K}'K}'K}'K}'K}'K}'K}'K}'K}HO\=J[=J[=J[ -> ,> ,>(.7#)2#)2(.7(.7(.7#)2(.7(.7(/7(/7)/8/28114H7,99@.05&,5$&)$$$######"""(((8888888888888884"nO9gXjZE/ (-" - - %' %$#" ! !$ - - - 48>7CU:GX JJJLLLKMPagp_enNZlLPVDQbDQbDQbDQbNVcuorj兌該KpKpKpKpKpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLp謂謂謂謂謂謂謂LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpGkGkGkGlGlGlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl'K}'K}'K}'K}DhDhDhIP\=J[=J[=J[=J[ -> ->(.7#)2#)2(.7(.7(.7#)2(.7(/7(/7)/8)/8)/803966:E?AC>A856,07%'*%')$$$######(((DDDBBB8888888880 cF1w]OcS{`QS;+57' - - -*    -  ;?E7CU;HY=I[ JJJMMMKMPacfbhqEQcHScNVd寒Э筏謂謂謂謂謂謂謂LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLp謂謂謂謂謂謂謂謂謂謂謂LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpGlGlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlDhDhDhDh=J[=J[=J[=J[=J[=J[ ->(/7#)2#)2(.7(.7(.7#*2(/7)/8)/8)/8)/8)08*0903:56:88@KBB=;@348*08&(+'(*%%%$$$(((EEE(((&&&">-"bF3oXMs[Ow]Py^PqbpXMdH5R<,Q;, &%%#'-"'-&3DS_qP\nR_p>J\?K]AG@B::@66:-29'),)'%BBBFFFEEE)))))))))&&& @@@FFFACFZ\_[ajagpキΞ!EQcGRcKTdPWdェ侵謂謂謂謂謂謂謂謂謂謂謂謂謂謂謂謂謂謂謂謂違違違違違LpLpLqLqLqLqLqLqLq宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴MqMqMqMqMqMqMqMqMqMqMqMqMqMqMqHlHlHlHlHlHlHlHlHlHlHlHl>J\>J\=J[=J[=J[=J[FLU39B#*2(/7)/7)/8$*3$*3$*3)/8)08*09*09*19',5(-5*.6.17338@<=G@BH@BXW]UUXLPWFHKDFHKKKHHH+++%%%%%%$$$###!!!!!!777777777777777777777AAAFFFACFACF\^aeltbhqDQbDQbDQbギ:亜О:亜О!!ERcERcERcERcHScLUdRXd|nj謂謂謂謂謂謂謂謂謂謂違違違違違宴宴宴宴宴宴宴宴宴宴宴宴MqMqMqMqMqMq宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴MqMqMqMqMqMqMqMqMqMqMqMqMqHlHlHlHlHlHlHlHlHlHlHlHlHlHl>J\=J[=J[FLUFLU(/7(/7*08*08%+3$*3$+3$+3*09*09*19&,5&,5'-6).6*/7-18NPURRVXUVc]^f^_[X]\XYTUZLQYKMPFHJ)))(((&&&%%%%%%$$$$$$###!!!!!!!!!777777777BBBEEEACGADGFIL\ckZ`iTZcDQbDQbDQbagpbiqcircir〒陰┗;亜О←←!?Y`hY_hERcERcERcGSdJTdNVdTYeLpLp違違違違宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴MqMq宴宴宴延延延延延延延延延延俄俄俄俄俄俄俄俄俄俄俄俄俄MqMqMqMqMqMqMqMqMqMqMqHlHlHlHlHlHlHlHlHlHlHlHlHmFLUFLUFLU)/8+08+08&+3&+3%+4%+4%+4*19+1:&,5'-5'-6(.6FLTHMTINUKOVOQWSTXYWX`[^lbac]_f_\a_aY\aRX_,.1*,.*+-***((('''&&&%%%%%%$$$$$$$$$###!!!!!!!!!!!!!!!%%%%%%%%%%%%"""""""""KKKJJJFFFGIL]_b^dm\bkV]eDQbEQcEQcEQccirdjsdksektdjsdjscir旺┗※←→[ajZ`iOU^ERcERcFRdFRdITdLUdPWeVZeLpLqLqLq宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴宴延延延延延延俄俄俄Mq俄俄俄俄俄俄イイイイイイイイイイイイイイイイイイイイイイMrMrMrMrMrMrMrMrMrMrHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHmHmHm-18,18',3',4',4&,4%,4+1:,2:'-5DJSEKSEKTFLTFLUHMUINVKOWLPWQSYTUZWWZpjje^`offb\_h`]eaaCCG8;A27?-/2+-/.+)******)))((('''&&&&&&%%%%%%$$$$$$$$$$$$$$$$$$######???EEEEEEEEE((((((###&&&%%%HJMHJMHJMHJM_en]dlZ`i_enEQcEQcEQcEQcbhqektflufluflufluektektdksdjscjr旺陰┗\ckQW`[ajZaiOU^FRdFRdFRdHSdKUdNVeRXeX\fLqMqMqMqMq宴宴宴宴宴延延延延延俄俄俄俄俄俄俄俄イイイイイMrMrMrMrMrイイイイイイイイイイイイイイイイイイイイイイイイイイイイNrNrNrNrNrNrNrNrHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHmHmHmHmImImImPT[KOVJOV(-4(-4'-5'-5JOXEKSEKSEKTFLTFLTGMUGMUHNVIOWKPWLQXMRYPTZTV[\]a_^asljd^azporjkE@CLEBIEFEDG29A28A17@135,.1+-0+,/./1..0'),)))++++++++++++***FFFFFFACFACFEEEACFACFJLOJLOKQZ_en]clY_hU[dEQcEQcEQcEQcEQcagp[aj\bk\bkgnvgnvgmvgmvfluflueltektdksdjscjrcir〒TZcSYbRYaRXaQW`[bj[ajZ`iFSdFSdGSdJTdLVePXeTZfZ]fMqMqMqMqMqMqMq俄俄俄俄俄イイイイイイイイイイイイイイNrNrNrNrNrNrNrNrNrイイイイウウウウウウウウウウウウウウウウ勀勀勀勀勀勀勀NrNrNrNrNr勀勀HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlImImImImImImImImImImLPVLPWKPWFLTFLTFLUGMUGMUHMVHNVINWIOWKPXLQYMRYNSZTX`X[a[]b]^c__ccacib`JDGi__aYYPJLD@C=;AKEDTQR@?A>>A;/5>.4=-43, 'fill'=>red, 'tags'=>$tag_item ) TkcLine.new(cvs, '1c','5c','7c','5c','7c','7c','9c','7c', 'width'=>'.5c', - 'stipple'=>'@'+[$demo_dir, - 'images','gray25.bmp'].join(File::Separator), + 'stipple'=>'@'+[$demo_dir,'..', + 'images','gray25.xbm'].join(File::Separator), 'arrow'=>'both', 'arrowshape'=>'15 15 7', 'tags'=>$tag_item ) TkcLine.new(cvs, '1c','7c','1.75c','5.8c','2.5c','7c','3.25c','5.8c','4c','7c', 'width'=>'.5c', 'capstyle'=>'round', 'join'=>'round', @@ -135,8 +136,8 @@ TkcLine.new(cvs, '15.5c','1c','19.5c','1.5c','15.5c','4.5c','19.5c','4c', TkcLine.new(cvs, '12c','6c','13.5c','4.5c','16.5c','7.5c','18c','6c', '16.5c','4.5c','13.5c','7.5c','12c','6c', 'smooth'=>'on', 'width'=>'3m', 'capstyle'=>'round', - 'stipple'=>'@'+[$demo_dir, - 'images', 'gray25.bmp'].join(File::Separator), + 'stipple'=>'@'+[$demo_dir, '..', + 'images', 'gray25.xbm'].join(File::Separator), 'fill'=>red, 'tags'=>$tag_item ) TkcText.new(cvs, '25c', '.2c', 'text'=>'多角形', 'anchor'=>'n') @@ -150,8 +151,8 @@ TkcPolygon.new(cvs, '25c','4c','25c','4c','25c','1c','26c','1c','27c','4c', TkcPolygon.new(cvs, '22c','4.5c','25c','4.5c','25c','6.75c','28c','6.75c', '28c','5.25c','24c','5.25c','24c','6.0c','26c','6c','26c', '7.5c','22c','7.5c', - 'stipple'=>'@' + [$demo_dir, - 'images', 'gray25.bmp'].join(File::Separator), + 'stipple'=>'@' + [$demo_dir, '..', + 'images', 'gray25.xbm'].join(File::Separator), 'outline'=>'black', 'tags'=>$tag_item ) TkcText.new(cvs, '5c', '8.2c', 'text'=>'矩形', 'anchor'=>'n') @@ -160,8 +161,8 @@ TkcRectangle.new(cvs, '1c','9.5c','4c','12.5c', TkcRectangle.new(cvs, '0.5c','13.5c','4.5c','15.5c', 'fill'=>green, 'tags'=>$tag_item ) TkcRectangle.new(cvs, '6c','10c','9c','15c', 'outline'=>'', - 'stipple'=>'@'+[$demo_dir, - 'images','gray25.bmp'].join(File::Separator), + 'stipple'=>'@'+[$demo_dir,'..', + 'images','gray25.xbm'].join(File::Separator), 'fill'=>blue, 'tags'=>$tag_item ) TkcText.new(cvs, '15c', '8.2c', 'text'=>'楕円', 'anchor'=>'n') @@ -170,8 +171,8 @@ TkcOval.new(cvs, '11c','9.5c','14c','12.5c', TkcOval.new(cvs, '10.5c','13.5c','14.5c','15.5c', 'fill'=>green, 'tags'=>$tag_item ) TkcOval.new(cvs, '16c','10c','19c','15c', 'outline'=>'', - 'stipple'=>'@'+[$demo_dir, - 'images','gray25.bmp'].join(File::Separator), + 'stipple'=>'@'+[$demo_dir,'..', + 'images','gray25.xbm'].join(File::Separator), 'fill'=>blue, 'tags'=>$tag_item ) TkcText.new(cvs, '25c', '8.2c', 'text'=>'テキスト', 'anchor'=>'n') @@ -186,7 +187,7 @@ TkcText.new(cvs, '25.5c', '11c', 'anchor'=>'w', 'font'=>font1, 'fill'=>blue, TkcRectangle.new(cvs, '24.9c','13.9c','25.1c','14.1c') if $tk_version =~ /^4\.[01]/ TkcText.new(cvs, '25c', '14c', 'anchor'=>'c', 'font'=>font2, 'fill'=>red, - 'stipple'=>'@' + [$demo_dir, + 'stipple'=>'@' + [$demo_dir, '..', 'images', 'grey.5'].join(File::Separator), 'text'=>'Stippled characters', 'tags'=>$tag_item ) else @@ -204,8 +205,8 @@ TkcArc.new(cvs, '0.5c','17c','7c','20c', 'fill'=>green, 'outline'=>'black', # 'tags'=>$tag_item) TkcArc.new(cvs, '6.5c','17c','9.5c','20c', 'width'=>'4m', 'style'=>'arc', 'outline'=>blue, 'start'=>135, 'extent'=>270, - 'outlinestipple'=>'@'+[$demo_dir, - 'images','gray25.bmp'].join(File::Separator), + 'outlinestipple'=>'@'+[$demo_dir, '..', + 'images','gray25.xbm'].join(File::Separator), 'tags'=>$tag_item) TkcArc.new(cvs, '0.5c','20c','9.5c','24c', 'width'=>'4m', 'style'=>'pieslice', 'fill'=>'', 'outline'=>red, 'start'=>225, 'extent'=>90, @@ -219,22 +220,22 @@ TkcText.new(cvs, '15c', '16.2c', 'text'=>' # 'bitmap'=>'@' + ['images', 'face'].join(File::Separator), # 'tags'=>$tag_item) TkcBitmap.new(cvs, '13c','20c', - 'bitmap'=>'@' + [$demo_dir, - 'images', 'face.bmp'].join(File::Separator), + 'bitmap'=>'@' + [$demo_dir, '..', + 'images', 'face.xbm'].join(File::Separator), 'tags'=>$tag_item) #TkcBitmap.new(cvs, '17c','18.5c', # 'bitmap'=>'@' + ['images', 'noletters'].join(File::Separator), # 'tags'=>$tag_item) TkcBitmap.new(cvs, '17c','18.5c', - 'bitmap'=>'@' + [$demo_dir, - 'images', 'noletter.bmp'].join(File::Separator), + 'bitmap'=>'@' + [$demo_dir, '..', + 'images', 'noletter.xbm'].join(File::Separator), 'tags'=>$tag_item) #TkcBitmap.new(cvs, '17c','21.5c', # 'bitmap'=>'@' + ['images', 'letters'].join(File::Separator), # 'tags'=>$tag_item) # ↓の形式でも可能 TkcBitmap.new(cvs, '17c','21.5c') { - bitmap '@' + [$demo_dir, 'images', 'letters.bmp'].join(File::Separator) + bitmap '@' + [$demo_dir, '..', 'images', 'letters.xbm'].join(File::Separator) tags $tag_item } #TkcBitmap.new(cvs, '17c','21.5c') { @@ -357,7 +358,7 @@ end def itemDrag(c,x,y) x = c.canvasx(x) y = c.canvasy(y) - c.move 'current', x - $lastX, y - $lastY + c.move('current', x - $lastX, y - $lastY) $lastX = x $lastY = y end diff --git a/ext/tk/sample/demos-jp/label.rb b/ext/tk/sample/demos-jp/label.rb index 80ab5f3d8f..425654216c 100644 --- a/ext/tk/sample/demos-jp/label.rb +++ b/ext/tk/sample/demos-jp/label.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($label_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $label_demo $label_demo = nil @@ -56,7 +57,7 @@ f_right = TkFrame.new($label_demo) ].each{|w| w.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'anchor'=>'w')} TkLabel.new(f_right) { - bitmap('@' + [$demo_dir,'images','face.bmp'].join(File::Separator)) + bitmap('@' + [$demo_dir,'..','images','face.xbm'].join(File::Separator)) borderwidth 2 relief 'sunken' }.pack('side'=>'top') diff --git a/ext/tk/sample/demos-jp/labelframe.rb b/ext/tk/sample/demos-jp/labelframe.rb index 044fcd23ae..8f76ffacfb 100644 --- a/ext/tk/sample/demos-jp/labelframe.rb +++ b/ext/tk/sample/demos-jp/labelframe.rb @@ -37,7 +37,7 @@ EOL TkFrame.new($labelframe_demo){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') - TkButton.new(f, :text=>'了解', :width=>15, :command=>proc{ + TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $labelframe_demo.destroy $labelframe_demo = nil }).pack(:side=>:left, :expand=>true) diff --git a/ext/tk/sample/demos-jp/menu.rb b/ext/tk/sample/demos-jp/menu.rb index fb32623cc8..79d5b3d4ca 100644 --- a/ext/tk/sample/demos-jp/menu.rb +++ b/ext/tk/sample/demos-jp/menu.rb @@ -31,7 +31,8 @@ TkLabel.new($menu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { # frame 生成 TkFrame.new($menu_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $menu_demo $menu_demo = nil @@ -150,7 +151,8 @@ TkMenubutton.new($menu_frame, 'text'=>'Icons', 'underline'=>0) {|m| TkMenu.new(m, 'tearoff'=>false) {|icon_menu| m.configure('menu'=>icon_menu) add('command', - 'bitmap'=>'@'+[$demo_dir,'images','pattern.bmp'].join(File::Separator), + 'bitmap'=>'@'+[$demo_dir,'..', + 'images','pattern.xbm'].join(File::Separator), 'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', 'text'=>'今あなたが選択したメニューの項目はテキストではなくビットマップを表示していました。それ以外の点では他のメニュー項目と変わりません。', 'bitmap'=>'', 'default'=>0, diff --git a/ext/tk/sample/demos-jp/menu84.rb b/ext/tk/sample/demos-jp/menu84.rb index ea5fdf6487..78d4e68872 100644 --- a/ext/tk/sample/demos-jp/menu84.rb +++ b/ext/tk/sample/demos-jp/menu84.rb @@ -45,7 +45,8 @@ TkFrame.new($menu84_demo) {|frame| # frame TkFrame.new($menu84_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $menu84_demo $menu84_demo = nil @@ -68,8 +69,8 @@ TkMenu.new($menu84_frame, 'tearoff'=>false) {|m| $menu84_frame.add('cascade', 'label'=>'File', 'menu'=>m, 'underline'=>0) add('command', 'label'=>'Open...', 'command'=>proc{fail 'これは単なるデモですから、"Open..." 項目の機能は特に定義されてはいません。'}) add('command', 'label'=>'New', 'command'=>proc{fail 'これは単なるデモですから、"New" 項目の機能は特に定義されてはいません。'}) - add('command', 'label'=>'Save', 'command'=>proc{fail 'これは単なるでもですから、"Save" 項目の機能は特に定義されてはいません。'}) - add('command', 'label'=>'Save As...', 'command'=>proc{fail 'これは単なるでもですから、"Save As..." 項目の機能は特に定義されてはいません。'}) + add('command', 'label'=>'Save', 'command'=>proc{fail 'これは単なるデモですから、"Save" 項目の機能は特に定義されてはいません。'}) + add('command', 'label'=>'Save As...', 'command'=>proc{fail 'これは単なるデモですから、"Save As..." 項目の機能は特に定義されてはいません。'}) add('separator') add('command', 'label'=>'Print Setup...', 'command'=>proc{fail 'これは単なるデモですから、"Print Setup..." 項目の機能は特に定義されてはいません。'}) add('command', 'label'=>'Print...', 'command'=>proc{fail 'これは単なるデモですから、"Print..." 項目の機能は特に定義されてはいません。'}) @@ -157,7 +158,8 @@ TkMenu.new($menu84_frame, 'tearoff'=>false) {|m| TkMenu.new($menu84_frame, 'tearoff'=>false) {|m| $menu84_frame.add('cascade', 'label'=>'Icons', 'menu'=>m, 'underline'=>0) add('command', 'hidemargin'=>1, - 'bitmap'=>'@'+[$demo_dir,'images','pattern.bmp'].join(File::Separator), + 'bitmap'=>'@'+[$demo_dir,'..', + 'images','pattern.xbm'].join(File::Separator), 'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', 'text'=>'あなたが選択したメニュー項目は、文字列の代わりにビットマップイメージで項目を表示したものです。それ以外の点では、ほかのメニュー項目との間で特に違いがあるわけではありません。', 'bitmap'=>'', 'default'=>0, diff --git a/ext/tk/sample/demos-jp/menu8x.rb b/ext/tk/sample/demos-jp/menu8x.rb index a6d3c5e09e..08598f88f8 100644 --- a/ext/tk/sample/demos-jp/menu8x.rb +++ b/ext/tk/sample/demos-jp/menu8x.rb @@ -26,7 +26,8 @@ TkLabel.new($menu8x_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { # frame 生成 TkFrame.new($menu8x_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $menu8x_demo $menu8x_demo = nil @@ -36,7 +37,7 @@ TkFrame.new($menu8x_demo) {|frame| TkButton.new(frame) { text 'コード参照' - command proc{showCode 'menu'} + command proc{showCode 'menu8x'} }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') @@ -62,7 +63,8 @@ TkFrame.new($menu8x_demo) {|frame| # frame 生成 TkFrame.new($menu8x_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $menu8x_demo $menu8x_demo = nil @@ -72,7 +74,7 @@ TkFrame.new($menu8x_demo) {|frame| TkButton.new(frame) { text 'コード参照' - command proc{showCode 'menu'} + command proc{showCode 'menu8x'} }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') diff --git a/ext/tk/sample/demos-jp/menubu.rb b/ext/tk/sample/demos-jp/menubu.rb index 8b4d7980d2..1308014183 100644 --- a/ext/tk/sample/demos-jp/menubu.rb +++ b/ext/tk/sample/demos-jp/menubu.rb @@ -43,7 +43,8 @@ TkLabel.new($menubu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { # frame 生成 TkFrame.new($menubu_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $menubu_demo $menubu_demo = nil @@ -53,7 +54,7 @@ TkFrame.new($menubu_demo) {|frame| TkButton.new(frame) { text 'コード参照' - command proc{showCode 'menu'} + command proc{showCode 'menubu'} }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') @@ -156,7 +157,8 @@ center = TkFrame.new(body) { TkFrame.new($menubu_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc { tmppath = $menubu_demo $menubu_demo = nil diff --git a/ext/tk/sample/demos-jp/msgbox.rb b/ext/tk/sample/demos-jp/msgbox.rb index cf53d70487..03ab1f7dbe 100644 --- a/ext/tk/sample/demos-jp/msgbox.rb +++ b/ext/tk/sample/demos-jp/msgbox.rb @@ -22,7 +22,8 @@ TkLabel.new($msgbox_demo, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', # frame 生成 TkFrame.new($msgbox_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $msgbox_demo $msgbox_demo = nil diff --git a/ext/tk/sample/demos-jp/paned1.rb b/ext/tk/sample/demos-jp/paned1.rb index 99e6b6cddb..cd51e34aa0 100644 --- a/ext/tk/sample/demos-jp/paned1.rb +++ b/ext/tk/sample/demos-jp/paned1.rb @@ -30,7 +30,7 @@ EOL TkFrame.new($paned1_demo){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') - TkButton.new(f, :text=>'了解', :width=>15, :command=>proc{ + TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $paned1_demo.destroy $paned1_demo = nil }).pack(:side=>:left, :expand=>true) diff --git a/ext/tk/sample/demos-jp/paned2.rb b/ext/tk/sample/demos-jp/paned2.rb index 9df88c4b97..b0261d50f0 100644 --- a/ext/tk/sample/demos-jp/paned2.rb +++ b/ext/tk/sample/demos-jp/paned2.rb @@ -30,7 +30,7 @@ EOL TkFrame.new($paned2_demo){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') - TkButton.new(f, :text=>'了解', :width=>15, :command=>proc{ + TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $paned2_demo.destroy $paned2_demo = nil }).pack(:side=>:left, :expand=>true) diff --git a/ext/tk/sample/demos-jp/plot.rb b/ext/tk/sample/demos-jp/plot.rb index 464dd4441d..c8025d8bf9 100644 --- a/ext/tk/sample/demos-jp/plot.rb +++ b/ext/tk/sample/demos-jp/plot.rb @@ -24,7 +24,8 @@ TkLabel.new($plot_demo, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', # frame 生成 $plot_buttons = TkFrame.new($plot_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $plot_demo $plot_demo = nil diff --git a/ext/tk/sample/demos-jp/puzzle.rb b/ext/tk/sample/demos-jp/puzzle.rb index 24c48693a9..afef8fcb09 100644 --- a/ext/tk/sample/demos-jp/puzzle.rb +++ b/ext/tk/sample/demos-jp/puzzle.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($puzzle_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $puzzle_demo $puzzle_demo = nil diff --git a/ext/tk/sample/demos-jp/radio.rb b/ext/tk/sample/demos-jp/radio.rb index 871503029e..5858b4222a 100644 --- a/ext/tk/sample/demos-jp/radio.rb +++ b/ext/tk/sample/demos-jp/radio.rb @@ -31,7 +31,8 @@ color = TkVariable.new # frame 生成 TkFrame.new($radio_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $radio_demo $radio_demo = nil diff --git a/ext/tk/sample/demos-jp/radio2.rb b/ext/tk/sample/demos-jp/radio2.rb index 62425af90d..c7b98e6312 100644 --- a/ext/tk/sample/demos-jp/radio2.rb +++ b/ext/tk/sample/demos-jp/radio2.rb @@ -1,4 +1,4 @@ -# radio.rb +# radio2.rb # # This demonstration script creates a toplevel window containing # several radiobutton widgets. @@ -14,8 +14,8 @@ end # demo toplevel widget $radio2_demo = TkToplevel.new {|w| - title("Radiobutton Demonstration") - iconname("radio") + title("Radiobutton Demonstration 2") + iconname("radio2") positionWindow(w) } @@ -24,7 +24,7 @@ msg = TkLabel.new($radio2_demo) { font $font wraplength '5i' justify 'left' - text "下には2つのラジオボタングループが表示されています。ボタンをクリックすると、そのボタンだけがそのグループの中で選択されます。各グループに対してそのグループの中のどのボタンが選択されているかを示す変数が割り当てられています。現在の変数の値を見るには「変数参照」ボタンをクリックしてください。" + text "下には3つのラジオボタングループが表示されています。ボタンをクリックすると、そのボタンだけがそのグループの中で選択されます。各グループに対してそのグループの中のどのボタンが選択されているかを示す変数が割り当てられています。現在の変数の値を見るには「変数参照」ボタンをクリックしてください。" } msg.pack('side'=>'top') @@ -36,7 +36,8 @@ align = TkVariable.new # frame TkFrame.new($radio2_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $radio2_demo $radio2_demo = nil @@ -47,7 +48,7 @@ TkFrame.new($radio2_demo) {|frame| TkButton.new(frame) { text 'コード参照' - command proc{showCode 'radio'} + command proc{showCode 'radio2'} }.pack('side'=>'left', 'expand'=>'yes') TkButton.new(frame) { diff --git a/ext/tk/sample/demos-jp/radio3.rb b/ext/tk/sample/demos-jp/radio3.rb new file mode 100644 index 0000000000..bdc3ee0bf5 --- /dev/null +++ b/ext/tk/sample/demos-jp/radio3.rb @@ -0,0 +1,114 @@ +# radio3.rb +# +# This demonstration script creates a toplevel window containing +# several radiobutton widgets. +# +# radiobutton widget demo (called by 'widget') +# + +# toplevel widget +if defined?($radio3_demo) && $radio3_demo + $radio3_demo.destroy + $radio3_demo = nil +end + +# demo toplevel widget +$radio3_demo = TkToplevel.new {|w| + title("Radiobutton Demonstration 3") + iconname("radio3") + positionWindow(w) +} + +# label +msg = TkLabel.new($radio3_demo) { + font $font + wraplength '5i' + justify 'left' + text '下には3つのラジオボタングループが表示されています。ボタンをクリックすると、そのグループに属するすべてのボタンの中でクリックしたボタンだけが選択された状態になります。各グループには、そのグループの中のどのボタンが選択されているかを示す変数が割り当てられています。「トライステート」ボタンが押されたときには、ラジオボタンの表示がトライステートモードになります。いずれかのボタンを選択すれば、ボタンの状態は元のように個々のボタンのon/off状態を示すようになります。現在の変数の値を見るには「変数参照」ボタンをクリックしてください。' +} +msg.grid(:row=>0, :column=>0, :columnspan=>3, :sticky=>'nsew') + +# variable +size = TkVariable.new +color = TkVariable.new +align = TkVariable.new + +# frame +TkFrame.new($radio3_demo) {|frame| + TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), + :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + TkButton.new(frame, :text=>'変数参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars($radio3_demo, ['size', size], + ['color', color], ['compound', align]) + }), + TkButton.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'radio3'}), + TkButton.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $radio3_demo + $radio3_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) + TkGrid(frame, :row=>3, :column=>0, :columnspan=>3, :sticky=>'nsew') +} + +# frame +f_left = TkLabelFrame.new($radio3_demo, 'text'=>'文字サイズ', + 'pady'=>2, 'padx'=>2) +f_mid = TkLabelFrame.new($radio3_demo, 'text'=>'色', + 'pady'=>2, 'padx'=>2) +f_right = TkLabelFrame.new($radio3_demo, 'text'=>'ビットマップ配置', + 'pady'=>2, 'padx'=>2) +f_left .grid('column'=>0, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) +f_mid .grid('column'=>1, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) +f_right.grid('column'=>2, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c') + +TkButton.new($radio3_demo, 'text'=>'トライステート', + 'command'=>proc{size.value = 'multi'; color.value = 'multi'}){ + grid('column'=>2, 'row'=>2, 'pady'=>'.5c', 'padx'=>'.5c') +} + +# radiobutton +[10, 12, 14, 18, 24].each {|sz| + TkRadioButton.new(f_left) { + text "ポイントサイズ #{sz}" + variable size + relief 'flat' + value sz + tristatevalue 'multi' + }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w', 'fill'=>'x') +} + +['Red', 'Green', 'Blue', 'Yellow', 'Orange', 'Purple'].each {|col| + TkRadioButton.new(f_mid) { + text col + variable color + relief 'flat' + value col.downcase + anchor 'w' + tristatevalue 'multi' + command proc{f_mid.fg(color.value)} + }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x') +} + +label = TkLabel.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', + 'compound'=>'left') +label.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top') +label.height(TkWinfo.reqheight(label)) +a_btn = ['Top', 'Left', 'Right', 'Bottom'].collect{|a| + TkRadioButton.new(f_right, 'text'=>a, 'variable'=>align, 'relief'=>'flat', + 'value'=>a.downcase, 'indicatoron'=>0, 'width'=>7, + 'command'=>proc{label.compound(align.value)}) +} + +Tk.grid('x', a_btn[0]) +Tk.grid(a_btn[1], label, a_btn[2]) +Tk.grid('x', a_btn[3]) diff --git a/ext/tk/sample/demos-jp/rolodex-j b/ext/tk/sample/demos-jp/rolodex-j index 1c482aafb2..dcc18cfa51 100644 --- a/ext/tk/sample/demos-jp/rolodex-j +++ b/ext/tk/sample/demos-jp/rolodex-j @@ -4,7 +4,7 @@ # このスクリプトは Tom LaStrange の rolodex の一部です。 # # Copyright (C) 1998 by Takaaki Tateishi -# Time-stamp: "03/08/02 14:01:54 nagai" +# Time-stamp: "04/04/09 00:32:12 nagai" # require "tk" diff --git a/ext/tk/sample/demos-jp/ruler.rb b/ext/tk/sample/demos-jp/ruler.rb index d1a7818be4..5d8c0443c1 100644 --- a/ext/tk/sample/demos-jp/ruler.rb +++ b/ext/tk/sample/demos-jp/ruler.rb @@ -37,7 +37,8 @@ TkLabel.new($ruler_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', # frame 生成 $ruler_buttons = TkFrame.new($ruler_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $ruler_demo $ruler_demo = nil @@ -72,11 +73,13 @@ $demo_rulerInfo.normalStyle = {'fill'=>'black'} if TkWinfo.depth($ruler_canvas) > 1 $demo_rulerInfo.activeStyle = {'fill'=>'red', 'stipple'=>''} $demo_rulerInfo.deleteStyle = {'fill'=>'red', - 'stipple'=>'@'+[$demo_dir, 'images', 'gray25.bmp'].join(File::Separator)} + 'stipple'=>'@'+[$demo_dir, '..', + 'images', 'gray25.xbm'].join(File::Separator)} else $demo_rulerInfo.activeStyle = {'fill'=>'black', 'stipple'=>''} $demo_rulerInfo.deleteStyle = {'fill'=>'black', - 'stipple'=>'@'+[$demo_dir, 'images', 'gray25.bmp'].join(File::Separator)} + 'stipple'=>'@'+[$demo_dir, '..', + 'images', 'gray25.xbm'].join(File::Separator)} end TkcLine.new($ruler_canvas, diff --git a/ext/tk/sample/demos-jp/sayings.rb b/ext/tk/sample/demos-jp/sayings.rb index f627396e0f..bcbdd7a5e7 100644 --- a/ext/tk/sample/demos-jp/sayings.rb +++ b/ext/tk/sample/demos-jp/sayings.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($sayings_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $sayings_demo $sayings_demo = nil diff --git a/ext/tk/sample/demos-jp/search.rb b/ext/tk/sample/demos-jp/search.rb index 538c607c01..3ae7de769d 100644 --- a/ext/tk/sample/demos-jp/search.rb +++ b/ext/tk/sample/demos-jp/search.rb @@ -77,7 +77,8 @@ $search_demo = TkToplevel.new {|w| # frame 生成 $search_buttons = TkFrame.new($search_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $search_demo $search_demo = nil @@ -141,45 +142,33 @@ $search_text = TkText.new($search_demo, 'setgrid'=>true) {|t| if TkWinfo.depth($search_demo) > 1 textToggle(proc{ - begin - $search_Tag.configure('background'=>'#ce5555', - 'foreground'=>'white') - rescue - end + $search_Tag.configure('background'=>'#ce5555', + 'foreground'=>'white') }, 800, proc{ - begin - $search_Tag.configure('background'=>'', 'foreground'=>'') - rescue - end + $search_Tag.configure('background'=>'', 'foreground'=>'') }, 200 ) else textToggle(proc{ - begin - $search_Tag.configure('background'=>'black', - 'foreground'=>'white') - rescue - end + $search_Tag.configure('background'=>'black', + 'foreground'=>'white') }, 800, proc{ - begin - $search_Tag.configure('background'=>'', 'foreground'=>'') - rescue - end + $search_Tag.configure('background'=>'', 'foreground'=>'') }, 200 ) end -$search_text.insert('1.0', '\ -このウィンドウは検索機構を実現するのにテキスト widget のタグ機能がどの -ように使われるのかをデモするものです。まず上のエントリにファイル名を入 -れ、<リターン> を押すか「ロード」ボタンを押してください。次にその下の -エントリに文字列を入力し、<リターン> を押すか「反転」ボタンを押してく -ださい。するとファイル中の、検索文字列と一致する部分に全て "search_Tag" -というタグがつけられ、タグの表示属性としてその文字列が点滅するように -設定されます。') +$search_text.insert('1.0', "\ +このウィンドウは検索機構を実現するのにテキスト widget のタグ機能がどの \ +ように使われるのかをデモするものです。まず上のエントリにファイル名を入 \ +れ、<リターン> を押すか「ロード」ボタンを押してください。次にその下の \ +エントリに文字列を入力し、<リターン> を押すか「反転」ボタンを押してく \ +ださい。するとファイル中の、検索文字列と一致する部分に全て \"search_Tag\" \ +というタグがつけられ、タグの表示属性としてその文字列が点滅するように \ +設定されます。") $search_text.set_insert '0.0' $search_fileName.value = '' diff --git a/ext/tk/sample/demos-jp/spin.rb b/ext/tk/sample/demos-jp/spin.rb index 4f6edc13c0..69d6d71d8d 100644 --- a/ext/tk/sample/demos-jp/spin.rb +++ b/ext/tk/sample/demos-jp/spin.rb @@ -41,7 +41,7 @@ EOL TkFrame.new($spin_demo){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') - TkButton.new(f, :text=>'了解', :width=>15, :command=>proc{ + TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $spin_demo.destroy $spin_demo = nil }).pack(:side=>:left, :expand=>true) diff --git a/ext/tk/sample/demos-jp/states.rb b/ext/tk/sample/demos-jp/states.rb index cf8a6768b6..dfae821261 100644 --- a/ext/tk/sample/demos-jp/states.rb +++ b/ext/tk/sample/demos-jp/states.rb @@ -27,7 +27,8 @@ msg.pack('side'=>'top') # frame 生成 TkFrame.new($states_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $states_demo $states_demo = nil diff --git a/ext/tk/sample/demos-jp/style.rb b/ext/tk/sample/demos-jp/style.rb index d58c6115ae..458479611b 100644 --- a/ext/tk/sample/demos-jp/style.rb +++ b/ext/tk/sample/demos-jp/style.rb @@ -18,7 +18,8 @@ $style_demo = TkToplevel.new {|w| # frame 生成 TkFrame.new($style_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $style_demo $style_demo = nil diff --git a/ext/tk/sample/demos-jp/tcolor b/ext/tk/sample/demos-jp/tcolor index 391ce4c446..fc697df63e 100644 --- a/ext/tk/sample/demos-jp/tcolor +++ b/ext/tk/sample/demos-jp/tcolor @@ -16,15 +16,16 @@ require "tk" # Tkによって変更される変数はTkVariableのインスタンスを使う。 $colorSpace = TkVariable.new(:rgb) +$master = nil $red = 65535 $green = 0 $blue = 0 $color = "#ffff00000000" $updating = TkVariable.new(0) $autoUpdate = TkVariable.new(1) -$name = TkVariable.new("") -# $command = TkVariable.new("print(%%,\"\n\")") -$command = TkVariable.new("") +$name = TkVariable.new($color) +$command = TkVariable.new("print(%%,\"\n\")") +# $command = TkVariable.new("") $label1 = TkVariable.new("label1") $label2 = TkVariable.new("label2") $label3 = TkVariable.new("label3") @@ -134,6 +135,8 @@ def tc_scaleChanged return end + $master = :scale if $master == nil + scale1 = $root.middle.middle.scale1 scale2 = $root.middle.middle.scale2 scale3 = $root.middle.middle.scale3 @@ -158,11 +161,13 @@ def tc_scaleChanged raise(Exception,"unknown colorSpace") end $color = format("#%04x%04x%04x",$red.to_i,$green.to_i,$blue.to_i) + $name.value = $color if $master == :scale $root.middle.right.set_color($color) if( $autoUpdate.to_i == 1 ) doUpdate end - Tk.update(TRUE) + Tk.update(true) + $master = nil if $master == :scale end @@ -196,6 +201,8 @@ end def tc_loadNamedColor(name) + $name.value = name + $master = :name if $master == nil if name[0,1] != "#" list = TkWinfo.rgb($root.middle.right.swatch,name) $red = list[0] @@ -222,9 +229,9 @@ def tc_loadNamedColor(name) if strlist.length != 3 raise(eException,"syntax error in color name \"#{name}\"") end - $red = strlist[0].to_i - $green = strlist[1].to_i - $blue = strlist[2].to_i + $red = strlist[0].hex + $green = strlist[1].hex + $blue = strlist[2].hex } $red = $red << shift $green = $green << shift @@ -237,6 +244,8 @@ def tc_loadNamedColor(name) if $autoUpdate.to_i == 1 doUpdate end + Tk.update(true) + $master = nil if $master == :name end diff --git a/ext/tk/sample/demos-jp/text.rb b/ext/tk/sample/demos-jp/text.rb index 179589d820..bec95ee525 100644 --- a/ext/tk/sample/demos-jp/text.rb +++ b/ext/tk/sample/demos-jp/text.rb @@ -25,7 +25,8 @@ end # frame 生成 TkFrame.new($text_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $text_demo $text_demo = nil diff --git a/ext/tk/sample/demos-jp/twind.rb b/ext/tk/sample/demos-jp/twind.rb index d35acd24d0..8716ad7278 100644 --- a/ext/tk/sample/demos-jp/twind.rb +++ b/ext/tk/sample/demos-jp/twind.rb @@ -18,7 +18,8 @@ $twind_demo = TkToplevel.new {|w| # frame 生成 $twind_buttons = TkFrame.new($twind_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc{ tmppath = $twind_demo $twind_demo = nil @@ -75,7 +76,7 @@ TkTextWindow.new($twind_text, 'end', command proc{textWindOn $twind_text,$twind_buttons} cursor 'top_left_arrow' }) -$twind_text.insert('end', 'にします。また2つめのボタンをクリックすると') +$twind_text.insert('end', "にします。また2つめのボタンをクリックすると\n") $twind_text.insert('end', '水平方向のスクロールを') TkTextWindow.new($twind_text, 'end', 'window'=>TkButton.new($twind_text) { diff --git a/ext/tk/sample/demos-jp/twind2.rb b/ext/tk/sample/demos-jp/twind2.rb new file mode 100644 index 0000000000..8c871688b3 --- /dev/null +++ b/ext/tk/sample/demos-jp/twind2.rb @@ -0,0 +1,381 @@ +# +# text (embedded windows) widget demo 2 (called by 'widget') +# + +# toplevel widget が存在すれば削除する +if defined?($twind2_demo) && $twind2_demo + $twind2_demo.destroy + $twind2_demo = nil +end + +# demo 用の toplevel widget を生成 +$twind2_demo = TkToplevel.new {|w| + title("Text Demonstration - Embedded Windows 2") + iconname("Embedded Windows") + positionWindow(w) +} + +# frame 生成 +$twind2_buttons = TkFrame.new($twind2_demo) {|frame| + TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), + :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + TkButton.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'twind2'}), + TkButton.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $twind2_demo + $twind2_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) +} +$twind2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# frame 生成 +$twind2_text = nil +TkFrame.new($twind2_demo, 'highlightthickness'=>2, 'borderwidth'=>2, + 'relief'=>'sunken') {|f| + $twind2_text = TkText.new(f, 'setgrid'=>true, 'font'=>$font, + # 'width'=>'70', 'height'=>35, 'wrap'=>'word', + 'width'=>'70', 'height'=>35, 'wrap'=>'char', + 'highlightthickness'=>0, 'borderwidth'=>0 ){|t| + TkScrollbar.new(f) {|s| + command proc{|*args| t.yview(*args)} + t.yscrollcommand proc{|first,last| s.set first,last} + }.pack('side'=>'right', 'fill'=>'y') + }.pack('expand'=>'yes', 'fill'=>'both') +}.pack('expand'=>'yes', 'fill'=>'both') + +# タグ生成 +$tag2_center = TkTextTag.new($twind2_text, + 'justify' =>'center', + 'spacing1'=>'5m', + 'spacing3'=>'5m' ) +$tag2_buttons = TkTextTag.new($twind2_text, + 'lmargin1'=>'1c', + 'lmargin2'=>'1c', + 'rmargin' =>'1c', + 'spacing1'=>'3m', + 'spacing2'=>0, + 'spacing3'=>0 ) + +# テキストの生成 +$twind2_text.insert('end', 'テキストウィジェットには色々な種類のアイテム') +$twind2_text.insert('end', '(動的なものや静的なものの両方があります)を') +$twind2_text.insert('end', '数多く含めることができます。そうしたアイテムは') +$twind2_text.insert('end', '行替え、タブ、中央揃えなどの様々な方法で') +$twind2_text.insert('end', '配置することができます。') +$twind2_text.insert('end', '加えて、テキストウィジェットの内容物が') +$twind2_text.insert('end', 'ウィンドウサイズに比べて大きすぎる場合でも') +$twind2_text.insert('end', 'すべての方向にスムーズにスクロールさせて') +$twind2_text.insert('end', '確認することが可能です。') +$twind2_text.insert('end', "\n\n") +$twind2_text.insert('end', 'テキストウィジェット上には他のウィジェットを') +$twind2_text.insert('end', '含めることもできます。こうしたものは') +$twind2_text.insert('end', '「埋め込みウィンドウ」と呼ばれ、その中に') +$twind2_text.insert('end', 'いかなるウィジェットでも詰め込むことができます。') +$twind2_text.insert('end', '例えば,ここには2つの') +$twind2_text.insert('end', 'ボタンウィジェットが埋め込まれています。') +$twind2_text.insert('end', '最初のボタンをクリックすると、') +$twind2_text.insert('end', '水平方向のスクロールを ') +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + #text 'ON' + text 'オン' + command proc{textWindOn2 $twind2_text,$twind2_buttons} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', "にします。また、2つめのボタンをクリックすると\n") +$twind2_text.insert('end', '水平方向のスクロールを') +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + #text 'OFF' + text 'オフ' + command proc{textWindOff2 $twind2_text} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', "にします。\n\n") + +$twind2_text.insert('end', '次はもうひとつの例です。') +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text 'ここをクリック' + command proc{textWindPlot2 $twind2_text} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', 'すると、x-yプロットがここに現れます。') +$mark2_plot = TkTextMark.new($twind2_text, 'insert') +$mark2_plot.gravity='left' +$twind2_text.insert('end', 'マウスでドラッグすることで、') +$twind2_text.insert('end', 'プロット上のデータ点を移動することができます。') +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text '消去' + command proc{textWindDel2 $twind2_text} + cursor 'top_left_arrow' + }) +$twind2_text.insert('end', 'をクリックすると元に戻ります。') +$twind2_text.insert('end', "\n\n") + +$twind2_text.insert('end', '表示するテキストなしに埋め込みウィンドウだけを') +$twind2_text.insert('end', 'テキストウィジェットに含めることも有用でしょう。') +$twind2_text.insert('end', 'この場合、テキストウィジェットは') +$twind2_text.insert('end', 'ジオメトリマネージャのように働きます。') +$twind2_text.insert('end', '例えば、ここにはテキストウィジェットに') +$twind2_text.insert('end', 'よってボタンがきれいに整列して配置されています。') +$twind2_text.insert('end', 'これらのボタンをクリックすることで、') +$twind2_text.insert('end', 'このテキストウィジェットの背景色を') +$twind2_text.insert('end', '変えることができます("デフォルト"ボタンで') +$twind2_text.insert('end', '元の色に戻すことができます)。') +$twind2_text.insert('end', '"Short"というボタンをクリックすると文字列の長さが') +$twind2_text.insert('end', '変わり、テキストウィジェットが自動的に') +$twind2_text.insert('end', 'レイアウトを整える様子を見ることができます。') +$twind2_text.insert('end', 'もう一度同じボタンを押すと元に戻ります。') +$twind2_text.insert('end', "\n") + +btn_default = TkButton.new($twind2_text) {|b| + text 'デフォルト' + command proc{embDefBg2 $twind2_text} + cursor 'top_left_arrow' +} +TkTextWindow.new($twind2_text, 'end', 'window'=>btn_default, 'padx'=>3) +embToggle = TkVariable.new('Short') +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkCheckButton.new($twind2_text) { + textvariable embToggle + indicatoron 0 + variable embToggle + onvalue 'A much longer string' + offvalue 'Short' + cursor 'top_left_arrow' + pady 5 + padx 2 + }, + 'padx'=>3, + 'pady'=>2 ) + +[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4', + 'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1', + 'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1', + 'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4' +].each{|twind_color| + TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text) { + text twind_color + cursor 'top_left_arrow' + command proc{$twind2_text.bg twind_color} + }, + 'padx'=>3, + 'pady'=>2 ) +} + +$tag2_buttons.add(btn_default, 'end') + +$text_normal2 = {} +$text_normal2['border'] = $twind2_text.cget('borderwidth') +$text_normal2['highlight'] = $twind2_text.cget('highlightthickness') +$text_normal2['pad'] = $twind2_text.cget('padx') + +$twind2_text.insert('end', "\nborder width や highlightthickness, ") +$twind2_text.insert('end', "padding を通常の値から変更することも可能です。\n") + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Big borders", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinBigB2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Small borders", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinSmallB2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Big highlight", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinBigH2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Small highlight", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinSmallH2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Big pad", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinBigP2 $twind2_text + })) + +TkTextWindow.new($twind2_text, 'end', + 'window'=>TkButton.new($twind2_text, :text=>"Small pad", + :cursor=>'top_left_arrow', + 'command'=>proc{ + textWinSmallP2 $twind2_text + })) + +$twind2_text.insert('end', "\n\n更にイメージもテキストウィジェットに") +$twind2_text.insert('end', "うまく配置できます:") + +TkTextImage.new($twind2_text, 'end', + 'image'=>TkBitmapImage.new(:file=>[ + $demo_dir, '..', + 'images', 'face.xbm' + ].join(File::Separator))) + +# メソッド定義 +def textWinBigB2(w) + w.borderwidth 15 +end +def textWinSmallB2(w) + w.borderwidth $text_normal2['border'] +end +def textWinBigH2(w) + w.highlightthickness 15 +end +def textWinSmallH2(w) + w.highlightthickness $text_normal2['highlight'] +end +def textWinBigP2(w) + w.configure(:padx=>15, :pady=>15) +end +def textWinSmallP2(w) + w.configure(:padx=>$text_normal2['pad'], :pady=>$text_normal2['pad']) +end + +def textWindOn2 (w,f) + if defined? $twind2_scroll + begin + $twind2_scroll.destroy + rescue + end + $twind2_scroll = nil + end + + base = TkWinfo.parent( TkWinfo.parent(w) ) + $twind2_scroll = TkScrollbar.new(base) {|s| + orient 'horizontal' + command proc{|*args| w.xview(*args)} + w.xscrollcommand proc{|first,last| s.set first,last} + w.wrap 'none' + pack('after'=>f, 'side'=>'bottom', 'fill'=>'x') + } + + return nil +end + +def textWindOff2 (w) + if defined? $twind2_scroll + begin + $twind2_scroll.destroy + rescue + end + $twind2_scroll = nil + end + w.xscrollcommand '' + #w.wrap 'word' + w.wrap 'char' +end + +def textWindPlot2 (t) + if (defined? $twind2_plot) && (TkWinfo.exist?($twind2_plot)) + return + end + + $twind2_plot = TkCanvas.new(t) { + relief 'sunken' + width 450 + height 300 + cursor 'top_left_arrow' + } + + #font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*' + font = 'Helvetica 18' + + TkcLine.new($twind2_plot, 100, 250, 400, 250, 'width'=>2) + TkcLine.new($twind2_plot, 100, 250, 100, 50, 'width'=>2) + TkcText.new($twind2_plot, 225, 20, + 'text'=>"A Simple Plot", 'font'=>font, 'fill'=>'brown') + + (0..10).each {|i| + x = 100 + (i * 30) + TkcLine.new($twind2_plot, x, 250, x, 245, 'width'=>2) + TkcText.new($twind2_plot, x, 254, + 'text'=>10*i, 'font'=>font, 'anchor'=>'n') + } + (0..5).each {|i| + y = 250 - (i * 40) + TkcLine.new($twind2_plot, 100, y, 105, y, 'width'=>2) + TkcText.new($twind2_plot, 96, y, + 'text'=>"#{i*50}.0", 'font'=>font, 'anchor'=>'e') + } + + for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]] + x = 100 + (3*xx) + y = 250 - (4*yy)/5 + item = TkcOval.new($twind2_plot, x-6, y-6, x+6, y+6, + 'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2') + item.addtag 'point' + end + + $twind2_plot.itembind('point', 'Any-Enter', + proc{$twind2_plot.itemconfigure 'current', 'fill', 'red'}) + $twind2_plot.itembind('point', 'Any-Leave', + proc{$twind2_plot.itemconfigure 'current', 'fill', 'SkyBlue2'}) + $twind2_plot.itembind('point', '1', + proc{|x,y| embPlotDown2 $twind2_plot,x,y}, "%x %y") + $twind2_plot.itembind('point', 'ButtonRelease-1', + proc{$twind2_plot.dtag 'selected'}) + $twind2_plot.bind('B1-Motion', + proc{|x,y| embPlotMove2 $twind2_plot,x,y}, "%x %y") + while ($twind2_text.get($mark2_plot) =~ /[ \t\n]/) + $twind2_text.delete $mark2_plot + end + $twind2_text.insert $mark2_plot,"\n" + TkTextWindow.new($twind2_text, $mark2_plot, 'window'=>$twind2_plot) + $tag2_center.add $mark2_plot + $twind2_text.insert $mark2_plot,"\n" +end + +$embPlot2 = {'lastX'=>0, 'lastY'=>0} + +def embPlotDown2 (w, x, y) + w.dtag 'selected' + w.addtag_withtag 'selected', 'current' + w.raise 'current' + $embPlot2['lastX'] = x + $embPlot2['lastY'] = y +end + +def embPlotMove2 (w, x, y) + w.move 'selected', x - $embPlot2['lastX'], y - $embPlot2['lastY'] + $embPlot2['lastX'] = x + $embPlot2['lastY'] = y +end + +def textWindDel2 (w) + if (defined? $twind2_text) && TkWinfo.exist?($twind2_plot) + $twind2_text.delete $twind2_plot + $twind2_plot = nil + while ($twind2_text.get($mark2_plot) =~ /[ \t\n]/) + $twind2_text.delete $mark2_plot + end + $twind2_text.insert $mark2_plot," " + end +end + +def embDefBg2 (w) + w['background'] = w.configinfo('background')[3] +end diff --git a/ext/tk/sample/demos-jp/unicodeout.rb b/ext/tk/sample/demos-jp/unicodeout.rb index d408a36aae..37cc1699bb 100644 --- a/ext/tk/sample/demos-jp/unicodeout.rb +++ b/ext/tk/sample/demos-jp/unicodeout.rb @@ -41,7 +41,7 @@ EOL TkFrame.new($unicodeout_demo){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') - TkButton.new(f, :text=>'了解', :width=>15, :command=>proc{ + TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $unicodeout_demo.destroy $unicodeout_demo = nil }).pack(:side=>:left, :expand=>true) diff --git a/ext/tk/sample/demos-jp/vscale.rb b/ext/tk/sample/demos-jp/vscale.rb index 4cb8e0f6b7..86f6f7cdee 100644 --- a/ext/tk/sample/demos-jp/vscale.rb +++ b/ext/tk/sample/demos-jp/vscale.rb @@ -24,7 +24,8 @@ msg.pack('side'=>'top', 'padx'=>'.5c') TkFrame.new($vscale_demo) {|frame| TkButton.new(frame) { - text '了解' + #text '了解' + text '閉じる' command proc { tmppath = $vscale_demo $vscale_demo = nil diff --git a/ext/tk/sample/demos-jp/widget b/ext/tk/sample/demos-jp/widget index 696a9073cc..0544127cbb 100644 --- a/ext/tk/sample/demos-jp/widget +++ b/ext/tk/sample/demos-jp/widget @@ -1,8 +1,11 @@ #!/usr/bin/env ruby +# 漢字コード設定 ( tk.rb のロード時の encoding 推定/設定に使われる ) +$KCODE = 'euc' + # tk 関係ライブラリの読み込み require 'tk' -require 'tkafter' +# require 'tkafter' # widget demo directory 位置の獲得 $demo_dir = File.dirname($0) @@ -12,43 +15,106 @@ $root = TkRoot.new{title "Widget Demonstration"} # tk バージョンの取得 $tk_version = Tk::TK_VERSION +$tk_major_ver, $tk_minor_ver = $tk_version.split('.').map{|n| n.to_i} +$tk_patchlevel = Tk::TK_PATCHLEVEL # tcl_platform 情報へのアクセスオブジェクト $tk_platform = TkVarAccess.new('tcl_platform') # フォント設定 -$font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil) -knjfont = '-*-r-*--16-*-jisx0208.1983-0' -$kanji_font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', - knjfont) -TkOption.add('*kanjiFont', knjfont, 'startupFile') -$msg_kanji_font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', - '-*-r-*--24-*-jisx0208.1983-0') ####### -#case($tk_version) -#when /^4.*/ -# $font = '-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*' -# $kanji_font = '-*--16-*-jisx0208.1983-0' -# $msg_kanji_font = '-*--24-*-jisx0208.1983-0' -# $knjfont_opt = 'kanjifont' -# TkOption.add('*kanjiFont', $kanji_font, 'startupFile') -# -#when /^8.*/ -# Tk.tk_call('font', 'create', '@ascii', -# '-copy', '-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*') -# Tk.tk_call('font', 'create', '@kanji', -# '-copy', '-*--16-*-jisx0208.1983-0') -# Tk.tk_call('font', 'create', '@msg_knj', -# '-copy', '-*--24-*-jisx0208.1983-0') -# Tk.tk_call('font', 'create', '@cFont', '-compound', '@ascii @kanji') -# Tk.tk_call('font', 'create', '@cMsgFont', '-compound', '@ascii @msg_knj') -# $font = '-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*' -# $kanji_font = '@cFont' -# $msg_kanji_font = '@cMsgFont' -# $knjfont_opt = 'font' -#end +case($tk_version) +when /^4.*/ + $font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil) + knjfont = '-*--16-*-jisx0208.1983-0' + $kanji_font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', + knjfont) + TkOption.add('*kanjiFont', knjfont, 'startupFile') + $msg_kanji_font=TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', + '-*--24-*-jisx0208.1983-0') + +#when '8.0' +# $font = TkFont.new('Helvetica -12') +# $kanji_font = TkFont.new('Helvetica -12', 'Mincho -12') +# TkOption.add('*kanjiFont', knjfont, 'startupFile') +# $msg_kanji_font=TkFont.new('Helvetica 16', 'Gothic 16 bold') + +when /^8.*/ + $font = TkFont.new('Helvetica -12') + $kanji_font = TkFont.new('Helvetica -12', 'Mincho -12') + TkOption.add('*kanjiFont', knjfont, 'startupFile') + $msg_kanji_font=TkFont.new('Helvetica 16', 'Gothic 16 bold') + +else + $font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil) + knjfont = '-*--16-*-jisx0208.1983-0' + $kanji_font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', + knjfont) + TkOption.add('*kanjiFont', knjfont, 'startupFile') + $msg_kanji_font=TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', + '-*--24-*-jisx0208.1983-0') +end ####### +# イメージ設定 +$image = {} + +if $tk_major_ver >= 8 +$image['refresh'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><= 8 +$image['view'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><= 8 +$image['delete'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><= 8 +$image['print'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><'top', 'fill'=>'x') $root.bind('F1', proc{aboutBox}) +$root.bind('Meta-q', proc{exit}) =begin TkFrame.new($root){|frame| @@ -77,7 +144,7 @@ if $tk_version =~ /^4\.[01]/ txt = TkText.new($root) { #wrap 'word' wrap 'char' - width 60 + width 70 height 30 font $font setgrid 'yes' @@ -95,7 +162,7 @@ else txt = TkText.new($root) { #wrap 'word' wrap 'char' - width 60 + width 70 height 30 font $font setgrid 'yes' @@ -103,6 +170,7 @@ else padx 4 pady 2 takefocus 0 + bd 1 yscrollcommand proc{|first,last| scr.set first,last} } scr.command(proc{|*args| txt.yview(*args)}) @@ -124,11 +192,13 @@ end # テキストタグ設定 tag_title = TkTextTag.new(txt, 'font'=>'-*-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*') -tag_kanji_title = TkTextTag.new(txt, 'kanjifont'=>$msg_kanji_font) -tag_middle = TkTextTag.new(txt, 'kanjifont'=>$kanji_font) +#tag_kanji_title = TkTextTag.new(txt, 'kanjifont'=>$msg_kanji_font) +#tag_middle = TkTextTag.new(txt, 'kanjifont'=>$kanji_font) +tag_kanji_title = TkTextTag.new(txt, 'font'=>$msg_kanji_font) +tag_middle = TkTextTag.new(txt, 'font'=>$kanji_font) tag_demospace = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c') -if TkWinfo.depth($root) == '1' +if TkWinfo.depth($root) == 1 tag_demo = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', 'underline'=>1) $tag_visited = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', @@ -218,28 +288,34 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. チェックボタン (複数を選択可能)\n", tag_demo, "demo-check") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "5. ラジオボタン (任意の一つを選択可能)\n", +txt.insert('end', "5. 3状態チェックボタン (機能に対応したバージョンのTkが必要)\n", + tag_demo, "demo-check2") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "6. ラジオボタン (任意の一つを選択可能)\n", tag_demo, "demo-radio") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "6. ラジオボタン (機能に対応したバージョンのTkが必要)\n", +txt.insert('end', "7. ラジオボタン (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-radio2") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "7. ボタンで作られた15-パズルゲーム\n", +txt.insert('end', "8. 3状態ラジオボタン (機能に対応したバージョンのTkが必要)\n", + tag_demo, "demo-radio3") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "9. ボタンで作られた15-パズルゲーム\n", tag_demo, "demo-puzzle") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "8. ビットマップを使用したアイコンボタン\n", +txt.insert('end', "10. ビットマップを使用したアイコンボタン\n", tag_demo, "demo-icon") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "9. 画像を表示する二つのラベル\n", +txt.insert('end', "11. 画像を表示する二つのラベル\n", tag_demo, "demo-image1") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "10. 画像を見るための簡単なユーザインターフェース\n", +txt.insert('end', "12. 画像を見るための簡単なユーザインターフェース\n", tag_demo, "demo-image2") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "11. 画像を見るための簡単なユーザインターフェース (機能に対応したバージョンのTkが必要)\n", +txt.insert('end', "13. 画像を見るための簡単なユーザインターフェース (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-image3") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "12. ラベル付きフレーム (機能に対応したバージョンのTkが必要)\n", +txt.insert('end', "14. ラベル付きフレーム (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-labelframe") txt.insert('end', " \n ", tag_demospace) @@ -286,7 +362,10 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. ウィンドウを埋め込んだテキスト\n", tag_demo, "demo-twind") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "5. 検索\n", tag_demo, "demo-search") +txt.insert('end', "5. ウィンドウを埋め込んだテキスト (機能に対応したバージョンのTkが必要)\n", + tag_demo, "demo-twind2") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "6. 検索\n", tag_demo, "demo-search") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -305,7 +384,9 @@ txt.insert('end', "5. txt.insert('end', " \n ", tag_demospace) txt.insert('end', "6. フロアプラン\n", tag_demo, "demo-floor") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "7. スクロール可能なキャンバス\n", +txt.insert('end', "7. フロアプラン (異なるキャンバスアイテム作成方法を使用)\n", tag_demo, "demo-floor2") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "8. スクロール可能なキャンバス\n", tag_demo, "demo-cscroll") txt.insert('end', " \n ", tag_demospace) @@ -381,14 +462,14 @@ end # 親ウィジェットと,変数名と TkVariable との組(配列)の並びを渡す $showVarsWin = {} -def showVars (parent, *args) +def showVars1(parent, *args) if $showVarsWin[parent.path] begin $showVarsWin[parent.path].destroy rescue end end - w = TkToplevel.new(parent) {|w| + top = TkToplevel.new(parent) {|w| title "Variable values" TkLabel.new(w) { text "変数値:" @@ -413,7 +494,49 @@ def showVars (parent, *args) command proc{w.destroy} }.pack('side'=>'bottom', 'pady'=>2) } - $showVarsWin[parent.path] = w + $showVarsWin[parent.path] = top +end + +def showVars2(parent, *args) + if $showVarsWin[parent.path] + begin + $showVarsWin[parent.path].destroy + rescue + end + end + $showVarsWin[parent.path] = TkToplevel.new(parent) {|w| + title "Variable values" + + TkLabelFrame.new(w, :text=>"変数値:", + :font=>{:family=>'Helvetica', :size=>14}){|f| + args.each{|vnam,vbody| + TkGrid(TkLabel.new(f, :text=>"#{vnam}: ", :anchor=>'w'), + TkLabel.new(f, :textvariable=>vbody, :anchor=>'w'), + :padx=>2, :pady=>2, :sticky=>'w') + } + + f.grid(:sticky=>'news', :padx=>4) + f.grid_columnconfig(1, :weight=>1) + f.grid_rowconfig(100, :weight=>1) + } + TkButton.new(w, :text=>"了解", :width=>8, :default=>:active, + :command=>proc{w.destroy}){|b| + w.bind('Return', proc{b.invoke}) + w.bind('Escape', proc{b.invoke}) + + b.grid(:sticky=>'e', :padx=>4, :pady=>[6, 4]) + } + w.grid_columnconfig(0, :weight=>1) + w.grid_rowconfig(0, :weight=>1) + } +end + +if $tk_major_ver < 8 + alias showVars showVars1 +elsif $tk_major_ver == 8 && $tk_minor_ver < 4 + alias showVars showVars1 +else # ver >= 8.4 + alias showVars showVars2 end # テキスト上での click に対する動作 @@ -424,7 +547,8 @@ def invoke (txt, index) txt.cursor('watch') Tk.update # eval `cat #{tag[5..-1]}.rb` - eval `cat #{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb` +# eval `cat #{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb` + eval IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join Tk.update # txt.cursor('xterm') txt.cursor(cursor) @@ -449,14 +573,15 @@ def showStatus (txt, index) end # ソースコードの表示 -def showCode (demo) +def showCode1(demo) file = "#{demo}.rb" $code_window = nil unless defined? $code_window - if $code_window == nil || TkWinfo.exist?($code_window) == '0' + if $code_window == nil || TkWinfo.exist?($code_window) == false $code_window = TkToplevel.new(nil) f = TkFrame.new($code_window) TkButton.new(f) { - text "了解" + #text "了解" + text "閉じる" command proc{ $code_window.destroy $code_window = nil @@ -528,13 +653,194 @@ def showCode (demo) fid.close end +def showCode2(demo) + file = "#{demo}.rb" + $code_window = nil unless defined? $code_window + if $code_window == nil || TkWinfo.exist?($code_window) == false + $code_window = TkToplevel.new(nil) + tf = TkFrame.new($code_window) + $code_text = TkText.new(tf, :font=>'Courier 10', :height=>30, + :wrap=>'word', :bd=>1, :setgrid=>true, + :highlightthickness=>0, :pady=>2, :padx=>3) + xscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)} + yscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)} + TkGrid($code_text, yscr, :sticky=>'news') + #TkGrid(xscr) + tf.grid_rowconfigure(0, :weight=>1) + tf.grid_columnconfigure(0, :weight=>1) + + bf = TkFrame.new($code_window) + + #b_dis = TkButton.new(bf, :text=>'了解', :default=>:active, + b_dis = TkButton.new(bf, :text=>'閉じる', :default=>:active, + :command=>proc{ + $code_window.destroy + $code_window = nil + }, + :image=>$image['delete'], :compound=>:left) + b_prn = TkButton.new(bf, :text=>'印刷', + :command=>proc{printCode($code_text, file)}, + :image=>$image['print'], :compound=>:left) + b_run = TkButton.new(bf, :text=>'再実行', + :command=>proc{eval($code_text.get('1.0','end'))}, + :image=>$image['refresh'], :compound=>:left) + + TkGrid('x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4]) + bf.grid_columnconfigure(0, :weight=>1) + + TkGrid(tf, :sticky=>'news') + TkGrid(bf, :sticky=>'ew') + $code_window.grid_columnconfigure(0, :weight=>1) + $code_window.grid_rowconfigure(0, :weight=>1) + + $code_window.bind('Return', proc{|win| + b_dis.invoke unless win.kind_of?(TkText) + }, '%W') + $code_window.bindinfo('Return').each{|cmd, arg| + $code_window.bind_append('Escape', cmd, arg) + } + else + $code_window.deiconify + $code_window.raise + end + + $code_window.title("Demo code: #{file}") + $code_window.iconname(file) + fid = open([$demo_dir, file].join(File::Separator), 'r') + $code_text.delete('1.0', 'end') + $code_text.insert('1.0', fid.read) + TkTextMarkInsert.new($code_text,'1.0') + fid.close +end + +if $tk_major_ver < 8 + alias showCode showCode1 +elsif $tk_major_ver == 8 && $tk_minor_ver < 4 + alias showCode showCode1 +else # ver >= 8.4 + alias showCode showCode2 +end + + +# printCode -- +# Prints the source code currently displayed in the See Code dialog. +# Much thanks to Arjen Markus for this. +# +# Arguments: +# txt - Name of text widget containing code to print +# file - Name of the original file (implicitly for title) + +def printCode(txt, file) + code = txt.get('1.0', 'end - 1c') + dir = '.' + dir = ENV['HOME'] if ENV['HOME'] + dir = ENV['TMP'] if ENV['TMP'] + dir = ENV['TEMP'] if ENV['TEMP'] + + fname = [dir, 'tkdemo-' + file].join(File::Separator) + open(fname, 'w'){|fid| fid.print(code)} + begin + case Tk::TCL_PLATFORM('platform') + when 'unix' + msg = `lp -c #{fname}` + unless $?.exitstatus == 0 + Tk.messageBox(:title=>'Print spooling failure', + :message=>'エラーが発生しました.' + + '印刷に失敗したものと思われます : ' + msg) + end + when 'windows' + begin + printTextWin32(fname) + rescue => e + Tk.messageBox(:title=>'Print spooling failure', + :message=>'エラーが発生しました.' + + '印刷に失敗したものと思われます : ' + + e.message) + end + when 'macintosh' + Tk.messageBox(:title=>'Operation not Implemented', + :message=>'印刷機能はまだ実装されていません') + else + Tk.messageBox(:title=>'Operation not Implemented', + :message=>'検出された環境 ' + + Tk::TCL_PLATFORM('platform') + + ' は未知の環境であるため,' + + '印刷機能は実装されていません: ') + end + ensure + File.delete(fname) + end +end + +# printTextWin32 -- +# Print a file under Windows +# +# Arguments: +# filename - Name of the file +# +def printTextWin32(fname) + require 'win32/registry' + begin + app = Win32::Registry::HKEY_CLASSES_ROOT['.txt'] + pcmd = nil + Win32::Registry::HKEY_CLASSES_ROOT.open("#{app}\\shell\\print"){|reg| + pcmd = reg['command'] + } + rescue + app = Tk.tk_call('auto_execok', 'notepad.exe') + pcmd = "#{app} /p %1" + end + + pcmd.gsub!('%1', fname) + puts pcmd + cmd = Tk.tk_call('auto_execok', 'start') + ' /min ' + pcmd + + msg = `#{cmd}` + unless $?.exitstatus == 0 + fail RuntimeError, msg + end +end + # aboutBox # # Pops up a message box with an "about" message # def aboutBox Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', - 'message'=>"Ruby/Tk ウィジェットデモ Ver.1.3.2-jp\n\n( based on Tk ウィジェットデモ :: Copyright (c) 1996-1997 Sun Microsystems, Inc. )\n\nRunning Version :: Ruby#{VERSION}/Tk#{$tk_version}#{(Tk::JAPANIZED_TK)? 'jp': ''}") + 'message'=>"Ruby/Tk ウィジェットデモ Ver.1.4.3-jp\n\n" + + "based on demos of Tk8.1 -- 8.5 " + + "( Copyright:: " + + "(c) 1996-1997 Sun Microsystems, Inc. / " + + "(c) 1997-2000 Ajuba Solutions, Inc. / " + + "(c) 2001-2003 Donal K. Fellows )\n\n" + + "Your Ruby & Tk Version ::\n" + + "Ruby#{RUBY_VERSION}(#{RUBY_RELEASE_DATE})[#{RUBY_PLATFORM}] / Tk#{$tk_patchlevel}#{(Tk::JAPANIZED_TK)? '-jp': ''}") +end + +#################################### +# 引数で指定されたデモを起動する +no_launcher = false +if ARGV[0] == '-n' + ARGV.shift + no_launcher = true if ARGV.size > 0 +end +ARGV.each{|cmd| + if cmd =~ /(.*).rb/ + cmd = $1 + end + eval IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join +} +if no_launcher + $root.withdraw # hide root window + Thread.start{ + loop do + count = 0 + $root.winfo_children.each{|w| + count += 1 if w.kind_of?(TkToplevel) + } + $root.destroy if count == 0 + end + } end ################################ diff --git a/ext/tk/sample/encstr_usage.rb b/ext/tk/sample/encstr_usage.rb new file mode 100644 index 0000000000..2155544c64 --- /dev/null +++ b/ext/tk/sample/encstr_usage.rb @@ -0,0 +1,29 @@ +require 'tk' + +TkMessage.new(:width=>400, :text=><5).pack +t2 = TkText.new(:height=>5).pack +t3 = TkText.new(:height=>5).pack + +src_str = IO.readlines('iso2022-kr.txt').join + +t1.insert('end', + "use neither Tk::EncodedString class nor Tk.encoding= method\n\n") +t1.insert('end', src_str) + +enc_str = Tk::EncodedString(src_str, 'iso2022-kr') +t2.insert('end', + "use Tk::EncodedString class (Tk.encoding => '#{Tk.encoding}')\n\n") +t2.insert('end', enc_str) + +Tk.encoding = 'iso2022-kr' +t3.insert('end', "use Tk.encoding = 'iso2022-kr'\n\n") +t3.insert('end', src_str) + +Tk.mainloop diff --git a/ext/tk/sample/demos-en/images/earth.gif b/ext/tk/sample/images/earth.gif similarity index 53% rename from ext/tk/sample/demos-en/images/earth.gif rename to ext/tk/sample/images/earth.gif index 3ae4a9ce01..2c229eb110 100644 Binary files a/ext/tk/sample/demos-en/images/earth.gif and b/ext/tk/sample/images/earth.gif differ diff --git a/ext/tk/sample/demos-jp/images/earthris.gif b/ext/tk/sample/images/earthris.gif similarity index 61% rename from ext/tk/sample/demos-jp/images/earthris.gif rename to ext/tk/sample/images/earthris.gif index 48f08c4421..c4ee473727 100644 Binary files a/ext/tk/sample/demos-jp/images/earthris.gif and b/ext/tk/sample/images/earthris.gif differ diff --git a/ext/tk/sample/demos-en/images/face.xbm b/ext/tk/sample/images/face.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/face.xbm rename to ext/tk/sample/images/face.xbm diff --git a/ext/tk/sample/demos-en/images/flagdown.xbm b/ext/tk/sample/images/flagdown.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/flagdown.xbm rename to ext/tk/sample/images/flagdown.xbm diff --git a/ext/tk/sample/demos-en/images/flagup.xbm b/ext/tk/sample/images/flagup.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/flagup.xbm rename to ext/tk/sample/images/flagup.xbm diff --git a/ext/tk/sample/demos-en/images/gray25.xbm b/ext/tk/sample/images/gray25.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/gray25.xbm rename to ext/tk/sample/images/gray25.xbm diff --git a/ext/tk/sample/demos-en/images/grey.25 b/ext/tk/sample/images/grey.25 similarity index 100% rename from ext/tk/sample/demos-en/images/grey.25 rename to ext/tk/sample/images/grey.25 diff --git a/ext/tk/sample/demos-en/images/grey.5 b/ext/tk/sample/images/grey.5 similarity index 100% rename from ext/tk/sample/demos-en/images/grey.5 rename to ext/tk/sample/images/grey.5 diff --git a/ext/tk/sample/demos-en/images/letters.xbm b/ext/tk/sample/images/letters.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/letters.xbm rename to ext/tk/sample/images/letters.xbm diff --git a/ext/tk/sample/demos-en/images/noletter.xbm b/ext/tk/sample/images/noletter.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/noletter.xbm rename to ext/tk/sample/images/noletter.xbm diff --git a/ext/tk/sample/demos-en/images/pattern.xbm b/ext/tk/sample/images/pattern.xbm similarity index 100% rename from ext/tk/sample/demos-en/images/pattern.xbm rename to ext/tk/sample/images/pattern.xbm diff --git a/ext/tk/sample/demos-jp/images/tcllogo.gif b/ext/tk/sample/images/tcllogo.gif similarity index 86% rename from ext/tk/sample/demos-jp/images/tcllogo.gif rename to ext/tk/sample/images/tcllogo.gif index 3fc7720b17..4603d4ff41 100644 Binary files a/ext/tk/sample/demos-jp/images/tcllogo.gif and b/ext/tk/sample/images/tcllogo.gif differ diff --git a/ext/tk/sample/demos-en/images/teapot.ppm b/ext/tk/sample/images/teapot.ppm similarity index 100% rename from ext/tk/sample/demos-en/images/teapot.ppm rename to ext/tk/sample/images/teapot.ppm diff --git a/ext/tk/sample/iso2022-kr.txt b/ext/tk/sample/iso2022-kr.txt new file mode 100644 index 0000000000..2e3fe6ea2a --- /dev/null +++ b/ext/tk/sample/iso2022-kr.txt @@ -0,0 +1,2 @@ +Sample text: +$)C Hangul (GQ1[) >H3gGO<H3gGO=J4O1n diff --git a/ext/tk/sample/msgs_rb/README b/ext/tk/sample/msgs_rb/README new file mode 100644 index 0000000000..2e3ff2a9c4 --- /dev/null +++ b/ext/tk/sample/msgs_rb/README @@ -0,0 +1,3 @@ +Message catalogs in this directory depend on Tcl/Tk's message catalogs. +Texts of each locale are copied from Tcl/Tk8.5a1 widget demos. +Please refer '../msgs_tk/README'. diff --git a/ext/tk/sample/msgs_rb/cs.msg b/ext/tk/sample/msgs_rb/cs.msg new file mode 100644 index 0000000000..199f2a73bd --- /dev/null +++ b/ext/tk/sample/msgs_rb/cs.msg @@ -0,0 +1,84 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + cs "Application Error", "Chyba programu" + cs "Blue", "Modr\341" + cs "Color", "Barva" + cs "Delete", "Smazat" + cs "Error", "Chyba" + cs "Exit", "Konec" + cs "Green", "Zelen\341" + cs "Red", "\\u010cerven\341" + cs "blue", "modr\341" + cs "green", "zelen\341" + cs "red", "\\u010derven\341" +} + +TkMsgCatalog.new('::tk') { + cs "&Abort", "&P\\u0159eru\\u0161it" + cs "About...", "O programu..." + cs "All Files", "V\\u0161echny soubory" + cs "Application Error", "Chyba programu" + cs "&Blue", "&Modr\341" + cs "&Cancel", "&Zru\\u0161it" + cs "Cannot change to the directory \"%1\$s\".\nPermission denied.", "Nemohu zm\\u011bnit atku\341ln\355 adres\341\\u0159 na \"%1\$s\".\nP\\u0159\355stup odm\355tnut." + cs "Choose Directory", "V\375b\\u011br adres\341\\u0159e" + cs "Clear", "Smazat" + cs "Color", "Barva" + cs "Console", "Konzole" + cs "Copy", "Kop\355rovat" + cs "Cut", "Vy\\u0159\355znout" + cs "Delete", "Smazat" + cs "Details >>", "Detaily >>" + cs "Directory \"%1\$s\" does not exist.", "Adres\341\\u0159 \"%1\$s\" neexistuje." + cs "&Directory:", "&Adres\341\\u0159:" + cs "Error: %1\$s", "Chyba: %1\$s" + cs "Exit", "Konec" + cs "File \"%1\$s\" already exists.\n\n", "Soubor \"%1\$s\" ji\\u017e existuje.\n\n" + cs "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "Soubor \"%1\$s\" ji\\u017e existuje.\nChcete jej p\\u0159epsat?" + cs "File \"%1\$s\" does not exist.", "Soubor \"%1\$s\" neexistuje." + cs "File &name:", "&Jm\351no souboru:" + cs "File &names:", "&Jm\351na soubor\\u016f:" + cs "Files of &type:", "&Typy soubor\\u016f:" + cs "Fi&les:", "Sou&bory:" + cs "&Filter", "&Filtr" + cs "Fil&ter:", "Fil&tr:" + cs "&Green", "Ze&len\341" + cs "Hi" + cs "Hide Console", "Skr\375t konsolu" + cs "&Ignore", "&Ignorovat" + cs "Invalid file name \"%1\$s\".", "\\u0160patn\351 jm\351no souboru \"%1\$s\"." + cs "Log Files", "Log soubory" + cs "&No", "&Ne" + cs "&OK" + cs "Ok" + cs "Open", "Otev\\u0159\355t" + cs "&Open", "&Otev\\u0159\355t" + cs "Open Multiple Files", "Otev\\u0159\355t v\355ce soubor\\u016f" + cs "Paste", "Vlo\\u017eit" + cs "Quit", "Skon\\u010dit" + cs "&Red", " \\u010ce&rven\341" + cs "Replace existing file?", "Nahradit st\341vaj\355c\355 soubor?" + cs "&Retry", "Z&novu" + cs "&Save", "&Ulo\\u017eit" + cs "Save As", "Ulo\\u017eit jako" + cs "Save To Log", "Ulo\\u017eit do logu" + cs "Select Log File", "Vybrat log soubor" + cs "Select a file to source", "Vybrat soubor k nahr\341n\355" + cs "&Selection:", "&V\375b\\u011br:" + cs "Skip Messages", "P\\u0159esko\\u010dit zpr\341vy" + cs "Source...", "Nahr\341t..." + cs "Tcl Scripts", "Tcl skripty" + cs "Tcl for Windows", "Tcl pro Windows" + cs "Text Files", "Textov\351 soubory" + cs "&Yes", "&Ano" + cs "abort", "p\\u0159eru\\u0161it" + cs "blue", "modr\341" + cs "cancel", "zru\\u0161it" + cs "extension", "p\\u0159\355pona" + cs "extensions", "p\\u0159\355pony" + cs "green", "zelen\341" + cs "ignore", "ignorovat" + cs "ok" + cs "red", "\\u010derven\341" + cs "retry", "znovu" + cs "yes", "ano" +} diff --git a/ext/tk/sample/msgs_rb/de.msg b/ext/tk/sample/msgs_rb/de.msg new file mode 100644 index 0000000000..283874df42 --- /dev/null +++ b/ext/tk/sample/msgs_rb/de.msg @@ -0,0 +1,88 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + de "Application Error", "Applikationsfehler" + de "Blue", "Blau" + de "Color", "Farbe" + de "Delete", "L\\u00f6schen" + de "Error", "Fehler" + de "Exit", "Ende" + de "Green", "Gr\\u00fcn" + de "Red", "Rot" + de "blue", "blau" + de "green", "gr\\u00fcn" + de "red", "rot" +} + +TkMsgCatalog.new('::tk') { + de "&Abort", "&Abbruch" + de "&About...", "&\\u00dcber..." + de "All Files", "Alle Dateien" + de "Application Error", "Applikationsfehler" + de "&Blue", "&Blau" + de "&Cancel", "&Abbruch" + de "Cannot change to the directory \"%1\$s\".\nPermission denied.", "Kann nicht in das Verzeichnis \"%1\$s\" wechseln.\nKeine Rechte vorhanden." + de "Choose Directory", "W\\u00e4hle Verzeichnis" + de "&Clear", "&R\\u00fccksetzen" + de "&Clear Console", "&Konsole l\\u00f6schen" + de "Color", "Farbe" + de "Console", "Konsole" + de "&Copy", "&Kopieren" + de "Cu&t", "Aus&schneiden" + de "&Delete", "&L\\u00f6schen" + de "Details >>" + de "Directory \"%1\$s\" does not exist.", "Das Verzeichnis \"%1\$s\" existiert nicht." + de "&Directory:", "&Verzeichnis:" + de "&Edit", "&Bearbieten" + de "Error: %1\$s", "Fehler: %1\$s" + de "E&xit", "&Ende" + de "&File", "&Datei" + de "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei \\u00fcberschreiben ?" + de "File \"%1\$s\" already exists.\n\n", "Die Datei \"%1\$s\" ist bereits vorhanden.\n\n" + de "File \"%1\$s\" does not exist.", "Die Datei \"%1\$s\" existiert nicht." + de "File &name:", "Datei&name:" + de "File &names:", "Datei&namen:" + de "Files of &type:", "Dateien des &Typs:" + de "Fi&les:", "Dat&eien:" + de "&Filter" + de "Fil&ter:" + de "&Green", "&Gr\\u00fcn" + de "&Help", "&Hilfe" + de "Hi", "Hallo" + de "&Hide Console", "&Konsole unsichtbar machen" + de "&Ignore", "&Ignorieren" + de "Invalid file name \"%1\$s\".", "Ung\\u00fcltiger Dateiname \"%1\$s\"." + de "Log Files", "Protokolldatei" + de "&No", "&Nein" + de "OK" + de "Ok" + de "Open", "\\u00d6ffnen" + de "&Open", "\\u00d6&ffnen" + de "Open Multiple Files" + de "P&aste", "E&inf\\u00fcgen" + de "&Quit", "&Beenden" + de "&Red", "&Rot" + de "Replace existing file?", "Existierende Datei ersetzen?" + de "&Retry", "&Wiederholen" + de "&Save", "&Speichern" + de "Save As", "Speichern unter" + de "Save To Log", "In Protokoll speichern" + de "Select Log File", "Protokolldatei ausw\\u00e4hlen" + de "Select a file to source", "Auszuf\\u00fchrende Datei ausw\\u00e4hlen" + de "&Selection:", "Auswah&l:" + de "Skip Messages", "Weitere Nachrichten \\u00fcberspringen" + de "&Source...", "&Ausf\\u00fchren..." + de "Tcl Scripts", "Tcl-Skripte" + de "Tcl for Windows", "Tcl f\\u00fcr Windows" + de "Text Files", "Textdateien" + de "&Yes", "&Ja" + de "abort", "abbrechen" + de "blue", "blau" + de "cancel", "abbrechen" + de "extension", "Erweiterung" + de "extensions", "Erweiterungen" + de "green", "gr\\u00fcn" + de "ignore", "ignorieren" + de "ok" + de "red", "rot" + de "retry", "wiederholen" + de "yes", "ja" +} diff --git a/ext/tk/sample/msgs_rb/el.msg b/ext/tk/sample/msgs_rb/el.msg new file mode 100644 index 0000000000..f314ae03eb --- /dev/null +++ b/ext/tk/sample/msgs_rb/el.msg @@ -0,0 +1,98 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + el 'Application Error', '\u039b\u03ac\u03b8\u03bf\u03c2 \u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2' + el 'Blue', '\u039c\u03c0\u03bb\u03b5' + el 'Color', '\u03a7\u03c1\u03ce\u03bc\u03b1' + el 'Delete', '\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae' + el 'Error', '\u039b\u03ac\u03b8\u03bf\u03c2' + el 'Exit', '\u0388\u03be\u03bf\u03b4\u03bf\u03c2' + el 'Green', '\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf' + el 'Red', '\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf' + el 'blue', '\u03bc\u03c0\u03bb\u03b5' + el 'green', '\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf' + el 'red', '\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf' +} + +TkMsgCatalog.new('::tk') { + el '&Abort', '\u03a4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2' + el 'About...', '\u03a3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac...' + el 'All Files', '\u038c\u03bb\u03b1 \u03c4\u03b1 \u0391\u03c1\u03c7\u03b5\u03af\u03b1' + el 'Application Error', '\u039b\u03ac\u03b8\u03bf\u03c2 \u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2' + el '&Blue', '\u039c\u03c0\u03bb\u03b5' + el '&Cancel', '\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7' + el 'Cannot change to the directory "%1\$s".' "\n" 'Permission denied.', \ + '\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bb\u03bb\u03b1\u03b3\u03ae \u03ba\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5 \u03c3\u03b5 "%1\$s".' \ + "\n" \ + '\u0397 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03b4\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03c4\u03b1\u03b9.' + el 'Choose Directory', '\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u039a\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5' + el 'Clear', '\u039a\u03b1\u03b8\u03b1\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2' + el 'Color', '\u03a7\u03c1\u03ce\u03bc\u03b1' + el 'Console', '\u039a\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1' + el 'Copy', '\u0391\u03bd\u03c4\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae' + el 'Cut', '\u0391\u03c0\u03bf\u03ba\u03bf\u03c0\u03ae' + el 'Delete', '\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae' + el 'Details >>', '\u039b\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2 >>' + el 'Directory "%1\$s", does not exist.', \ + '\u039f \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 \'%1\$s\' \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.' + el '&Directory:', '&\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2:' + el 'Error: %1\$s', '\u039b\u03ac\u03b8\u03bf\u03c2: %1\$s' + el 'Exit', '\u0388\u03be\u03bf\u03b4\u03bf\u03c2' + el 'File "%1\$s" already exists.' "\n" 'Do you want to overwrite it?', \ + '\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf "%1\$s" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.' \ + "\n" \ + '\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03c0\u03b9\u03ba\u03b1\u03bb\u03c5\u03c6\u03b8\u03b5\u03af;' + el 'File "%1\$s" already exists.' "\n\n", \ + '\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf "%1\$s" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.' "\n\n" + el 'File "%1\$s" does not exist.', \ + '\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf "%1\$s" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.' + el 'File &name:', '\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5:' + el 'File &names:', '\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd:' + el 'Files of &type:', '\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03c4\u03bf\u03c5 &\u03c4\u03cd\u03c0\u03bf\u03c5:' + el 'Fi&les:', '\u0391\u03c1\u03c7\u03b5\u03af\u03b1:' + el '&Filter', '\u03a6\u03af\u03bb\u03c4\u03c1\u03bf' + el 'Fil&ter:', '\u03a6\u03af\u03bb\u03c4\u03c1\u03bf:' + el '&Green', '\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf' + el 'Hi', '\u0393\u03b5\u03b9\u03b1' + el 'Hide Console', '\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03ba\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1\u03c2' + el '&Ignore', '\u0391\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7' + el 'Invalid file name "%1\$s".', \ + '\u0386\u03ba\u03c5\u03c1\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 "%1\$s".' + el 'Log Files', '\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2' + el '&No', '\u038c\u03c7\u03b9' + el '&OK', '\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9' + el '&Ok', '\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9' + el 'Open', '\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1' + el '&Open', '\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1' + el 'Open Multiple Files', \ + '\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bf\u03bb\u03bb\u03b1\u03c0\u03bb\u03ce\u03bd \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd' + el 'Paste', '\u0395\u03c0\u03b9\u03ba\u03cc\u03bb\u03bb\u03b7\u03c3\u03b7' + el 'Quit', '\u0388\u03be\u03bf\u03b4\u03bf\u03c2' + el '&Red', '\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf' + el 'Replace existing file?', \ + '\u0395\u03c0\u03b9\u03ba\u03ac\u03bb\u03c5\u03c8\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03bd\u03c4\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5;' + el '&Retry', '\u03a0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac' + el '&Save', '\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7' + el 'Save As', '\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03b1\u03bd' + el 'Save To Log', '\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2' + el 'Select Log File', '\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2' + el 'Select a file to source', \ + '\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b3\u03b9\u03b1 \u03b5\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7' + el '&Selection:', '\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae:' + el 'Skip Messages', '\u0391\u03c0\u03bf\u03c6\u03c5\u03b3\u03ae \u03bc\u03c5\u03bd\u03b7\u03bc\u03ac\u03c4\u03c9\u03bd' + el 'Source...', '\u0395\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7...' + el 'Tcl Scripts', 'Tcl Scripts' + el 'Tcl for Windows', 'Tcl \u03b3\u03b9\u03b1 Windows' + el 'Text Files', '\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5' + el '&Yes', '\u039d\u03b1\u03b9' + el 'abort', '\u03c4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2' + el 'blue', '\u03bc\u03c0\u03bb\u03b5' + el 'cancel', '\u03b1\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7' + el 'extension', '\u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7' + el 'extensions', '\u03b5\u03c0\u03b5\u03ba\u03c4\u03ac\u03c3\u03b5\u03b9\u03c2' + el 'green', '\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf' + el 'ignore', '\u03b1\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7' + el 'ok', '\u03b5\u03bd\u03c4\u03ac\u03be\u03b5\u03b9' + el 'red', '\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf' + el 'retry', '\u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac' + el 'yes', '\u03bd\u03b1\u03b9' +} + diff --git a/ext/tk/sample/msgs_rb/en.msg b/ext/tk/sample/msgs_rb/en.msg new file mode 100644 index 0000000000..9b70239511 --- /dev/null +++ b/ext/tk/sample/msgs_rb/en.msg @@ -0,0 +1,83 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + en "Application Error" + en "Blue" + en "Color" + en "Delete" + en "Error" + en "Green" + en "Red" + en "blue" + en "green" + en "red" +} + +TkMsgCatalog.new('::tk') { + en "&Abort" + en "About..." + en "All Files" + en "Application Error" + en "&Blue" + en "&Cancel" + en "Cannot change to the directory \"%1\$s\".\nPermission denied." + en "Choose Directory" + en "Clear" + en "Color" + en "Console" + en "Copy" + en "Cut" + en "Delete" + en "Details >>" + en "Directory \"%1\$s\" does not exist." + en "&Directory:" + en "Error: %1\$s" + en "Exit" + en "File \"%1\$s\" already exists.\nDo you want to overwrite it?" + en "File \"%1\$s\" already exists.\n\n" + en "File \"%1\$s\" does not exist." + en "File &name:" + en "File &names:" + en "Files of &type:" + en "Fi&les:" + en "&Filter" + en "Fil&ter:" + en "&Green" + en "Hi" + en "Hide Console" + en "&Ignore" + en "Invalid file name \"%1\$s\"." + en "Log Files" + en "&No" + en "&OK" + en "Ok" + en "Open" + en "&Open" + en "Open Multiple Files" + en "Paste" + en "Quit" + en "&Red" + en "Replace existing file?" + en "&Retry" + en "&Save" + en "Save As" + en "Save To Log" + en "Select Log File" + en "Select a file to source" + en "&Selection:" + en "Skip Messages" + en "Source..." + en "Tcl Scripts" + en "Tcl for Windows" + en "Text Files" + en "&Yes" + en "abort" + en "blue" + en "cancel" + en "extension" + en "extensions" + en "green" + en "ignore" + en "ok" + en "red" + en "retry" + en "yes" +} diff --git a/ext/tk/sample/msgs_rb/en_gb.msg b/ext/tk/sample/msgs_rb/en_gb.msg new file mode 100644 index 0000000000..97c58959b1 --- /dev/null +++ b/ext/tk/sample/msgs_rb/en_gb.msg @@ -0,0 +1,7 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + en_gb 'Color', 'Colour' +} + +TkMsgCatalog.new('::tk') { + en_gb 'Color', 'Colour' +} diff --git a/ext/tk/sample/msgs_rb/eo.msg b/ext/tk/sample/msgs_rb/eo.msg new file mode 100644 index 0000000000..1630df5e83 --- /dev/null +++ b/ext/tk/sample/msgs_rb/eo.msg @@ -0,0 +1,87 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + eo 'Application Error', 'Aplikoerraro' + eo 'Blue', 'Blua' + eo 'Color', 'Farbo' + eo 'Delete', 'Forprenu' + eo 'Error', 'Eraro' + eo 'Exit', 'Eliru' + eo 'Green', 'Verda' + eo 'Red', 'Rosa' + eo 'blue', 'blua' + eo 'green', 'verda' + eo 'red', 'ru\u011da' +} + +TkMsgCatalog.new('::tk') { + eo '&Abort', '&\u0108esigo' + eo '&About...', 'Pri...' + eo 'All Files', '\u0108ioj dosieroj' + eo 'Application Error', 'Aplikoerraro' + eo '&Blue', '&Blua' + eo '&Cancel', '&Rezignu' + eo 'Cannot change to the directory "%1\$s".' "\n" 'Permission denied.', 'Neeble \u0109angi al dosierulon "%1\$s".' "\n" 'Vi ne rajtas tion.' + eo 'Choose Directory', 'Elektu Dosierujo' + eo '&Clear', '&Klaru' + eo '&Clear Console', '&Klaru konzolon' + eo 'Color', 'Farbo' + eo 'Console', 'Konzolo' + eo '&Copy', '&Kopiu' + eo 'Cu&t', '&Enpo\u015digu' + eo '&Delete', '&Forprenu' + eo 'Details >>', 'Detaloj >>' + eo 'Directory "%1\$s" does not exist.', 'La dosierujo "%1\$s" ne ekzistas.' + eo '&Directory:', '&Dosierujo:' + eo '&Edit', '&Redaktu' + eo 'Error: %1\$s', 'Eraro: %1\$s' + eo 'E&xit', '&Eliru' + eo '&File', '&Dosiero' + eo 'File "%1\$s" already exists.' "\n" 'Do you want to overwrite it?', 'La dosiero "%1\$s" jam ekzistas.' "\n" '\u0108u vi volas anstata\u00fbigi la dosieron?' + eo 'File "%1\$s" already exists.' "\n\n", 'La dosiero "%1\$s" jam egzistas.' "\n\n" + eo 'File "%1\$s" does not exist.', 'La dosierp "%1\$s" ne estas.' + eo 'File &name:', 'Dosiero&nomo:' + eo 'File &names:', 'Dosiero&nomoj:' + eo 'Files of &type:', 'Dosieroj de &Typo:' + eo 'Fi&les:', 'Do&sieroj:' + eo '&Filter', '&Filtrilo' + eo 'Fil&ter:', '&Filtrilo:' + eo '&Green', '&Verda' + eo '&Help', '&Helpu' + eo 'Hi', 'Saluton' + eo '&Hide Console', '&Ka\u015du konzolon' + eo '&Ignore', '&Ignoru' + eo 'Invalid file name "%1\$s".', 'Malvalida dosieronomo "%1\$s".' + eo 'Log Files', 'Protokolo' + eo '&No', '&Ne' + eo 'OK' + eo 'Ok' + eo 'Open', 'Malfermu' + eo '&Open', '&Malfermu' + eo 'Open Multiple Files', 'Melfermu multan dosierojn' + eo 'P&aste', '&Elpo\u015digi' + eo '&Quit', '&Finigu' + eo '&Red', '&Rosa' + eo 'Replace existing file?', '\u0108u anstata\u00fbu ekzistantan dosieron?' + eo '&Retry', '&Ripetu' + eo '&Save', '&Savu' + eo 'Save As', 'Savu kiel' + eo 'Save To Log', 'Savu en protokolon' + eo 'Select Log File', 'Elektu prokolodosieron' + eo 'Select a file to source', 'Elektu dosieron por interpreti' + eo '&Selection:', '&Elekto:' + eo 'Skip Messages', 'transsaltu pluajn mesa\u011dojn' + eo '&Source...', '&Fontoprogramo...' + eo 'Tcl Scripts', 'Tcl-skriptoj' + eo 'Tcl for Windows', 'Tcl por vindoso' + eo 'Text Files', 'Tekstodosierojn' + eo '&Yes', '&Jes' + eo 'abort', '\u0109esigo' + eo 'blue', 'blua' + eo 'cancel', 'rezignu' + eo 'extension', 'ekspansio' + eo 'extensions', 'ekspansioj' + eo 'green', 'verda' + eo 'ignore', 'ignorieren' + eo 'red', 'ru\u011da' + eo 'retry', 'ripetu' + eo 'yes', 'jes' +} diff --git a/ext/tk/sample/msgs_rb/es.msg b/ext/tk/sample/msgs_rb/es.msg new file mode 100644 index 0000000000..460dbe848c --- /dev/null +++ b/ext/tk/sample/msgs_rb/es.msg @@ -0,0 +1,84 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + es "Application Error", "Error de la aplicaci\\u00f3n" + es "Blue", "Azul" + es "Color", "Color" + es "Delete", "Borrar" + es "Error", "Error" + es "Exit", "Salir" + es "Green", "Verde" + es "Red", "Rojo" + es "blue", "azul" + es "green", "verde" + es "red", "rojo" +} + +TkMsgCatalog.new('::tk') { + es "&Abort", "&Abortar" + es "About...", "Acerca de ..." + es "All Files", "Todos los archivos" + es "Application Error", "Error de la aplicaci\\u00f3n" + es "&Blue", "&Azul" + es "&Cancel", "&Cancelar" + es "Cannot change to the directory \"%1\$s\".\nPermission denied.", "No es posible acceder al directorio \"%1\$s\".\nPermiso denegado." + es "Choose Directory", "Elegir directorio" + es "Clear", "Borrar" + es "Color", "Color" + es "Console", "Consola" + es "Copy", "Copiar" + es "Cut", "Cortar" + es "Delete", "Borrar" + es "Details >>", "Detalles >>" + es "Directory \"%1\$s\" does not exist.", "El directorio \"%1\$s\" no existe." + es "&Directory:", "&Directorio:" + es "Error: %1\$s", "Error: %1\$s" + es "Exit", "Salir" + es "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "El archivo \"%1\$s\" ya existe.\nDesea sobreescribirlo?" + es "File \"%1\$s\" already exists.\n\n", "El archivo \"%1\$s\" ya existe.\n\n" + es "File \"%1\$s\" does not exist.", "El archivo \"%1\$s\" no existe." + es "File &name:", "&Nombre de archivo:" + es "File &names:", "&Nombres de archivo:" + es "Files of &type:", "Archivos de &tipo:" + es "Fi&les:", "&Archivos:" + es "&Filter", "&Filtro" + es "Fil&ter:", "Fil&tro:" + es "&Green", "&Verde" + es "Hi", "Hola" + es "Hide Console", "Esconder la consola" + es "&Ignore", "&Ignorar" + es "Invalid file name \"%1\$s\".", "Nombre de archivo inv\\u00e1lido \"%1\$s\"." + es "Log Files", "Ficheros de traza" + es "&No", "&No" + es "&OK", "&OK" + es "Ok", "Ok" + es "Open", "Abrir" + es "&Open", "&Abrir" + es "Open Multiple Files", "Abrir m\\u00faltiples archivos" + es "Paste", "Pegar" + es "Quit", "Abandonar" + es "&Red", "&Rojo" + es "Replace existing file?", "Reemplazar el archivo existente?" + es "&Retry", "&Reintentar" + es "&Save", "&Salvar" + es "Save As", "Salvar como" + es "Save To Log", "Salvar al archivo de traza" + es "Select Log File", "Elegir un archivo de traza" + es "Select a file to source", "Seleccionar un archivo a evaluar" + es "&Selection:", "&Selecci\\u00f3n:" + es "Skip Messages", "Omitir los mensajes" + es "Source...", "Evaluar..." + es "Tcl Scripts", "Scripts Tcl" + es "Tcl for Windows", "Tcl para Windows" + es "Text Files", "Archivos de texto" + es "&Yes", "&S\\u00ed" + es "abort", "abortar" + es "blue", "azul" + es "cancel", "cancelar" + es "extension", "extensi\\u00f3n" + es "extensions", "extensiones" + es "green", "verde" + es "ignore", "ignorar" + es "ok", "ok" + es "red", "rojo" + es "retry", "reintentar" + es "yes", "s\\u00ed" +} diff --git a/ext/tk/sample/msgs_rb/fr.msg b/ext/tk/sample/msgs_rb/fr.msg new file mode 100644 index 0000000000..ea85cf1a39 --- /dev/null +++ b/ext/tk/sample/msgs_rb/fr.msg @@ -0,0 +1,84 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + fr 'Application Error', "Erreur d'application" + fr 'Blue', 'Bleu' + fr 'Color', 'Couleur' + fr 'Delete', 'Effacer' + fr 'Error', 'Erreur' + fr 'Exit', 'Quitter' + fr 'Green', 'Vert' + fr 'Red', 'Rouge' + fr 'blue', 'bleu' + fr 'green', 'vert' + fr 'red', 'rouge' +} + +TkMsgCatalog.new('::tk') { + fr '&Abort', '&Annuler' + fr 'About...', '\u00c0 propos...' + fr 'All Files', 'Tous les fichiers' + fr 'Application Error', "Erreur d'application" + fr '&Blue', '&Bleu' + fr '&Cancel', '&Annuler' + fr 'Cannot change to the directory "%1\$s".' "\n" 'Permission denied.', 'Impossible d\'acc\u00e9der au r\u00e9pertoire "%1\$s".' "\n" 'Permission refus\u00e9e.' + fr 'Choose Directory', 'Choisir r\u00e9pertoire' + fr 'Clear', 'Effacer' + fr 'Color', 'Couleur' + fr 'Console' + fr 'Copy', 'Copier' + fr 'Cut', 'Couper' + fr 'Delete', 'Effacer' + fr 'Details >>', 'D\u00e9tails >>' + fr 'Directory "%1\$s" does not exist.', 'Le r\u00e9pertoire "%1\$s" n\'existe pas.' + fr '&Directory:', '&R\u00e9pertoire:' + fr 'Error: %1\$s', 'Erreur: %1\$s' + fr 'Exit', 'Quitter' + fr 'File "%1\$s" already exists.' "\n" 'Do you want to overwrite it?', 'Le fichier "%1\$s" existe d\u00e9j\u00e0.' "\n" 'Voulez-vous l\'\u00e9craser?' + fr 'File "%1\$s" already exists.' "\n\n", 'Le fichier "%1\$s" existe d\u00e9j\u00e0.' "\n\n" + fr 'File "%1\$s" does not exist.', 'Le fichier "%1\$s" n\'existe pas.' + fr 'File &name:', '&Nom de fichier:' + fr 'File &names:', '&Noms de fichiers:' + fr 'Files of &type:', '&Type de fichiers:' + fr 'Fi&les:', 'Fich&iers:' + fr '&Filter', '&Filtre' + fr 'Fil&ter:', 'Fil&tre:' + fr '&Green', '&Vert' + fr 'Hi', 'Salut' + fr 'Hide Console', 'Cacher la Console' + fr '&Ignore', '&Ignorer' + fr 'Invalid file name "%1\$s".', 'Nom de fichier invalide "%1\$s".' + fr 'Log Files', 'Fichiers de trace' + fr '&No', '&Non' + fr '&OK' + fr 'Ok' + fr 'Open', 'Ouvrir' + fr '&Open', '&Ouvrir' + fr 'Open Multiple Files', 'Ouvrir plusieurs fichiers' + fr 'Paste', 'Coller' + fr 'Quit', 'Quitter' + fr '&Red', '&Rouge' + fr 'Replace existing file?', 'Remplacer le fichier existant?' + fr '&Retry', '&R\u00e9-essayer' + fr '&Save', '&Sauvegarder' + fr 'Save As', 'Sauvegarder sous' + fr 'Save To Log', 'Sauvegarde au fichier de trace' + fr 'Select Log File', 'Choisir un fichier de trace' + fr 'Select a file to source', 'Choisir un fichier \u00e0 \u00e9valuer' + fr '&Selection:', '&S\u00e9lection:' + fr 'Skip Messages', 'Omettre les messages' + fr 'Source...', '\u00c9valuer...' + fr 'Tcl Scripts', 'Scripts Tcl' + fr 'Tcl for Windows', 'Tcl pour Windows' + fr 'Text Files', 'Fichiers texte' + fr '&Yes', '&Oui' + fr 'abort', 'abandonner' + fr 'blue', 'bleu' + fr 'cancel', 'annuler' + fr 'extension' + fr 'extensions' + fr 'green', 'vert' + fr 'ignore', 'ignorer' + fr 'ok' + fr 'red', 'rouge' + fr 'retry', 'r\u00e9essayer' + fr 'yes', 'oui' +} diff --git a/ext/tk/sample/msgs_rb/it.msg b/ext/tk/sample/msgs_rb/it.msg new file mode 100644 index 0000000000..a180bdbd99 --- /dev/null +++ b/ext/tk/sample/msgs_rb/it.msg @@ -0,0 +1,84 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + it "Application Error", "Errore dell' applicazione" + it "Blue", "Blu" + it "Color", "Colore" + it "Delete", "Incolla" + it "Error", "Errore" + it "Exit", "Esci" + it "Green", "Verde" + it "Red", "Rosso" + it "blue", "blu" + it "green", "verde" + it "red", "rosso" +} + +TkMsgCatalog.new('::tk') { + it "&Abort", "&Interrompi" + it "About...", "Informazioni ..." + it "All Files", "Tutti i file" + it "Application Error", "Errore dell' applicazione" + it "&Blue", "&Blu" + it "&Cancel", "&Annulla" + it "Cannot change to the directory \"%1\$s\".\nPermission denied.", "Impossibile accedere alla directory \"%1\$s\".\nPermesso negato." + it "Choose Directory", "Scegli directory" + it "Clear", "Azzera" + it "Color", "Colore" + it "Console" + it "Copy", "Copia" + it "Cut", "Taglia" + it "Delete", "Incolla" + it "Details >>", "Dettagli >>" + it "Directory \"%1\$s\" does not exist.", "La directory \"%1\$s\" non esiste." + it "&Directory:" + it "Error: %1\$s", "Errore: %1\$s" + it "Exit", "Esci" + it "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "Il file \"%1\$s\" esiste gi\\u00e0.\nVuoi sovrascriverlo?" + it "File \"%1\$s\" already exists.\n\n", "Il file \"%1\$s\" esiste gi\\u00e0.\n\n" + it "File \"%1\$s\" does not exist.", "Il file \"%1\$s\" non esiste." + it "File &name:", "&Nome del file:" + it "File &names:", "&Nomi dei file:" + it "Files of &type:", "File di &tipo:" + it "Fi&les:", "Fi&le:" + it "&Filter", "&Filtro" + it "Fil&ter:", "Fil&tro:" + it "&Green", "&Verde" + it "Hi", "Salve" + it "Hide Console", "Nascondi la console" + it "&Ignore", "&Ignora" + it "Invalid file name \"%1\$s\".", "Nome di file non valido \"%1\$s\"." + it "Log Files", "File di log" + it "&No" + it "&OK" + it "Ok" + it "&Open", "A&pri" + it "Open", "Apri" + it "Open Multiple Files", "Apri file multipli" + it "Paste", "Incolla" + it "Quit", "Esci" + it "&Red", "&Rosso" + it "Replace existing file?", "Sostituisci il file esistente?" + it "&Retry", "&Riprova" + it "&Save", "&Salva" + it "Save As", "Salva come" + it "Save To Log", "Salva il log" + it "Select Log File", "Scegli un file di log" + it "Select a file to source", "Scegli un file da eseguire" + it "&Selection:", "&Selezione:" + it "Skip Messages", "Salta i messaggi" + it "Source...", "Esegui..." + it "Tcl Scripts", "Scripts Tcl" + it "Tcl for Windows", "Tcl per Windows" + it "Text Files", "File di testo" + it "&Yes", "&Si" + it "abort", "interrompi" + it "blue", "blu" + it "cancel", "annulla" + it "extension", "estensione" + it "extensions", "estensioni" + it "green", "verde" + it "ignore", "ignora" + it "ok" + it "red", "rosso" + it "retry", "riprova" + it "yes", "si" +} diff --git a/ext/tk/sample/msgs_rb/ja.msg b/ext/tk/sample/msgs_rb/ja.msg new file mode 100644 index 0000000000..40587c1f1d --- /dev/null +++ b/ext/tk/sample/msgs_rb/ja.msg @@ -0,0 +1,13 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + ja 'Application Error', '\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30A8\u30E9\u30FC' + ja 'Blue', '\u9752' + ja 'Color', '\u80CC\u666F\u8272' + ja 'Delete', '\u6D88\u53BB' + ja 'Error', '\u30A8\u30E9\u30FC' + ja 'Exit', '\u7D42\u4E86' + ja 'Green', '\u7DD1' + ja 'Red', '\u8D64' + ja 'blue', '\u9752' + ja 'green', '\u7DD1' + ja 'red', '\u8D64' +} diff --git a/ext/tk/sample/msgs_rb/nl.msg b/ext/tk/sample/msgs_rb/nl.msg new file mode 100644 index 0000000000..24e41dae86 --- /dev/null +++ b/ext/tk/sample/msgs_rb/nl.msg @@ -0,0 +1,123 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + nl "Application Error", "Toepassingsfout" + nl "Blue", "Blauw" + nl "Color", "Kleur" + nl "Delete", "Wissen" + nl "Error", "Fout" + nl "Exit", "Be\\u00ebindigen" + nl "Green", "Groen" + nl "Red", "Rood" + nl "blue", "blauw" + nl "green", "groen" + nl "red", "rood" +} + +TkMsgCatalog.new('::tk') { + nl "\"%1\$s\" must be an absolute pathname", "\"%1\$s\" moet een absolute pad-naam zijn" + nl "%1\$s is not a toplevel window", "%1\$s is geen toplevel window" + nl ", or", ", of" + nl "-default, -icon, -message, -parent, -title, or -type", "-default, -icon, -message, -parent, -title, of -type" + nl "-initialdir, -mustexist, -parent, or -title", "-initialdir, -mustexist, -parent, of -title" + nl "&Abort", "&Afbreken" + nl "About...", "Over..." + nl "All Files", "Alle Bestanden" + nl "Application Error", "Toepassingsfout" + nl "&Blue", "&Blauw" + nl "&Cancel", "&Annuleren" + nl "Cannot change to the directory \"%1\$s\".\nPermission denied.", "Kan niet naar map \"%1\$s\" gaan.\nU heeft hiervoor geen toestemming." + nl "Choose Directory", "Kies map" + nl "Clear", "Wissen" + nl "Clear entry, Press OK; Enter %1\$s, press OK", "Wis veld, Druk op OK; typ %1\$s in, druk op OK" + nl "&Clear Console", "&Wis Console" + nl "Color", "Kleur" + nl "Console" + nl "Copy", "Kopi\\u00ebren" + nl "Cut", "Knippen" + nl "Delete", "Wissen" + nl "Details" + nl "Details >>" + nl "Directory \"%1\$s\" does not exist.", "Map \"%1\$s\" bestaat niet." + nl "&Directory:", "&Map:" + nl "Edit", "Bewerken" + nl "Enter \"%1\$s\", press OK", "Typ \"%1\$s\", druk op OK" + nl "Enter \"%1\$s\", press OK, enter \"%2\$s\", press OK", "Typ \"%1\$s\", druk op OK, typ \"%2\$s\", druk op OK" + nl "Error: %1\$s", "Fout: %1\$s" + nl "Exit", "Be\\u00ebindigen" + nl "File", "Bestand" + nl "File \"%1\$s\" already exists.\n\n", "Bestand \"%1\$s\" bestaat al.\n\n" + nl "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "Bestand \"%1\$s\" bestaat al.\nWilt u het overschrijven?" + nl "File \"%1\$s\" does not exist.", "Bestand \"%1\$s\" bestaat niet." + nl "File &name:", "Bestands&naam:" + nl "File &names:", "Bestands&namen:" + nl "Files of &type:", "Bestanden van het &type:" + nl "Fi&les:", "&Bestanden:" + nl "&Filter" + nl "Fil&ter:" + nl "&Green", "&Groen" + nl "Hi", "H\\u00e9" + nl "Hide Console", "Verberg Console" + nl "&Ignore", "&Negeren" + nl "Invalid file name \"%1\$s\".", "Ongeldige bestandsnaam \"%1\$s\"." + nl "Log Files", "Log Bestanden" + nl "&No", "&Nee" + nl "&OK" + nl "Ok" + nl "&Open", "&Openen" + nl "Open", "Openen" + nl "Open Multiple Files", "Open meerdere bestanden" + nl "Paste", "Plakken" + nl "Please press %1\$s", "Druk op %1\$s, A.U.B." + nl "Please press ok", "Druk op ok, A.U.B." + nl "Press Cancel", "Druk op Annuleren" + nl "Press Ok", "Druk op Ok" + nl "Quit", "Stoppen" + nl "&Red", "&Rood" + nl "Replace existing file?", "Vervang bestaand bestand?" + nl "&Retry", "&Herhalen" + nl "&Save", "Op&slaan" + nl "Save As", "Opslaan als" + nl "Save To Log", "Opslaan naar Log" + nl "Select Log File", "Selecteer Log bestand" + nl "Select a file to source", "Selecteer bronbestand" + nl "&Selection:", "&Selectie:" + nl "Skip Messages", "Berichten overslaan" + nl "Source...", "Bron..." + nl "Tcl Scripts" + nl "Tcl for Windows", "Tcl voor Windows" + nl "Text Files", "Tekstbestanden" + nl "&Yes", "&Ja" + nl "abort", "afbreken" + nl "abort, retry, ignore, ok, cancel, no, or yes", "afbreken, opnieuw, negeren, ok, annuleren, nee, of ja" + nl "abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel", "abortretryignore, ok, okcancel, retrycancel, yesno, of yesnocancel" + nl "bad %1\$s value \"%2\$s\": must be %3\$s", "verkeerde %1\$s waarde \"%2\$s\": moet zijn %3\$s" + nl "bad file type \"%1\$s\", should be", "verkeerd bestandstype \"%1\$s\", moet zijn" + nl "bad option \"%1\$s\": should be %2\$s", "verkeerde optie \"%1\$s\": moet zijn %2\$s" + nl "bad window path name \"%1\$s\"", "verkeerde window-padnaam \"%1\$s\"" + nl "blue", "blauw" + nl "can't post %1\$s: it isn't a descendant of %2\$s (this is a new requirement in Tk versions 3.0 and later)", "kan %1\$s niet verzenden: het is geen afstammeling van %2\$s (dit is een nieuwe eis in Tk versies 3.0 en later)" + nl "cancel", "annuleren" + nl "default button index greater than number of buttons specified for tk_dialog", "default knop index is groter dan het aantal knoppen beschikbaar voor tk_dialog" + nl "display name to use (current one otherwise)", "te gebruiken schermnaam (anders huidige scherm)" + nl "error, info, question, or warning", "error, info, question, of warning" + nl "extension" + nl "extensions" + nl "focus group \"%1\$s\" doesn't exist", "focusgroep \"%1\$s\" bestaat niet" + nl "green", "groen" + nl "history event %1\$s" + nl "ignore", "negeren" + nl "invalid default button \"%1\$s\"", "ongeldige default knop \"%1\$s\"" + nl "macType" + nl "macTypes" + nl "must specify a background color", "een achtergrondkleur is verplicht" + nl "name of the slave interpreter", "naam van de slaaf-interpreter" + nl "no winfo screen . nor env(DISPLAY)", "geen winfo scherm . noch env(DISPLAY)" + nl "ok" + nl "red", "rood" + nl "retry", "opnieuw" + nl "should contain 5 or 4 elements", "moet 4 of 5 elementen bevatten" + nl "spec" + nl "tk_chooseDirectory command", "tk_chooseDirectory opdracht" + nl "tk_chooseDirectory command, cancel gives null", "tk_chooseDirectory opdracht, annuleren geeft lege waarde" + nl "tk_chooseDirectory command, initialdir", "tk_chooseDirectory opdracht, initi\\u00eble map" + nl "yes", "ja" +} diff --git a/ext/tk/sample/msgs_rb/pl.msg b/ext/tk/sample/msgs_rb/pl.msg new file mode 100644 index 0000000000..0b3b4445c2 --- /dev/null +++ b/ext/tk/sample/msgs_rb/pl.msg @@ -0,0 +1,87 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + pl 'Application Error', 'Bl\u0105d w Programie' + pl 'Blue', 'Niebieski' + pl 'Color', 'Kolor' + pl 'Delete', 'Usu\u0144' + pl 'Error', 'B\u0142\u0105d' + pl 'Exit', 'Zako\u0144cz' + pl 'Green', 'Zielony' + pl 'Red', 'Czerwonz' + pl 'blue', 'niebieski' + pl 'green', 'zielony' + pl 'red', 'czerwony' +} + +TkMsgCatalog.new('::tk') { + pl '&Abort', '&Anuluj' + pl '&About...', 'O Programie...' + pl 'All Files', 'Wszystkie pliki' + pl 'Application Error', 'Bl\u0105d w Programie' + pl '&Blue', '&Niebieski' + pl '&Cancel', '&Anuluj' + pl 'Cannot change to the directory "%1\$s".' "\n" 'Permission denied.', 'Katalog "%1\$s" nie mo\u017ce zosta\u0107 odczytany lub nie istnieje.' + pl 'Choose Directory', 'Wybierz katalog' + pl '&Clear', '&Wyczy\u015b\u0107' + pl '&Clear Console', '&Wyczy\u015b\u0107 konsol\u0119' + pl 'Color', 'Kolor' + pl 'Console', 'Konsola' + pl '&Copy', '&Kopiuj' + pl 'Cu&t', '&Wytnij' + pl '&Delete', '&Usu\u0144' + pl 'Details >>', 'Detale >>' + pl 'Directory "%1\$s" does not exist.', 'Katalog "%1\$s" nie istniej.' + pl '&Directory:', '&Katalog:' + pl '&Edit', '&Edytuj' + pl 'Error: %1\$s', 'B\u0142\u0105d: %1\$s' + pl 'E&xit', '&Zako\u0144cz' + pl '&File', '&Plik' + pl 'File "%1\$s" already exists.' "\n" 'Do you want to overwrite it?', 'Plik "%1\$s" ju\u017c istnieje.' "\n" 'Czy chcesz go zast\u0105pi\u0107?' + pl 'File "%1\$s" already exists.' "\n\n", 'Plik "%1\$s" ju\u017c istnieje. ' "\n\n" + pl 'File "%1\$s" does not exist.', 'Plik "%1\$s" nie istnieje.' + pl 'File &name:', 'Nazwa &pliku:' + pl 'File &names:', 'Nazwy &plik\u00f3w:' + pl 'Files of &type:', 'Pliki &typu:' + pl 'Fi&les:', 'Pli&ki:' + pl '&Filter', '&Filter' + pl 'Fil&ter:', '&Filter:' + pl '&Green', '&Zielony' + pl '&Help', '&Pomoc' + pl 'Hi', 'Witaj' + pl '&Hide Console', '&Schowaj konsol\u0119' + pl '&Ignore', '&Ignoruj' + pl 'Invalid file name "%1\$s".', 'Niew\u0142a\u015bciwa nazwa pliku "%1\$s".' + pl 'Log Files', 'Protoko\u0142uj' + pl '&No', '&Nie' + pl 'OK' + pl 'Ok' + pl 'Open', 'Wczytaj' + pl '&Open', '&Wczytaj' + pl 'Open Multiple Files', 'Wczytuj wiele plik\u00f3w' + pl 'P&aste', '&Wklej' + pl '&Quit', '&Zako\u0144cz' + pl '&Red', '&Czerwonz' + pl 'Replace existing file?', 'Czy zost\u0105pi\u0107 instniej\u0105cy plik?' + pl '&Retry', '&Powt\u00f3rz' + pl '&Save', '&Zapisz' + pl 'Save As', 'Zapisz jako' + pl 'Save To Log', 'Wpisz do protoko\u0142u' + pl 'Select Log File', 'Wybierz plik proko\u0142u' + pl 'Select a file to source', 'Wybierz plik do wykonania' + pl '&Selection:', '&Wyb\u00f3r:' + pl 'Skip Messages', 'Omi\u0144 pozosta\u0142e komunikaty' + pl '&Source...', '&Kod \u017ar\u00f3d\u0142owy...' + pl 'Tcl Scripts', 'Tcl-skrypty' + pl 'Tcl for Windows', 'Tcl dla Okienek (Windows)' + pl 'Text Files', 'Pliki Tekstowe' + pl '&Yes', '&Tak' + pl 'abort', 'zako\u0144cz' + pl 'blue', 'niebieski' + pl 'cancel', 'anuluj' + pl 'extension', 'rozszerzenie' + pl 'extensions', 'rozszerzenia' + pl 'green', 'zielony' + pl 'ignore', 'ignoruj' + pl 'red', 'czerwony' + pl 'retry', 'potw\u00f3rz' + pl 'yes', 'tak' +} diff --git a/ext/tk/sample/msgs_rb/ru.msg b/ext/tk/sample/msgs_rb/ru.msg new file mode 100644 index 0000000000..d6739ceb56 --- /dev/null +++ b/ext/tk/sample/msgs_rb/ru.msg @@ -0,0 +1,87 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + ru 'Application Error', '\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435' + ru 'Blue', ' \u0413\u043e\u043b\u0443\u0431\u043e\u0439' + ru 'Color', '\u0426\u0432\u0435\u0442' + ru 'Delete', '\u0423\u0434\u0430\u043b\u0438\u0442\u044c' + ru 'Error', '\u041e\u0448\u0438\u0431\u043a\u0430' + ru 'Exit', '\u0412\u044b\u0445\u043e\u0434' + ru 'Green', '\u0417\u0435\u043b\u0435\u043d\u044b\u0439' + ru 'Red', '\u041a\u0440\u0430\u0441\u043d\u044b\u0439' + ru 'blue', ' \u0433\u043e\u043b\u0443\u0431\u043e\u0439' + ru 'green', ' \u0437\u0435\u043b\u0435\u043d\u044b\u0439' + ru 'red', ' \u043a\u0440\u0430\u0441\u043d\u044b\u0439' +} + +TkMsgCatalog.new('::tk') { + ru '&Abort', '&\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c' + ru 'About...', '\u041f\u0440\u043e...' + ru 'All Files', '\u0412\u0441\u0435 \u0444\u0430\u0439\u043b\u044b' + ru 'Application Error', '\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435' + ru '&Blue', ' &\u0413\u043e\u043b\u0443\u0431\u043e\u0439' + ru '&Cancel', '\u041e\u0442&\u043c\u0435\u043d\u0430' + ru 'Cannot change to the directory "%1\$s".' "\n" 'Permission denied.' \ + '\u041d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 "%1\$s".' "\n" '\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430' + ru 'Choose Directory', '\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433' + ru 'Clear', '\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c' + ru 'Color', '\u0426\u0432\u0435\u0442' + ru 'Console', '\u041a\u043e\u043d\u0441\u043e\u043b\u044c' + ru 'Copy', '\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c' + ru 'Cut', '\u0412\u044b\u0440\u0435\u0437\u0430\u0442\u044c' + ru 'Delete', '\u0423\u0434\u0430\u043b\u0438\u0442\u044c' + ru 'Details >>', '\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 >>' + ru 'Directory "%1\$s" does not exist.', '\u041a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 "%1\$s" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.' + ru '&Directory:', '&\u041a\u0430\u0442\u0430\u043b\u043e\u0433:' + ru 'Error: %1\$s', '\u041e\u0448\u0438\u0431\u043a\u0430: %1\$s' + ru 'Exit', '\u0412\u044b\u0445\u043e\u0434' + ru 'File "%1\$s" already exists.' "\n" 'Do you want to overwrite it?' \ + '\u0424\u0430\u0439\u043b "%1\$s" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.' "\n" '\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e?' + ru 'File "%1\$s" already exists.' "\n\n", '\u0424\u0430\u0439\u043b "%1\$s" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.' "\n\n" + ru 'File "%1\$s" does not exist.', '\u0424\u0430\u0439\u043b "%1\$s" \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.' + ru 'File &name:', '&\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430:' + ru 'File &names:', '&\u0418\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432:' + ru 'Files of &type:', '&\u0422\u0438\u043f \u0444\u0430\u0439\u043b\u043e\u0432:' + ru 'Fi&les:', '\u0424\u0430\u0439&\u043b\u044b:' + ru '&Filter', '&\u0424\u0438\u043b\u044c\u0442\u0440' + ru 'Fil&ter:', '\u0424\u0438\u043b\u044c&\u0442\u0440:' + ru '&Green', ' &\u0417\u0435\u043b\u0435\u043d\u044b\u0439' + ru 'Hi', '\u041f\u0440\u0438\u0432\u0435\u0442' + ru 'Hide Console', '\u0421\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c' + ru '&Ignore', '&\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c' + ru 'Invalid file name "%1\$s".', '\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 "%1\$s".' + ru 'Log Files', '\u0424\u0430\u0439\u043b\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u0430' + ru '&No', '&\u041d\u0435\u0442' + ru '&OK', '&\u041e\u041a' + ru 'Ok', '\u0414\u0430' + ru 'Open', '\u041e\u0442\u043a\u0440\u044b\u0442\u044c' + ru '&Open', '&\u041e\u0442\u043a\u0440\u044b\u0442\u044c' + ru 'Open Multiple Files', '\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432' + ru 'Paste', '\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c' + ru 'Quit', '\u0412\u044b\u0445\u043e\u0434' + ru '&Red', ' &\u041a\u0440\u0430\u0441\u043d\u044b\u0439' + ru 'Replace existing file?', '\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b?' + ru '&Retry', '&\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c' + ru '&Save', '&\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c' + ru 'Save As', '\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a' + ru 'Save To Log', '\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b' + ru 'Select Log File', '\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b' + ru 'Select a file to source', '\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438' + ru '&Selection:', '&Selection:' + ru 'Skip Messages', '\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f' + ru 'Source...', '\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b...' + ru 'Tcl Scripts', '\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 TCL' + ru 'Tcl for Windows', 'TCL \u0434\u043b\u044f Windows' + ru 'Text Files', '\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b' + ru '&Yes', '&\u0414\u0430' + ru 'abort', '\u043e\u0442\u043c\u0435\u043d\u0430' + ru 'blue', ' \u0433\u043e\u043b\u0443\u0431\u043e\u0439' + ru 'cancel', '\u043e\u0442\u043c\u0435\u043d\u0430' + ru 'extension', '\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435' + ru 'extensions', '\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f' + ru 'green', ' \u0437\u0435\u043b\u0435\u043d\u044b\u0439' + ru 'ignore', '\u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c' + ru 'ok', '\u043e\u043a' + ru 'red', ' \u043a\u0440\u0430\u0441\u043d\u044b\u0439' + ru 'retry', '\u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c' + ru 'yes', '\u0434\u0430' +} + diff --git a/ext/tk/sample/msgs_rb2/README b/ext/tk/sample/msgs_rb2/README new file mode 100644 index 0000000000..b8aa114e1b --- /dev/null +++ b/ext/tk/sample/msgs_rb2/README @@ -0,0 +1,5 @@ +Message catalogs in this directory are written in encodings except +UTF-8. As if you have a trouble to edit UTF-8 text, you can write +message catalogs in your familier encoding. + +Please see '../msgs_rb/README' too. diff --git a/ext/tk/sample/msgs_rb2/de.msg b/ext/tk/sample/msgs_rb2/de.msg new file mode 100644 index 0000000000..0d6c82d9e5 --- /dev/null +++ b/ext/tk/sample/msgs_rb2/de.msg @@ -0,0 +1,88 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + de 'Application Error', 'Applikationsfehler' + de 'Blue', 'Blau' + de 'Color', 'Farbe' + de 'Delete', 'Lschen', 'iso8859-1' + de 'Error', 'Fehler' + de 'Exit', 'Ende' + de 'Green', 'Grn', 'iso8859-1' + de 'Red', 'Rot' + de 'blue', 'blau' + de 'green', 'grn', 'iso8859-1' + de 'red', 'rot' +} + +TkMsgCatalog.new('::tk') { + de "&Abort", "&Abbruch" + de "&About...", "&ber...", 'iso8859-1' + de "All Files", "Alle Dateien" + de "Application Error", "Applikationsfehler" + de "&Blue", "&Blau" + de "&Cancel", "&Abbruch" + de "Cannot change to the directory \"%1\$s\".\nPermission denied.", "Kann nicht in das Verzeichnis \"%1\$s\" wechseln.\nKeine Rechte vorhanden." + de "Choose Directory", "Whle Verzeichnis", 'iso8859-1' + de "&Clear", "&Rcksetzen", 'iso8859-1' + de "&Clear Console", "&Konsole lschen", 'iso8859-1' + de "Color", "Farbe" + de "Console", "Konsole" + de "&Copy", "&Kopieren" + de "Cu&t", "Aus&schneiden" + de '&Delete', '&Lschen', 'iso8859-1' + de "Details >>" + de "Directory \"%1\$s\" does not exist.", "Das Verzeichnis \"%1\$s\" existiert nicht." + de "&Directory:", "&Verzeichnis:" + de "&Edit", "&Bearbieten" + de "Error: %1\$s", "Fehler: %1\$s" + de "E&xit", "&Ende" + de "&File", "&Datei" + de "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei berschreiben ?", 'iso8859-1' + de "File \"%1\$s\" already exists.\n\n", "Die Datei \"%1\$s\" ist bereits vorhanden.\n\n" + de "File \"%1\$s\" does not exist.", "Die Datei \"%1\$s\" existiert nicht." + de "File &name:", "Datei&name:" + de "File &names:", "Datei&namen:" + de "Files of &type:", "Dateien des &Typs:" + de "Fi&les:", "Dat&eien:" + de "&Filter" + de "Fil&ter:" + de '&Green', '&Grn', 'iso8859-1' + de "&Help", "&Hilfe" + de "Hi", "Hallo" + de "&Hide Console", "&Konsole unsichtbar machen" + de "&Ignore", "&Ignorieren" + de "Invalid file name \"%1\$s\".", "Ungltiger Dateiname \"%1\$s\".", 'iso8859-1' + de "Log Files", "Protokolldatei" + de "&No", "&Nein" + de "OK" + de "Ok" + de "Open", "ffnen", 'iso8859-1' + de "&Open", "&ffnen", 'iso8859-1' + de "Open Multiple Files" + de "P&aste", "E&infgen", 'iso8859-1' + de "&Quit", "&Beenden" + de "&Red", "&Rot" + de "Replace existing file?", "Existierende Datei ersetzen?" + de "&Retry", "&Wiederholen" + de "&Save", "&Speichern" + de "Save As", "Speichern unter" + de "Save To Log", "In Protokoll speichern" + de "Select Log File", "Protokolldatei auswhlen", 'iso8859-1' + de "Select a file to source", "Auszufhrende Datei auswhlen", 'iso8859-1' + de "&Selection:", "Auswah&l:" + de "Skip Messages", "Weitere Nachrichten berspringen", 'iso8859-1' + de "&Source...", "&Ausfhren...", 'iso8859-1' + de "Tcl Scripts", "Tcl-Skripte" + de "Tcl for Windows", "Tcl fr Windows", 'iso8859-1' + de "Text Files", "Textdateien" + de "&Yes", "&Ja" + de "abort", "abbrechen" + de "blue", "blau" + de "cancel", "abbrechen" + de "extension", "Erweiterung" + de "extensions", "Erweiterungen" + de 'green', 'grn', 'iso8859-1' + de "ignore", "ignorieren" + de "ok" + de "red", "rot" + de "retry", "wiederholen" + de "yes", "ja" +} diff --git a/ext/tk/sample/msgs_rb2/ja.msg b/ext/tk/sample/msgs_rb2/ja.msg new file mode 100644 index 0000000000..84e89aa6ef --- /dev/null +++ b/ext/tk/sample/msgs_rb2/ja.msg @@ -0,0 +1,85 @@ +TkMsgCatalog.new('::tkmsgcat_demo') { + ja 'Application Error', 'アプリケーションエラー', 'euc-jp' + ja 'Blue', '青', 'euc-jp' + ja 'Color', '色選択', 'euc-jp' + ja 'Delete', '消去', 'euc-jp' + ja 'Error', 'エラー', 'euc-jp' + ja 'Exit', '終了', 'euc-jp' + ja 'Green', '緑', 'euc-jp' + ja 'Red', '赤', 'euc-jp' + ja 'blue', '青', 'euc-jp' + ja 'green', '緑', 'euc-jp' + ja 'red', '赤', 'euc-jp' +} + +TkMsgCatalog.new('::tk') { + ja "&Abort", '中止', 'euc-jp' + ja "About..." + ja "All Files", 'すべてのファイル', 'euc-jp' + ja "Application Error", 'アプリケーションエラー', 'euc-jp' + ja "&Blue", '青', 'euc-jp' + ja "&Cancel", '取り消し', 'euc-jp' + ja "Cannot change to the directory \"%1\$s\".\nPermission denied.", "ディレクトリ \"%1\$s\" に変更できません.\n許可がありません.", 'euc-jp' + ja "Choose Directory", 'ディレクトリを選択', 'euc-jp' + ja "Clear", '消去', 'euc-jp' + ja "Color", '色', 'euc-jp' + ja "Console", 'コンソール', 'euc-jp' + ja "Copy", 'コピー', 'euc-jp' + ja "Cut", '切り取り', 'euc-jp' + ja "Delete", '消去', 'euc-jp' + ja "Details >>", '詳細 >>', 'euc-jp' + ja "Directory \"%1\$s\" does not exist.", '"%1$s" というディレクトリは存在しません.', 'euc-jp' + ja "&Directory:", 'ディレクトリ', 'euc-jp' + ja "Error: %1\$s" + ja "Exit", '終了', 'euc-jp' + ja "File \"%1\$s\" already exists.\nDo you want to overwrite it?", "\"%1\$s\" というファイルは既に存在しています.\n書き換えますか?", 'euc-jp' + ja "File \"%1\$s\" already exists.\n\n", "\"%1\$s\" というファイルは既に存在しています.\n\n", 'euc-jp' + ja "File \"%1\$s\" does not exist.", '"%1$s" というファイルは存在しません.', 'euc-jp' + ja "File &name:", 'ファイル名', 'euc-jp' + ja "File &names:", 'ファイル名', 'euc-jp' + ja "Files of &type:", 'ファイル形式', 'euc-jp' + ja "Fi&les:", 'ファイル', 'euc-jp' + ja "&Filter", 'フィルター', 'euc-jp' + ja "Fil&ter:", 'フィルター', 'euc-jp' + ja "&Green", '緑', 'euc-jp' + ja "Hi", 'こんにちは', 'euc-jp' + ja "Hide Console", 'コンソールを隠す', 'euc-jp' + ja "&Ignore", '無視', 'euc-jp' + ja "Invalid file name \"%1\$s\".", '"%1$s" は不正なファイル名です.', 'euc-jp' + ja "Log Files", 'ログファイル', 'euc-jp' + ja "&No", 'いいえ', 'euc-jp' + ja "&OK", '了解', 'euc-jp' + ja "OK", '了解', 'euc-jp' + ja "Ok", '了解', 'euc-jp' + ja "Open", '開く', 'euc-jp' + ja "&Open", '開く', 'euc-jp' + ja "Open Multiple Files", '複数のファイルを開く', 'euc-jp' + ja "Paste", '貼り付け', 'euc-jp' + ja "Quit", '終了', 'euc-jp' + ja "&Red", '赤', 'euc-jp' + ja "Replace existing file?", '既存のファイルを置き換えますか?', 'euc-jp' + ja "&Retry", '再実行', 'euc-jp' + ja "&Save", '保存', 'euc-jp' + ja "Save As", '名前を付けて保存', 'euc-jp' + ja "Save To Log", 'ログを保存', 'euc-jp' + ja "Select Log File", 'ログファイルを選択', 'euc-jp' + ja "Select a file to source", 'ソースファイルを選択', 'euc-jp' + ja "&Selection:", '選択', 'euc-jp' + ja "Skip Messages", 'メッセージをとばす', 'euc-jp' + ja "Source...", 'ソース...', 'euc-jp' + ja "Tcl Scripts", 'Tcl スクリプト', 'euc-jp' + ja "Tcl for Windows" + ja "Text Files", 'テキストファイル', 'euc-jp' + ja "&Yes", 'はい', 'euc-jp' + ja "abort", '中止', 'euc-jp' + ja "blue", '青', 'euc-jp' + ja "cancel", '取り消し', 'euc-jp' + ja "extension", '拡張子', 'euc-jp' + ja "extensions", '拡張子', 'euc-jp' + ja "green", '緑', 'euc-jp' + ja "ignore", '無視', 'euc-jp' + ja "ok", '了解', 'euc-jp' + ja "red", '赤', 'euc-jp' + ja "retry", '再実行', 'euc-jp' + ja "yes", 'はい', 'euc-jp' +} diff --git a/ext/tk/sample/msgs_tk/README b/ext/tk/sample/msgs_tk/README new file mode 100644 index 0000000000..c7422e3a9b --- /dev/null +++ b/ext/tk/sample/msgs_tk/README @@ -0,0 +1,4 @@ +Almost all of Message-Catalog files in this directory are quoted +from Tcl/Tk8.5a1 source archive (only a little are modified for +'tkmsgcat-load_tk.rb'). Please read the file 'license.terms' in +this directry (That was included in demo directory of Tcl/Tk8.5a1). diff --git a/ext/tk/sample/msgs_tk/cs.msg b/ext/tk/sample/msgs_tk/cs.msg new file mode 100644 index 0000000000..697070985e --- /dev/null +++ b/ext/tk/sample/msgs_tk/cs.msg @@ -0,0 +1,84 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset cs "Application Error" "Chyba programu" + ::msgcat::mcset cs "Blue" "Modr\341" + ::msgcat::mcset cs "Color" "Barva" + ::msgcat::mcset cs "Delete" "Smazat" + ::msgcat::mcset cs "Error" "Chyba" + ::msgcat::mcset cs "Exit" "Konec" + ::msgcat::mcset cs "Green" "Zelen\341" + ::msgcat::mcset cs "Red" "\u010cerven\341" + ::msgcat::mcset cs "blue" "modr\341" + ::msgcat::mcset cs "green" "zelen\341" + ::msgcat::mcset cs "red" "\u010derven\341" +} + +namespace eval ::tk { + ::msgcat::mcset cs "&Abort" "&P\u0159eru\u0161it" + ::msgcat::mcset cs "About..." "O programu..." + ::msgcat::mcset cs "All Files" "V\u0161echny soubory" + ::msgcat::mcset cs "Application Error" "Chyba programu" + ::msgcat::mcset cs "&Blue" "&Modr\341" + ::msgcat::mcset cs "&Cancel" "&Zru\u0161it" + ::msgcat::mcset cs "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nemohu zm\u011bnit atku\341ln\355 adres\341\u0159 na \"%1\$s\".\nP\u0159\355stup odm\355tnut." + ::msgcat::mcset cs "Choose Directory" "V\375b\u011br adres\341\u0159e" + ::msgcat::mcset cs "Clear" "Smazat" + ::msgcat::mcset cs "Color" "Barva" + ::msgcat::mcset cs "Console" "Konzole" + ::msgcat::mcset cs "Copy" "Kop\355rovat" + ::msgcat::mcset cs "Cut" "Vy\u0159\355znout" + ::msgcat::mcset cs "Delete" "Smazat" + ::msgcat::mcset cs "Details >>" "Detaily >>" + ::msgcat::mcset cs "Directory \"%1\$s\" does not exist." "Adres\341\u0159 \"%1\$s\" neexistuje." + ::msgcat::mcset cs "&Directory:" "&Adres\341\u0159:" + ::msgcat::mcset cs "Error: %1\$s" "Chyba: %1\$s" + ::msgcat::mcset cs "Exit" "Konec" + ::msgcat::mcset cs "File \"%1\$s\" already exists.\n\n" "Soubor \"%1\$s\" ji\u017e existuje.\n\n" + ::msgcat::mcset cs "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Soubor \"%1\$s\" ji\u017e existuje.\nChcete jej p\u0159epsat?" + ::msgcat::mcset cs "File \"%1\$s\" does not exist." "Soubor \"%1\$s\" neexistuje." + ::msgcat::mcset cs "File &name:" "&Jm\351no souboru:" + ::msgcat::mcset cs "File &names:" "&Jm\351na soubor\u016f:" + ::msgcat::mcset cs "Files of &type:" "&Typy soubor\u016f:" + ::msgcat::mcset cs "Fi&les:" "Sou&bory:" + ::msgcat::mcset cs "&Filter" "&Filtr" + ::msgcat::mcset cs "Fil&ter:" "Fil&tr:" + ::msgcat::mcset cs "&Green" "Ze&len\341" + ::msgcat::mcset cs "Hi" + ::msgcat::mcset cs "Hide Console" "Skr\375t konsolu" + ::msgcat::mcset cs "&Ignore" "&Ignorovat" + ::msgcat::mcset cs "Invalid file name \"%1\$s\"." "\u0160patn\351 jm\351no souboru \"%1\$s\"." + ::msgcat::mcset cs "Log Files" "Log soubory" + ::msgcat::mcset cs "&No" "&Ne" + ::msgcat::mcset cs "&OK" + ::msgcat::mcset cs "Ok" + ::msgcat::mcset cs "Open" "Otev\u0159\355t" + ::msgcat::mcset cs "&Open" "&Otev\u0159\355t" + ::msgcat::mcset cs "Open Multiple Files" "Otev\u0159\355t v\355ce soubor\u016f" + ::msgcat::mcset cs "Paste" "Vlo\u017eit" + ::msgcat::mcset cs "Quit" "Skon\u010dit" + ::msgcat::mcset cs "&Red" " \u010ce&rven\341" + ::msgcat::mcset cs "Replace existing file?" "Nahradit st\341vaj\355c\355 soubor?" + ::msgcat::mcset cs "&Retry" "Z&novu" + ::msgcat::mcset cs "&Save" "&Ulo\u017eit" + ::msgcat::mcset cs "Save As" "Ulo\u017eit jako" + ::msgcat::mcset cs "Save To Log" "Ulo\u017eit do logu" + ::msgcat::mcset cs "Select Log File" "Vybrat log soubor" + ::msgcat::mcset cs "Select a file to source" "Vybrat soubor k nahr\341n\355" + ::msgcat::mcset cs "&Selection:" "&V\375b\u011br:" + ::msgcat::mcset cs "Skip Messages" "P\u0159esko\u010dit zpr\341vy" + ::msgcat::mcset cs "Source..." "Nahr\341t..." + ::msgcat::mcset cs "Tcl Scripts" "Tcl skripty" + ::msgcat::mcset cs "Tcl for Windows" "Tcl pro Windows" + ::msgcat::mcset cs "Text Files" "Textov\351 soubory" + ::msgcat::mcset cs "&Yes" "&Ano" + ::msgcat::mcset cs "abort" "p\u0159eru\u0161it" + ::msgcat::mcset cs "blue" "modr\341" + ::msgcat::mcset cs "cancel" "zru\u0161it" + ::msgcat::mcset cs "extension" "p\u0159\355pona" + ::msgcat::mcset cs "extensions" "p\u0159\355pony" + ::msgcat::mcset cs "green" "zelen\341" + ::msgcat::mcset cs "ignore" "ignorovat" + ::msgcat::mcset cs "ok" + ::msgcat::mcset cs "red" "\u010derven\341" + ::msgcat::mcset cs "retry" "znovu" + ::msgcat::mcset cs "yes" "ano" +} diff --git a/ext/tk/sample/msgs_tk/de.msg b/ext/tk/sample/msgs_tk/de.msg new file mode 100644 index 0000000000..437f2ed9e7 --- /dev/null +++ b/ext/tk/sample/msgs_tk/de.msg @@ -0,0 +1,88 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset de "Application Error" "Applikationsfehler" + ::msgcat::mcset de "Blue" "Blau" + ::msgcat::mcset de "Color" "Farbe" + ::msgcat::mcset de "Delete" "L\u00f6schen" + ::msgcat::mcset de "Error" "Fehler" + ::msgcat::mcset de "Exit" "Ende" + ::msgcat::mcset de "Green" "Gr\u00fcn" + ::msgcat::mcset de "Red" "Rot" + ::msgcat::mcset de "blue" "blau" + ::msgcat::mcset de "green" "gr\u00fcn" + ::msgcat::mcset de "red" "rot" +} + +namespace eval ::tk { + ::msgcat::mcset de "&Abort" "&Abbruch" + ::msgcat::mcset de "&About..." "&\u00dcber..." + ::msgcat::mcset de "All Files" "Alle Dateien" + ::msgcat::mcset de "Application Error" "Applikationsfehler" + ::msgcat::mcset de "&Blue" "&Blau" + ::msgcat::mcset de "&Cancel" "&Abbruch" + ::msgcat::mcset de "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kann nicht in das Verzeichnis \"%1\$s\" wechseln.\nKeine Rechte vorhanden." + ::msgcat::mcset de "Choose Directory" "W\u00e4hle Verzeichnis" + ::msgcat::mcset de "&Clear" "&R\u00fccksetzen" + ::msgcat::mcset de "&Clear Console" "&Konsole l\u00f6schen" + ::msgcat::mcset de "Color" "Farbe" + ::msgcat::mcset de "Console" "Konsole" + ::msgcat::mcset de "&Copy" "&Kopieren" + ::msgcat::mcset de "Cu&t" "Aus&schneiden" + ::msgcat::mcset de "&Delete" "&L\u00f6schen" + ::msgcat::mcset de "Details >>" + ::msgcat::mcset de "Directory \"%1\$s\" does not exist." "Das Verzeichnis \"%1\$s\" existiert nicht." + ::msgcat::mcset de "&Directory:" "&Verzeichnis:" + ::msgcat::mcset de "&Edit" "&Bearbieten" + ::msgcat::mcset de "Error: %1\$s" "Fehler: %1\$s" + ::msgcat::mcset de "E&xit" "&Ende" + ::msgcat::mcset de "&File" "&Datei" + ::msgcat::mcset de "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei \u00fcberschreiben ?" + ::msgcat::mcset de "File \"%1\$s\" already exists.\n\n" "Die Datei \"%1\$s\" ist bereits vorhanden.\n\n" + ::msgcat::mcset de "File \"%1\$s\" does not exist." "Die Datei \"%1\$s\" existiert nicht." + ::msgcat::mcset de "File &name:" "Datei&name:" + ::msgcat::mcset de "File &names:" "Datei&namen:" + ::msgcat::mcset de "Files of &type:" "Dateien des &Typs:" + ::msgcat::mcset de "Fi&les:" "Dat&eien:" + ::msgcat::mcset de "&Filter" + ::msgcat::mcset de "Fil&ter:" + ::msgcat::mcset de "&Green" "&Gr\u00fcn" + ::msgcat::mcset de "&Help" "&Hilfe" + ::msgcat::mcset de "Hi" "Hallo" + ::msgcat::mcset de "&Hide Console" "&Konsole unsichtbar machen" + ::msgcat::mcset de "&Ignore" "&Ignorieren" + ::msgcat::mcset de "Invalid file name \"%1\$s\"." "Ung\u00fcltiger Dateiname \"%1\$s\"." + ::msgcat::mcset de "Log Files" "Protokolldatei" + ::msgcat::mcset de "&No" "&Nein" + ::msgcat::mcset de "OK" + ::msgcat::mcset de "Ok" + ::msgcat::mcset de "Open" "\u00d6ffnen" + ::msgcat::mcset de "&Open" "\u00d6&ffnen" + ::msgcat::mcset de "Open Multiple Files" + ::msgcat::mcset de "P&aste" "E&inf\u00fcgen" + ::msgcat::mcset de "&Quit" "&Beenden" + ::msgcat::mcset de "&Red" "&Rot" + ::msgcat::mcset de "Replace existing file?" "Existierende Datei ersetzen?" + ::msgcat::mcset de "&Retry" "&Wiederholen" + ::msgcat::mcset de "&Save" "&Speichern" + ::msgcat::mcset de "Save As" "Speichern unter" + ::msgcat::mcset de "Save To Log" "In Protokoll speichern" + ::msgcat::mcset de "Select Log File" "Protokolldatei ausw\u00e4hlen" + ::msgcat::mcset de "Select a file to source" "Auszuf\u00fchrende Datei ausw\u00e4hlen" + ::msgcat::mcset de "&Selection:" "Auswah&l:" + ::msgcat::mcset de "Skip Messages" "Weitere Nachrichten \u00fcberspringen" + ::msgcat::mcset de "&Source..." "&Ausf\u00fchren..." + ::msgcat::mcset de "Tcl Scripts" "Tcl-Skripte" + ::msgcat::mcset de "Tcl for Windows" "Tcl f\u00fcr Windows" + ::msgcat::mcset de "Text Files" "Textdateien" + ::msgcat::mcset de "&Yes" "&Ja" + ::msgcat::mcset de "abort" "abbrechen" + ::msgcat::mcset de "blue" "blau" + ::msgcat::mcset de "cancel" "abbrechen" + ::msgcat::mcset de "extension" "Erweiterung" + ::msgcat::mcset de "extensions" "Erweiterungen" + ::msgcat::mcset de "green" "gr\u00fcn" + ::msgcat::mcset de "ignore" "ignorieren" + ::msgcat::mcset de "ok" + ::msgcat::mcset de "red" "rot" + ::msgcat::mcset de "retry" "wiederholen" + ::msgcat::mcset de "yes" "ja" +} diff --git a/ext/tk/sample/msgs_tk/el.msg b/ext/tk/sample/msgs_tk/el.msg new file mode 100644 index 0000000000..1e3a539647 --- /dev/null +++ b/ext/tk/sample/msgs_tk/el.msg @@ -0,0 +1,103 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset el "Application Error" "\u039b\u03ac\u03b8\u03bf\u03c2 \u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2" + ::msgcat::mcset el "Blue" "\u039c\u03c0\u03bb\u03b5" + ::msgcat::mcset el "Color" "\u03a7\u03c1\u03ce\u03bc\u03b1" + ::msgcat::mcset el "Delete" "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae" + ::msgcat::mcset el "Error" "\u039b\u03ac\u03b8\u03bf\u03c2" + ::msgcat::mcset el "Exit" "\u0388\u03be\u03bf\u03b4\u03bf\u03c2" + ::msgcat::mcset el "Green" "\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf" + ::msgcat::mcset el "Red" "\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf" + ::msgcat::mcset el "blue" "\u03bc\u03c0\u03bb\u03b5" + ::msgcat::mcset el "green" "\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf" + ::msgcat::mcset el "red" "\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf" +} + + +# followings are same to original file included into Tk8.5a1's widget demos. + +## Messages for the Greek (Hellenic - "el") language. +## Please report any changes/suggestions to: +## petasis@iit.demokritos.gr + +namespace eval ::tk { + ::msgcat::mcset el "&Abort" "\u03a4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2" + ::msgcat::mcset el "About..." "\u03a3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac..." + ::msgcat::mcset el "All Files" "\u038c\u03bb\u03b1 \u03c4\u03b1 \u0391\u03c1\u03c7\u03b5\u03af\u03b1" + ::msgcat::mcset el "Application Error" "\u039b\u03ac\u03b8\u03bf\u03c2 \u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2" + ::msgcat::mcset el "&Blue" "\u039c\u03c0\u03bb\u03b5" + ::msgcat::mcset el "&Cancel" "\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7" + ::msgcat::mcset el \ +"Cannot change to the directory \"%1\$s\".\nPermission denied." \ +"\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bb\u03bb\u03b1\u03b3\u03ae \u03ba\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5 \u03c3\u03b5 \"%1\$s\".\n\u0397 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03b4\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03c4\u03b1\u03b9." + ::msgcat::mcset el "Choose Directory" "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u039a\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5" + ::msgcat::mcset el "Clear" "\u039a\u03b1\u03b8\u03b1\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2" + ::msgcat::mcset el "Color" "\u03a7\u03c1\u03ce\u03bc\u03b1" + ::msgcat::mcset el "Console" "\u039a\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1" + ::msgcat::mcset el "Copy" "\u0391\u03bd\u03c4\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae" + ::msgcat::mcset el "Cut" "\u0391\u03c0\u03bf\u03ba\u03bf\u03c0\u03ae" + ::msgcat::mcset el "Delete" "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae" + ::msgcat::mcset el "Details >>" "\u039b\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2 >>" + ::msgcat::mcset el "Directory \"%1\$s\" does not exist." \ + "\u039f \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 \"%1\$s\" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9." + ::msgcat::mcset el "&Directory:" "&\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2:" + ::msgcat::mcset el "Error: %1\$s" "\u039b\u03ac\u03b8\u03bf\u03c2: %1\$s" + ::msgcat::mcset el "Exit" "\u0388\u03be\u03bf\u03b4\u03bf\u03c2" + ::msgcat::mcset el \ + "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \ + "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.\n\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03c0\u03b9\u03ba\u03b1\u03bb\u03c5\u03c6\u03b8\u03b5\u03af;" + ::msgcat::mcset el "File \"%1\$s\" already exists.\n\n" \ + "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.\n\n" + ::msgcat::mcset el "File \"%1\$s\" does not exist." \ + "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9." + ::msgcat::mcset el "File &name:" "\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5:" + ::msgcat::mcset el "File &names:" "\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd:" + ::msgcat::mcset el "Files of &type:" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03c4\u03bf\u03c5 &\u03c4\u03cd\u03c0\u03bf\u03c5:" + ::msgcat::mcset el "Fi&les:" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1:" + ::msgcat::mcset el "&Filter" "\u03a6\u03af\u03bb\u03c4\u03c1\u03bf" + ::msgcat::mcset el "Fil&ter:" "\u03a6\u03af\u03bb\u03c4\u03c1\u03bf:" + ::msgcat::mcset el "&Green" "\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf" + ::msgcat::mcset el "Hi" "\u0393\u03b5\u03b9\u03b1" + ::msgcat::mcset el "Hide Console" "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03ba\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1\u03c2" + ::msgcat::mcset el "&Ignore" "\u0391\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7" + ::msgcat::mcset el "Invalid file name \"%1\$s\"." \ + "\u0386\u03ba\u03c5\u03c1\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \"%1\$s\"." + ::msgcat::mcset el "Log Files" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2" + ::msgcat::mcset el "&No" "\u038c\u03c7\u03b9" + ::msgcat::mcset el "&OK" "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" + ::msgcat::mcset el "&Ok" "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" + ::msgcat::mcset el "Open" "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1" + ::msgcat::mcset el "&Open" "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1" + ::msgcat::mcset el "Open Multiple Files" \ + "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bf\u03bb\u03bb\u03b1\u03c0\u03bb\u03ce\u03bd \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd" + ::msgcat::mcset el "Paste" "\u0395\u03c0\u03b9\u03ba\u03cc\u03bb\u03bb\u03b7\u03c3\u03b7" + ::msgcat::mcset el "Quit" "\u0388\u03be\u03bf\u03b4\u03bf\u03c2" + ::msgcat::mcset el "&Red" "\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf" + ::msgcat::mcset el "Replace existing file?" \ + "\u0395\u03c0\u03b9\u03ba\u03ac\u03bb\u03c5\u03c8\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03bd\u03c4\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5;" + ::msgcat::mcset el "&Retry" "\u03a0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac" + ::msgcat::mcset el "&Save" "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7" + ::msgcat::mcset el "Save As" "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03b1\u03bd" + ::msgcat::mcset el "Save To Log" "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2" + ::msgcat::mcset el "Select Log File" "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2" + ::msgcat::mcset el "Select a file to source" \ + "\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b3\u03b9\u03b1 \u03b5\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7" + ::msgcat::mcset el "&Selection:" "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae:" + ::msgcat::mcset el "Skip Messages" "\u0391\u03c0\u03bf\u03c6\u03c5\u03b3\u03ae \u03bc\u03c5\u03bd\u03b7\u03bc\u03ac\u03c4\u03c9\u03bd" + ::msgcat::mcset el "Source..." "\u0395\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7..." + ::msgcat::mcset el "Tcl Scripts" "Tcl Scripts" + ::msgcat::mcset el "Tcl for Windows" "Tcl \u03b3\u03b9\u03b1 Windows" + ::msgcat::mcset el "Text Files" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5" + ::msgcat::mcset el "&Yes" "\u039d\u03b1\u03b9" + ::msgcat::mcset el "abort" "\u03c4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2" + ::msgcat::mcset el "blue" "\u03bc\u03c0\u03bb\u03b5" + ::msgcat::mcset el "cancel" "\u03b1\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7" + ::msgcat::mcset el "extension" "\u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7" + ::msgcat::mcset el "extensions" "\u03b5\u03c0\u03b5\u03ba\u03c4\u03ac\u03c3\u03b5\u03b9\u03c2" + ::msgcat::mcset el "green" "\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf" + ::msgcat::mcset el "ignore" "\u03b1\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7" + ::msgcat::mcset el "ok" "\u03b5\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" + ::msgcat::mcset el "red" "\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf" + ::msgcat::mcset el "retry" "\u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac" + ::msgcat::mcset el "yes" "\u03bd\u03b1\u03b9" +} + diff --git a/ext/tk/sample/msgs_tk/en.msg b/ext/tk/sample/msgs_tk/en.msg new file mode 100644 index 0000000000..de586d195e --- /dev/null +++ b/ext/tk/sample/msgs_tk/en.msg @@ -0,0 +1,83 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset en "Application Error" + ::msgcat::mcset en "Blue" + ::msgcat::mcset en "Color" + ::msgcat::mcset en "Delete" + ::msgcat::mcset en "Error" + ::msgcat::mcset en "Green" + ::msgcat::mcset en "Red" + ::msgcat::mcset en "blue" + ::msgcat::mcset en "green" + ::msgcat::mcset en "red" +} + +namespace eval ::tk { + ::msgcat::mcset en "&Abort" + ::msgcat::mcset en "About..." + ::msgcat::mcset en "All Files" + ::msgcat::mcset en "Application Error" + ::msgcat::mcset en "&Blue" + ::msgcat::mcset en "&Cancel" + ::msgcat::mcset en "Cannot change to the directory \"%1\$s\".\nPermission denied." + ::msgcat::mcset en "Choose Directory" + ::msgcat::mcset en "Clear" + ::msgcat::mcset en "Color" + ::msgcat::mcset en "Console" + ::msgcat::mcset en "Copy" + ::msgcat::mcset en "Cut" + ::msgcat::mcset en "Delete" + ::msgcat::mcset en "Details >>" + ::msgcat::mcset en "Directory \"%1\$s\" does not exist." + ::msgcat::mcset en "&Directory:" + ::msgcat::mcset en "Error: %1\$s" + ::msgcat::mcset en "Exit" + ::msgcat::mcset en "File \"%1\$s\" already exists.\nDo you want to overwrite it?" + ::msgcat::mcset en "File \"%1\$s\" already exists.\n\n" + ::msgcat::mcset en "File \"%1\$s\" does not exist." + ::msgcat::mcset en "File &name:" + ::msgcat::mcset en "File &names:" + ::msgcat::mcset en "Files of &type:" + ::msgcat::mcset en "Fi&les:" + ::msgcat::mcset en "&Filter" + ::msgcat::mcset en "Fil&ter:" + ::msgcat::mcset en "&Green" + ::msgcat::mcset en "Hi" + ::msgcat::mcset en "Hide Console" + ::msgcat::mcset en "&Ignore" + ::msgcat::mcset en "Invalid file name \"%1\$s\"." + ::msgcat::mcset en "Log Files" + ::msgcat::mcset en "&No" + ::msgcat::mcset en "&OK" + ::msgcat::mcset en "Ok" + ::msgcat::mcset en "Open" + ::msgcat::mcset en "&Open" + ::msgcat::mcset en "Open Multiple Files" + ::msgcat::mcset en "Paste" + ::msgcat::mcset en "Quit" + ::msgcat::mcset en "&Red" + ::msgcat::mcset en "Replace existing file?" + ::msgcat::mcset en "&Retry" + ::msgcat::mcset en "&Save" + ::msgcat::mcset en "Save As" + ::msgcat::mcset en "Save To Log" + ::msgcat::mcset en "Select Log File" + ::msgcat::mcset en "Select a file to source" + ::msgcat::mcset en "&Selection:" + ::msgcat::mcset en "Skip Messages" + ::msgcat::mcset en "Source..." + ::msgcat::mcset en "Tcl Scripts" + ::msgcat::mcset en "Tcl for Windows" + ::msgcat::mcset en "Text Files" + ::msgcat::mcset en "&Yes" + ::msgcat::mcset en "abort" + ::msgcat::mcset en "blue" + ::msgcat::mcset en "cancel" + ::msgcat::mcset en "extension" + ::msgcat::mcset en "extensions" + ::msgcat::mcset en "green" + ::msgcat::mcset en "ignore" + ::msgcat::mcset en "ok" + ::msgcat::mcset en "red" + ::msgcat::mcset en "retry" + ::msgcat::mcset en "yes" +} diff --git a/ext/tk/sample/msgs_tk/en_gb.msg b/ext/tk/sample/msgs_tk/en_gb.msg new file mode 100644 index 0000000000..1aa5b49380 --- /dev/null +++ b/ext/tk/sample/msgs_tk/en_gb.msg @@ -0,0 +1,7 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset en_gb Color Colour +} + +namespace eval ::tk { + ::msgcat::mcset en_gb Color Colour +} diff --git a/ext/tk/sample/msgs_tk/eo.msg b/ext/tk/sample/msgs_tk/eo.msg new file mode 100644 index 0000000000..e683cef297 --- /dev/null +++ b/ext/tk/sample/msgs_tk/eo.msg @@ -0,0 +1,87 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset eo "Application Error" "Aplikoerraro" + ::msgcat::mcset eo "Blue" "Blua" + ::msgcat::mcset eo "Color" "Farbo" + ::msgcat::mcset eo "Delete" "Forprenu" + ::msgcat::mcset eo "Error" "Eraro" + ::msgcat::mcset eo "Exit" "Eliru" + ::msgcat::mcset eo "Green" "Verda" + ::msgcat::mcset eo "Red" "Rosa" + ::msgcat::mcset eo "blue" "blua" + ::msgcat::mcset eo "green" "verda" + ::msgcat::mcset eo "red" "ru\u011da" +} + +namespace eval ::tk { + ::msgcat::mcset eo "&Abort" "&\u0108esigo" + ::msgcat::mcset eo "&About..." "Pri..." + ::msgcat::mcset eo "All Files" "\u0108ioj dosieroj" + ::msgcat::mcset eo "Application Error" "Aplikoerraro" + ::msgcat::mcset eo "&Blue" "&Blua" + ::msgcat::mcset eo "&Cancel" "&Rezignu" + ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble \u0109angi al dosierulon \"%1\$s\".\nVi ne rajtas tion." + ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujo" + ::msgcat::mcset eo "&Clear" "&Klaru" + ::msgcat::mcset eo "&Clear Console" "&Klaru konzolon" + ::msgcat::mcset eo "Color" "Farbo" + ::msgcat::mcset eo "Console" "Konzolo" + ::msgcat::mcset eo "&Copy" "&Kopiu" + ::msgcat::mcset eo "Cu&t" "&Enpo\u015digu" + ::msgcat::mcset eo "&Delete" "&Forprenu" + ::msgcat::mcset eo "Details >>" "Detaloj >>" + ::msgcat::mcset eo "Directory \"%1\$s\" does not exist." "La dosierujo \"%1\$s\" ne ekzistas." + ::msgcat::mcset eo "&Directory:" "&Dosierujo:" + ::msgcat::mcset eo "&Edit" "&Redaktu" + ::msgcat::mcset eo "Error: %1\$s" "Eraro: %1\$s" + ::msgcat::mcset eo "E&xit" "&Eliru" + ::msgcat::mcset eo "&File" "&Dosiero" + ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\n\u0108u vi volas anstata\u00fbigi la dosieron?" + ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam egzistas. \n\n" + ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosierp \"%1\$s\" ne estas." + ::msgcat::mcset eo "File &name:" "Dosiero&nomo:" + ::msgcat::mcset eo "File &names:" "Dosiero&nomoj:" + ::msgcat::mcset eo "Files of &type:" "Dosieroj de &Typo:" + ::msgcat::mcset eo "Fi&les:" "Do&sieroj:" + ::msgcat::mcset eo "&Filter" "&Filtrilo" + ::msgcat::mcset eo "Fil&ter:" "&Filtrilo:" + ::msgcat::mcset eo "&Green" "&Verda" + ::msgcat::mcset eo "&Help" "&Helpu" + ::msgcat::mcset eo "Hi" "Saluton" + ::msgcat::mcset eo "&Hide Console" "&Ka\u015du konzolon" + ::msgcat::mcset eo "&Ignore" "&Ignoru" + ::msgcat::mcset eo "Invalid file name \"%1\$s\"." "Malvalida dosieronomo \"%1\$s\"." + ::msgcat::mcset eo "Log Files" "Protokolo" + ::msgcat::mcset eo "&No" "&Ne" + ::msgcat::mcset eo "OK" + ::msgcat::mcset eo "Ok" + ::msgcat::mcset eo "Open" "Malfermu" + ::msgcat::mcset eo "&Open" "&Malfermu" + ::msgcat::mcset eo "Open Multiple Files" "Melfermu multan dosierojn" + ::msgcat::mcset eo "P&aste" "&Elpo\u015digi" + ::msgcat::mcset eo "&Quit" "&Finigu" + ::msgcat::mcset eo "&Red" "&Rosa" + ::msgcat::mcset eo "Replace existing file?" "\u0108u anstata\u00fbu ekzistantan dosieron?" + ::msgcat::mcset eo "&Retry" "&Ripetu" + ::msgcat::mcset eo "&Save" "&Savu" + ::msgcat::mcset eo "Save As" "Savu kiel" + ::msgcat::mcset eo "Save To Log" "Savu en protokolon" + ::msgcat::mcset eo "Select Log File" "Elektu prokolodosieron" + ::msgcat::mcset eo "Select a file to source" "Elektu dosieron por interpreti" + ::msgcat::mcset eo "&Selection:" "&Elekto:" + ::msgcat::mcset eo "Skip Messages" "transsaltu pluajn mesa\u011dojn" + ::msgcat::mcset eo "&Source..." "&Fontoprogramo..." + ::msgcat::mcset eo "Tcl Scripts" "Tcl-skriptoj" + ::msgcat::mcset eo "Tcl for Windows" "Tcl por vindoso" + ::msgcat::mcset eo "Text Files" "Tekstodosierojn" + ::msgcat::mcset eo "&Yes" "&Jes" + ::msgcat::mcset eo "abort" "\u0109esigo" + ::msgcat::mcset eo "blue" "blua" + ::msgcat::mcset eo "cancel" "rezignu" + ::msgcat::mcset eo "extension" "ekspansio" + ::msgcat::mcset eo "extensions" "ekspansioj" + ::msgcat::mcset eo "green" "verda" + ::msgcat::mcset eo "ignore" "ignorieren" + ::msgcat::mcset eo "red" "ru\u011da" + ::msgcat::mcset eo "retry" "ripetu" + ::msgcat::mcset eo "yes" "jes" +} diff --git a/ext/tk/sample/msgs_tk/es.msg b/ext/tk/sample/msgs_tk/es.msg new file mode 100644 index 0000000000..ba981236a3 --- /dev/null +++ b/ext/tk/sample/msgs_tk/es.msg @@ -0,0 +1,84 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset es "Application Error" "Error de la aplicaci\u00f3n" + ::msgcat::mcset es "Blue" "Azul" + ::msgcat::mcset es "Color" "Color" + ::msgcat::mcset es "Delete" "Borrar" + ::msgcat::mcset es "Error" "Error" + ::msgcat::mcset es "Exit" "Salir" + ::msgcat::mcset es "Green" "Verde" + ::msgcat::mcset es "Red" "Rojo" + ::msgcat::mcset es "blue" "azul" + ::msgcat::mcset es "green" "verde" + ::msgcat::mcset es "red" "rojo" +} + +namespace eval ::tk { + ::msgcat::mcset es "&Abort" "&Abortar" + ::msgcat::mcset es "About..." "Acerca de ..." + ::msgcat::mcset es "All Files" "Todos los archivos" + ::msgcat::mcset es "Application Error" "Error de la aplicaci\u00f3n" + ::msgcat::mcset es "&Blue" "&Azul" + ::msgcat::mcset es "&Cancel" "&Cancelar" + ::msgcat::mcset es "Cannot change to the directory \"%1\$s\".\nPermission denied." "No es posible acceder al directorio \"%1\$s\".\nPermiso denegado." + ::msgcat::mcset es "Choose Directory" "Elegir directorio" + ::msgcat::mcset es "Clear" "Borrar" + ::msgcat::mcset es "Color" "Color" + ::msgcat::mcset es "Console" "Consola" + ::msgcat::mcset es "Copy" "Copiar" + ::msgcat::mcset es "Cut" "Cortar" + ::msgcat::mcset es "Delete" "Borrar" + ::msgcat::mcset es "Details >>" "Detalles >>" + ::msgcat::mcset es "Directory \"%1\$s\" does not exist." "El directorio \"%1\$s\" no existe." + ::msgcat::mcset es "&Directory:" "&Directorio:" + ::msgcat::mcset es "Error: %1\$s" "Error: %1\$s" + ::msgcat::mcset es "Exit" "Salir" + ::msgcat::mcset es "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "El archivo \"%1\$s\" ya existe.\nDesea sobreescribirlo?" + ::msgcat::mcset es "File \"%1\$s\" already exists.\n\n" "El archivo \"%1\$s\" ya existe.\n\n" + ::msgcat::mcset es "File \"%1\$s\" does not exist." "El archivo \"%1\$s\" no existe." + ::msgcat::mcset es "File &name:" "&Nombre de archivo:" + ::msgcat::mcset es "File &names:" "&Nombres de archivo:" + ::msgcat::mcset es "Files of &type:" "Archivos de &tipo:" + ::msgcat::mcset es "Fi&les:" "&Archivos:" + ::msgcat::mcset es "&Filter" "&Filtro" + ::msgcat::mcset es "Fil&ter:" "Fil&tro:" + ::msgcat::mcset es "&Green" "&Verde" + ::msgcat::mcset es "Hi" "Hola" + ::msgcat::mcset es "Hide Console" "Esconder la consola" + ::msgcat::mcset es "&Ignore" "&Ignorar" + ::msgcat::mcset es "Invalid file name \"%1\$s\"." "Nombre de archivo inv\u00e1lido \"%1\$s\"." + ::msgcat::mcset es "Log Files" "Ficheros de traza" + ::msgcat::mcset es "&No" "&No" + ::msgcat::mcset es "&OK" "&OK" + ::msgcat::mcset es "Ok" "Ok" + ::msgcat::mcset es "Open" "Abrir" + ::msgcat::mcset es "&Open" "&Abrir" + ::msgcat::mcset es "Open Multiple Files" "Abrir m\u00faltiples archivos" + ::msgcat::mcset es "Paste" "Pegar" + ::msgcat::mcset es "Quit" "Abandonar" + ::msgcat::mcset es "&Red" "&Rojo" + ::msgcat::mcset es "Replace existing file?" "Reemplazar el archivo existente?" + ::msgcat::mcset es "&Retry" "&Reintentar" + ::msgcat::mcset es "&Save" "&Salvar" + ::msgcat::mcset es "Save As" "Salvar como" + ::msgcat::mcset es "Save To Log" "Salvar al archivo de traza" + ::msgcat::mcset es "Select Log File" "Elegir un archivo de traza" + ::msgcat::mcset es "Select a file to source" "Seleccionar un archivo a evaluar" + ::msgcat::mcset es "&Selection:" "&Selecci\u00f3n:" + ::msgcat::mcset es "Skip Messages" "Omitir los mensajes" + ::msgcat::mcset es "Source..." "Evaluar..." + ::msgcat::mcset es "Tcl Scripts" "Scripts Tcl" + ::msgcat::mcset es "Tcl for Windows" "Tcl para Windows" + ::msgcat::mcset es "Text Files" "Archivos de texto" + ::msgcat::mcset es "&Yes" "&S\u00ed" + ::msgcat::mcset es "abort" "abortar" + ::msgcat::mcset es "blue" "azul" + ::msgcat::mcset es "cancel" "cancelar" + ::msgcat::mcset es "extension" "extensi\u00f3n" + ::msgcat::mcset es "extensions" "extensiones" + ::msgcat::mcset es "green" "verde" + ::msgcat::mcset es "ignore" "ignorar" + ::msgcat::mcset es "ok" "ok" + ::msgcat::mcset es "red" "rojo" + ::msgcat::mcset es "retry" "reintentar" + ::msgcat::mcset es "yes" "s\u00ed" +} diff --git a/ext/tk/sample/msgs_tk/fr.msg b/ext/tk/sample/msgs_tk/fr.msg new file mode 100644 index 0000000000..ebbba48ca1 --- /dev/null +++ b/ext/tk/sample/msgs_tk/fr.msg @@ -0,0 +1,84 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset fr "Application Error" "Erreur d'application" + ::msgcat::mcset fr "Blue" "Bleu" + ::msgcat::mcset fr "Color" "Couleur" + ::msgcat::mcset fr "Delete" "Effacer" + ::msgcat::mcset fr "Error" "Erreur" + ::msgcat::mcset fr "Exit" "Quitter" + ::msgcat::mcset fr "Green" "Vert" + ::msgcat::mcset fr "Red" "Rouge" + ::msgcat::mcset fr "blue" "bleu" + ::msgcat::mcset fr "green" "vert" + ::msgcat::mcset fr "red" "rouge" +} + +namespace eval ::tk { + ::msgcat::mcset fr "&Abort" "&Annuler" + ::msgcat::mcset fr "About..." "\u00c0 propos..." + ::msgcat::mcset fr "All Files" "Tous les fichiers" + ::msgcat::mcset fr "Application Error" "Erreur d'application" + ::msgcat::mcset fr "&Blue" "&Bleu" + ::msgcat::mcset fr "&Cancel" "&Annuler" + ::msgcat::mcset fr "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossible d'acc\u00e9der au r\u00e9pertoire \"%1\$s\".\nPermission refus\u00e9e." + ::msgcat::mcset fr "Choose Directory" "Choisir r\u00e9pertoire" + ::msgcat::mcset fr "Clear" "Effacer" + ::msgcat::mcset fr "Color" "Couleur" + ::msgcat::mcset fr "Console" + ::msgcat::mcset fr "Copy" "Copier" + ::msgcat::mcset fr "Cut" "Couper" + ::msgcat::mcset fr "Delete" "Effacer" + ::msgcat::mcset fr "Details >>" "D\u00e9tails >>" + ::msgcat::mcset fr "Directory \"%1\$s\" does not exist." "Le r\u00e9pertoire \"%1\$s\" n'existe pas." + ::msgcat::mcset fr "&Directory:" "&R\u00e9pertoire:" + ::msgcat::mcset fr "Error: %1\$s" "Erreur: %1\$s" + ::msgcat::mcset fr "Exit" "Quitter" + ::msgcat::mcset fr "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Le fichier \"%1\$s\" existe d\u00e9j\u00e0.\nVoulez-vous l'\u00e9craser?" + ::msgcat::mcset fr "File \"%1\$s\" already exists.\n\n" "Le fichier \"%1\$s\" existe d\u00e9j\u00e0.\n\n" + ::msgcat::mcset fr "File \"%1\$s\" does not exist." "Le fichier \"%1\$s\" n'existe pas." + ::msgcat::mcset fr "File &name:" "&Nom de fichier:" + ::msgcat::mcset fr "File &names:" "&Noms de fichiers:" + ::msgcat::mcset fr "Files of &type:" "&Type de fichiers:" + ::msgcat::mcset fr "Fi&les:" "Fich&iers:" + ::msgcat::mcset fr "&Filter" "&Filtre" + ::msgcat::mcset fr "Fil&ter:" "Fil&tre:" + ::msgcat::mcset fr "&Green" "&Vert" + ::msgcat::mcset fr "Hi" "Salut" + ::msgcat::mcset fr "Hide Console" "Cacher la Console" + ::msgcat::mcset fr "&Ignore" "&Ignorer" + ::msgcat::mcset fr "Invalid file name \"%1\$s\"." "Nom de fichier invalide \"%1\$s\"." + ::msgcat::mcset fr "Log Files" "Fichiers de trace" + ::msgcat::mcset fr "&No" "&Non" + ::msgcat::mcset fr "&OK" + ::msgcat::mcset fr "Ok" + ::msgcat::mcset fr "Open" "Ouvrir" + ::msgcat::mcset fr "&Open" "&Ouvrir" + ::msgcat::mcset fr "Open Multiple Files" "Ouvrir plusieurs fichiers" + ::msgcat::mcset fr "Paste" "Coller" + ::msgcat::mcset fr "Quit" "Quitter" + ::msgcat::mcset fr "&Red" "&Rouge" + ::msgcat::mcset fr "Replace existing file?" "Remplacer le fichier existant?" + ::msgcat::mcset fr "&Retry" "&R\u00e9-essayer" + ::msgcat::mcset fr "&Save" "&Sauvegarder" + ::msgcat::mcset fr "Save As" "Sauvegarder sous" + ::msgcat::mcset fr "Save To Log" "Sauvegarde au fichier de trace" + ::msgcat::mcset fr "Select Log File" "Choisir un fichier de trace" + ::msgcat::mcset fr "Select a file to source" "Choisir un fichier \u00e0 \u00e9valuer" + ::msgcat::mcset fr "&Selection:" "&S\u00e9lection:" + ::msgcat::mcset fr "Skip Messages" "Omettre les messages" + ::msgcat::mcset fr "Source..." "\u00c9valuer..." + ::msgcat::mcset fr "Tcl Scripts" "Scripts Tcl" + ::msgcat::mcset fr "Tcl for Windows" "Tcl pour Windows" + ::msgcat::mcset fr "Text Files" "Fichiers texte" + ::msgcat::mcset fr "&Yes" "&Oui" + ::msgcat::mcset fr "abort" "abandonner" + ::msgcat::mcset fr "blue" "bleu" + ::msgcat::mcset fr "cancel" "annuler" + ::msgcat::mcset fr "extension" + ::msgcat::mcset fr "extensions" + ::msgcat::mcset fr "green" "vert" + ::msgcat::mcset fr "ignore" "ignorer" + ::msgcat::mcset fr "ok" + ::msgcat::mcset fr "red" "rouge" + ::msgcat::mcset fr "retry" "r\u00e9essayer" + ::msgcat::mcset fr "yes" "oui" +} diff --git a/ext/tk/sample/msgs_tk/it.msg b/ext/tk/sample/msgs_tk/it.msg new file mode 100644 index 0000000000..b144fcc073 --- /dev/null +++ b/ext/tk/sample/msgs_tk/it.msg @@ -0,0 +1,84 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset it "Application Error" "Errore dell' applicazione" + ::msgcat::mcset it "Blue" "Blu" + ::msgcat::mcset it "Color" "Colore" + ::msgcat::mcset it "Delete" "Incolla" + ::msgcat::mcset it "Error" "Errore" + ::msgcat::mcset it "Exit" "Esci" + ::msgcat::mcset it "Green" "Verde" + ::msgcat::mcset it "Red" "Rosso" + ::msgcat::mcset it "blue" "blu" + ::msgcat::mcset it "green" "verde" + ::msgcat::mcset it "red" "rosso" +} + +namespace eval ::tk { + ::msgcat::mcset it "&Abort" "&Interrompi" + ::msgcat::mcset it "About..." "Informazioni ..." + ::msgcat::mcset it "All Files" "Tutti i file" + ::msgcat::mcset it "Application Error" "Errore dell' applicazione" + ::msgcat::mcset it "&Blue" "&Blu" + ::msgcat::mcset it "&Cancel" "&Annulla" + ::msgcat::mcset it "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossibile accedere alla directory \"%1\$s\".\nPermesso negato." + ::msgcat::mcset it "Choose Directory" "Scegli directory" + ::msgcat::mcset it "Clear" "Azzera" + ::msgcat::mcset it "Color" "Colore" + ::msgcat::mcset it "Console" + ::msgcat::mcset it "Copy" "Copia" + ::msgcat::mcset it "Cut" "Taglia" + ::msgcat::mcset it "Delete" "Incolla" + ::msgcat::mcset it "Details >>" "Dettagli >>" + ::msgcat::mcset it "Directory \"%1\$s\" does not exist." "La directory \"%1\$s\" non esiste." + ::msgcat::mcset it "&Directory:" + ::msgcat::mcset it "Error: %1\$s" "Errore: %1\$s" + ::msgcat::mcset it "Exit" "Esci" + ::msgcat::mcset it "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Il file \"%1\$s\" esiste gi\u00e0.\nVuoi sovrascriverlo?" + ::msgcat::mcset it "File \"%1\$s\" already exists.\n\n" "Il file \"%1\$s\" esiste gi\u00e0.\n\n" + ::msgcat::mcset it "File \"%1\$s\" does not exist." "Il file \"%1\$s\" non esiste." + ::msgcat::mcset it "File &name:" "&Nome del file:" + ::msgcat::mcset it "File &names:" "&Nomi dei file:" + ::msgcat::mcset it "Files of &type:" "File di &tipo:" + ::msgcat::mcset it "Fi&les:" "Fi&le:" + ::msgcat::mcset it "&Filter" "&Filtro" + ::msgcat::mcset it "Fil&ter:" "Fil&tro:" + ::msgcat::mcset it "&Green" "&Verde" + ::msgcat::mcset it "Hi" "Salve" + ::msgcat::mcset it "Hide Console" "Nascondi la console" + ::msgcat::mcset it "&Ignore" "&Ignora" + ::msgcat::mcset it "Invalid file name \"%1\$s\"." "Nome di file non valido \"%1\$s\"." + ::msgcat::mcset it "Log Files" "File di log" + ::msgcat::mcset it "&No" + ::msgcat::mcset it "&OK" + ::msgcat::mcset it "Ok" + ::msgcat::mcset it "&Open" "A&pri" + ::msgcat::mcset it "Open" "Apri" + ::msgcat::mcset it "Open Multiple Files" "Apri file multipli" + ::msgcat::mcset it "Paste" "Incolla" + ::msgcat::mcset it "Quit" "Esci" + ::msgcat::mcset it "&Red" "&Rosso" + ::msgcat::mcset it "Replace existing file?" "Sostituisci il file esistente?" + ::msgcat::mcset it "&Retry" "&Riprova" + ::msgcat::mcset it "&Save" "&Salva" + ::msgcat::mcset it "Save As" "Salva come" + ::msgcat::mcset it "Save To Log" "Salva il log" + ::msgcat::mcset it "Select Log File" "Scegli un file di log" + ::msgcat::mcset it "Select a file to source" "Scegli un file da eseguire" + ::msgcat::mcset it "&Selection:" "&Selezione:" + ::msgcat::mcset it "Skip Messages" "Salta i messaggi" + ::msgcat::mcset it "Source..." "Esegui..." + ::msgcat::mcset it "Tcl Scripts" "Scripts Tcl" + ::msgcat::mcset it "Tcl for Windows" "Tcl per Windows" + ::msgcat::mcset it "Text Files" "File di testo" + ::msgcat::mcset it "&Yes" "&Si" + ::msgcat::mcset it "abort" "interrompi" + ::msgcat::mcset it "blue" "blu" + ::msgcat::mcset it "cancel" "annulla" + ::msgcat::mcset it "extension" "estensione" + ::msgcat::mcset it "extensions" "estensioni" + ::msgcat::mcset it "green" "verde" + ::msgcat::mcset it "ignore" "ignora" + ::msgcat::mcset it "ok" + ::msgcat::mcset it "red" "rosso" + ::msgcat::mcset it "retry" "riprova" + ::msgcat::mcset it "yes" "si" +} diff --git a/ext/tk/sample/msgs_tk/ja.msg b/ext/tk/sample/msgs_tk/ja.msg new file mode 100644 index 0000000000..44a25839db --- /dev/null +++ b/ext/tk/sample/msgs_tk/ja.msg @@ -0,0 +1,13 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset ja "Application Error" "\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30A8\u30E9\u30FC" + ::msgcat::mcset ja "Blue" "\u9752" + ::msgcat::mcset ja "Color" "\u80CC\u666F\u8272" + ::msgcat::mcset ja "Delete" "\u6D88\u53BB" + ::msgcat::mcset ja "Error" "\u30A8\u30E9\u30FC" + ::msgcat::mcset ja "Exit" "\u7D42\u4E86" + ::msgcat::mcset ja "Green" "\u7DD1" + ::msgcat::mcset ja "Red" "\u8D64" + ::msgcat::mcset ja "blue" "\u9752" + ::msgcat::mcset ja "green" "\u7DD1" + ::msgcat::mcset ja "red" "\u8D64" +} diff --git a/ext/tk/sample/msgs_tk/license.terms b/ext/tk/sample/msgs_tk/license.terms new file mode 100644 index 0000000000..03ca6fcb31 --- /dev/null +++ b/ext/tk/sample/msgs_tk/license.terms @@ -0,0 +1,39 @@ +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., and other parties. The following +terms apply to all files associated with the software unless explicitly +disclaimed in individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. diff --git a/ext/tk/sample/msgs_tk/nl.msg b/ext/tk/sample/msgs_tk/nl.msg new file mode 100644 index 0000000000..d9642e808c --- /dev/null +++ b/ext/tk/sample/msgs_tk/nl.msg @@ -0,0 +1,123 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset nl "Application Error" "Toepassingsfout" + ::msgcat::mcset nl "Blue" "Blauw" + ::msgcat::mcset nl "Color" "Kleur" + ::msgcat::mcset nl "Delete" "Wissen" + ::msgcat::mcset nl "Error" "Fout" + ::msgcat::mcset nl "Exit" "Be\u00ebindigen" + ::msgcat::mcset nl "Green" "Groen" + ::msgcat::mcset nl "Red" "Rood" + ::msgcat::mcset nl "blue" "blauw" + ::msgcat::mcset nl "green" "groen" + ::msgcat::mcset nl "red" "rood" +} + +namespace eval ::tk { + ::msgcat::mcset nl "\"%1\$s\" must be an absolute pathname" "\"%1\$s\" moet een absolute pad-naam zijn" + ::msgcat::mcset nl "%1\$s is not a toplevel window" "%1\$s is geen toplevel window" + ::msgcat::mcset nl ", or" ", of" + ::msgcat::mcset nl "-default, -icon, -message, -parent, -title, or -type" "-default, -icon, -message, -parent, -title, of -type" + ::msgcat::mcset nl "-initialdir, -mustexist, -parent, or -title" "-initialdir, -mustexist, -parent, of -title" + ::msgcat::mcset nl "&Abort" "&Afbreken" + ::msgcat::mcset nl "About..." "Over..." + ::msgcat::mcset nl "All Files" "Alle Bestanden" + ::msgcat::mcset nl "Application Error" "Toepassingsfout" + ::msgcat::mcset nl "&Blue" "&Blauw" + ::msgcat::mcset nl "&Cancel" "&Annuleren" + ::msgcat::mcset nl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan niet naar map \"%1\$s\" gaan.\nU heeft hiervoor geen toestemming." + ::msgcat::mcset nl "Choose Directory" "Kies map" + ::msgcat::mcset nl "Clear" "Wissen" + ::msgcat::mcset nl "Clear entry, Press OK; Enter %1\$s, press OK" "Wis veld, Druk op OK; typ %1\$s in, druk op OK" + ::msgcat::mcset nl "&Clear Console" "&Wis Console" + ::msgcat::mcset nl "Color" "Kleur" + ::msgcat::mcset nl "Console" + ::msgcat::mcset nl "Copy" "Kopi\u00ebren" + ::msgcat::mcset nl "Cut" "Knippen" + ::msgcat::mcset nl "Delete" "Wissen" + ::msgcat::mcset nl "Details" + ::msgcat::mcset nl "Details >>" + ::msgcat::mcset nl "Directory \"%1\$s\" does not exist." "Map \"%1\$s\" bestaat niet." + ::msgcat::mcset nl "&Directory:" "&Map:" + ::msgcat::mcset nl "Edit" "Bewerken" + ::msgcat::mcset nl "Enter \"%1\$s\", press OK" "Typ \"%1\$s\", druk op OK" + ::msgcat::mcset nl "Enter \"%1\$s\", press OK, enter \"%2\$s\", press OK" "Typ \"%1\$s\", druk op OK, typ \"%2\$s\", druk op OK" + ::msgcat::mcset nl "Error: %1\$s" "Fout: %1\$s" + ::msgcat::mcset nl "Exit" "Be\u00ebindigen" + ::msgcat::mcset nl "File" "Bestand" + ::msgcat::mcset nl "File \"%1\$s\" already exists.\n\n" "Bestand \"%1\$s\" bestaat al.\n\n" + ::msgcat::mcset nl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Bestand \"%1\$s\" bestaat al.\nWilt u het overschrijven?" + ::msgcat::mcset nl "File \"%1\$s\" does not exist." "Bestand \"%1\$s\" bestaat niet." + ::msgcat::mcset nl "File &name:" "Bestands&naam:" + ::msgcat::mcset nl "File &names:" "Bestands&namen:" + ::msgcat::mcset nl "Files of &type:" "Bestanden van het &type:" + ::msgcat::mcset nl "Fi&les:" "&Bestanden:" + ::msgcat::mcset nl "&Filter" + ::msgcat::mcset nl "Fil&ter:" + ::msgcat::mcset nl "&Green" "&Groen" + ::msgcat::mcset nl "Hi" "H\u00e9" + ::msgcat::mcset nl "Hide Console" "Verberg Console" + ::msgcat::mcset nl "&Ignore" "&Negeren" + ::msgcat::mcset nl "Invalid file name \"%1\$s\"." "Ongeldige bestandsnaam \"%1\$s\"." + ::msgcat::mcset nl "Log Files" "Log Bestanden" + ::msgcat::mcset nl "&No" "&Nee" + ::msgcat::mcset nl "&OK" + ::msgcat::mcset nl "Ok" + ::msgcat::mcset nl "&Open" "&Openen" + ::msgcat::mcset nl "Open" "Openen" + ::msgcat::mcset nl "Open Multiple Files" "Open meerdere bestanden" + ::msgcat::mcset nl "Paste" "Plakken" + ::msgcat::mcset nl "Please press %1\$s" "Druk op %1\$s, A.U.B." + ::msgcat::mcset nl "Please press ok" "Druk op ok, A.U.B." + ::msgcat::mcset nl "Press Cancel" "Druk op Annuleren" + ::msgcat::mcset nl "Press Ok" "Druk op Ok" + ::msgcat::mcset nl "Quit" "Stoppen" + ::msgcat::mcset nl "&Red" "&Rood" + ::msgcat::mcset nl "Replace existing file?" "Vervang bestaand bestand?" + ::msgcat::mcset nl "&Retry" "&Herhalen" + ::msgcat::mcset nl "&Save" "Op&slaan" + ::msgcat::mcset nl "Save As" "Opslaan als" + ::msgcat::mcset nl "Save To Log" "Opslaan naar Log" + ::msgcat::mcset nl "Select Log File" "Selecteer Log bestand" + ::msgcat::mcset nl "Select a file to source" "Selecteer bronbestand" + ::msgcat::mcset nl "&Selection:" "&Selectie:" + ::msgcat::mcset nl "Skip Messages" "Berichten overslaan" + ::msgcat::mcset nl "Source..." "Bron..." + ::msgcat::mcset nl "Tcl Scripts" + ::msgcat::mcset nl "Tcl for Windows" "Tcl voor Windows" + ::msgcat::mcset nl "Text Files" "Tekstbestanden" + ::msgcat::mcset nl "&Yes" "&Ja" + ::msgcat::mcset nl "abort" "afbreken" + ::msgcat::mcset nl "abort, retry, ignore, ok, cancel, no, or yes" "afbreken, opnieuw, negeren, ok, annuleren, nee, of ja" + ::msgcat::mcset nl "abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel" "abortretryignore, ok, okcancel, retrycancel, yesno, of yesnocancel" + ::msgcat::mcset nl "bad %1\$s value \"%2\$s\": must be %3\$s" "verkeerde %1\$s waarde \"%2\$s\": moet zijn %3\$s" + ::msgcat::mcset nl "bad file type \"%1\$s\", should be" "verkeerd bestandstype \"%1\$s\", moet zijn" + ::msgcat::mcset nl "bad option \"%1\$s\": should be %2\$s" "verkeerde optie \"%1\$s\": moet zijn %2\$s" + ::msgcat::mcset nl "bad window path name \"%1\$s\"" "verkeerde window-padnaam \"%1\$s\"" + ::msgcat::mcset nl "blue" "blauw" + ::msgcat::mcset nl "can't post %1\$s: it isn't a descendant of %2\$s (this is a new requirement in Tk versions 3.0 and later)" "kan %1\$s niet verzenden: het is geen afstammeling van %2\$s (dit is een nieuwe eis in Tk versies 3.0 en later)" + ::msgcat::mcset nl "cancel" "annuleren" + ::msgcat::mcset nl "default button index greater than number of buttons specified for tk_dialog" "default knop index is groter dan het aantal knoppen beschikbaar voor tk_dialog" + ::msgcat::mcset nl "display name to use (current one otherwise)" "te gebruiken schermnaam (anders huidige scherm)" + ::msgcat::mcset nl "error, info, question, or warning" "error, info, question, of warning" + ::msgcat::mcset nl "extension" + ::msgcat::mcset nl "extensions" + ::msgcat::mcset nl "focus group \"%1\$s\" doesn't exist" "focusgroep \"%1\$s\" bestaat niet" + ::msgcat::mcset nl "green" "groen" + ::msgcat::mcset nl "history event %1\$s" + ::msgcat::mcset nl "ignore" "negeren" + ::msgcat::mcset nl "invalid default button \"%1\$s\"" "ongeldige default knop \"%1\$s\"" + ::msgcat::mcset nl "macType" + ::msgcat::mcset nl "macTypes" + ::msgcat::mcset nl "must specify a background color" "een achtergrondkleur is verplicht" + ::msgcat::mcset nl "name of the slave interpreter" "naam van de slaaf-interpreter" + ::msgcat::mcset nl "no winfo screen . nor env(DISPLAY)" "geen winfo scherm . noch env(DISPLAY)" + ::msgcat::mcset nl "ok" + ::msgcat::mcset nl "red" "rood" + ::msgcat::mcset nl "retry" "opnieuw" + ::msgcat::mcset nl "should contain 5 or 4 elements" "moet 4 of 5 elementen bevatten" + ::msgcat::mcset nl "spec" + ::msgcat::mcset nl "tk_chooseDirectory command" "tk_chooseDirectory opdracht" + ::msgcat::mcset nl "tk_chooseDirectory command, cancel gives null" "tk_chooseDirectory opdracht, annuleren geeft lege waarde" + ::msgcat::mcset nl "tk_chooseDirectory command, initialdir" "tk_chooseDirectory opdracht, initi\u00eble map" + ::msgcat::mcset nl "yes" "ja" +} diff --git a/ext/tk/sample/msgs_tk/pl.msg b/ext/tk/sample/msgs_tk/pl.msg new file mode 100644 index 0000000000..2699e42bdf --- /dev/null +++ b/ext/tk/sample/msgs_tk/pl.msg @@ -0,0 +1,87 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset pl "Application Error" "Bl\u0105d w Programie" + ::msgcat::mcset pl "Blue" "Niebieski" + ::msgcat::mcset pl "Color" "Kolor" + ::msgcat::mcset pl "Delete" "Usu\u0144" + ::msgcat::mcset pl "Error" "B\u0142\u0105d" + ::msgcat::mcset pl "Exit" "Zako\u0144cz" + ::msgcat::mcset pl "Green" "Zielony" + ::msgcat::mcset pl "Red" "Czerwonz" + ::msgcat::mcset pl "blue" "niebieski" + ::msgcat::mcset pl "green" "zielony" + ::msgcat::mcset pl "red" "czerwony" +} + +namespace eval ::tk { + ::msgcat::mcset pl "&Abort" "&Anuluj" + ::msgcat::mcset pl "&About..." "O Programie..." + ::msgcat::mcset pl "All Files" "Wszystkie pliki" + ::msgcat::mcset pl "Application Error" "Bl\u0105d w Programie" + ::msgcat::mcset pl "&Blue" "&Niebieski" + ::msgcat::mcset pl "&Cancel" "&Anuluj" + ::msgcat::mcset pl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Katalog \"%1\$s\" nie mo\u017ce zosta\u0107 odczytany lub nie istnieje." + ::msgcat::mcset pl "Choose Directory" "Wybierz katalog" + ::msgcat::mcset pl "&Clear" "&Wyczy\u015b\u0107" + ::msgcat::mcset pl "&Clear Console" "&Wyczy\u015b\u0107 konsol\u0119" + ::msgcat::mcset pl "Color" "Kolor" + ::msgcat::mcset pl "Console" "Konsola" + ::msgcat::mcset pl "&Copy" "&Kopiuj" + ::msgcat::mcset pl "Cu&t" "&Wytnij" + ::msgcat::mcset pl "&Delete" "&Usu\u0144" + ::msgcat::mcset pl "Details >>" "Detale >>" + ::msgcat::mcset pl "Directory \"%1\$s\" does not exist." "Katalog \"%1\$s\" nie istniej." + ::msgcat::mcset pl "&Directory:" "&Katalog:" + ::msgcat::mcset pl "&Edit" "&Edytuj" + ::msgcat::mcset pl "Error: %1\$s" "B\u0142\u0105d: %1\$s" + ::msgcat::mcset pl "E&xit" "&Zako\u0144cz" + ::msgcat::mcset pl "&File" "&Plik" + ::msgcat::mcset pl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Plik \"%1\$s\" ju\u017c istnieje.\nCzy chcesz go zast\u0105pi\u0107?" + ::msgcat::mcset pl "File \"%1\$s\" already exists.\n\n" "Plik \"%1\$s\" ju\u017c istnieje. \n\n" + ::msgcat::mcset pl "File \"%1\$s\" does not exist." "Plik \"%1\$s\" nie istnieje." + ::msgcat::mcset pl "File &name:" "Nazwa &pliku:" + ::msgcat::mcset pl "File &names:" "Nazwy &plik\u00f3w:" + ::msgcat::mcset pl "Files of &type:" "Pliki &typu:" + ::msgcat::mcset pl "Fi&les:" "Pli&ki:" + ::msgcat::mcset pl "&Filter" "&Filter" + ::msgcat::mcset pl "Fil&ter:" "&Filter:" + ::msgcat::mcset pl "&Green" "&Zielony" + ::msgcat::mcset pl "&Help" "&Pomoc" + ::msgcat::mcset pl "Hi" "Witaj" + ::msgcat::mcset pl "&Hide Console" "&Schowaj konsol\u0119" + ::msgcat::mcset pl "&Ignore" "&Ignoruj" + ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "Niew\u0142a\u015bciwa nazwa pliku \"%1\$s\"." + ::msgcat::mcset pl "Log Files" "Protoko\u0142uj" + ::msgcat::mcset pl "&No" "&Nie" + ::msgcat::mcset pl "OK" + ::msgcat::mcset pl "Ok" + ::msgcat::mcset pl "Open" "Wczytaj" + ::msgcat::mcset pl "&Open" "&Wczytaj" + ::msgcat::mcset pl "Open Multiple Files" "Wczytuj wiele plik\u00f3w" + ::msgcat::mcset pl "P&aste" "&Wklej" + ::msgcat::mcset pl "&Quit" "&Zako\u0144cz" + ::msgcat::mcset pl "&Red" "&Czerwonz" + ::msgcat::mcset pl "Replace existing file?" "Czy zost\u0105pi\u0107 instniej\u0105cy plik?" + ::msgcat::mcset pl "&Retry" "&Powt\u00f3rz" + ::msgcat::mcset pl "&Save" "&Zapisz" + ::msgcat::mcset pl "Save As" "Zapisz jako" + ::msgcat::mcset pl "Save To Log" "Wpisz do protoko\u0142u" + ::msgcat::mcset pl "Select Log File" "Wybierz plik proko\u0142u" + ::msgcat::mcset pl "Select a file to source" "Wybierz plik do wykonania" + ::msgcat::mcset pl "&Selection:" "&Wyb\u00f3r:" + ::msgcat::mcset pl "Skip Messages" "Omi\u0144 pozosta\u0142e komunikaty" + ::msgcat::mcset pl "&Source..." "&Kod \u017ar\u00f3d\u0142owy..." + ::msgcat::mcset pl "Tcl Scripts" "Tcl-skrypty" + ::msgcat::mcset pl "Tcl for Windows" "Tcl dla Okienek (Windows)" + ::msgcat::mcset pl "Text Files" "Pliki Tekstowe" + ::msgcat::mcset pl "&Yes" "&Tak" + ::msgcat::mcset pl "abort" "zako\u0144cz" + ::msgcat::mcset pl "blue" "niebieski" + ::msgcat::mcset pl "cancel" "anuluj" + ::msgcat::mcset pl "extension" "rozszerzenie" + ::msgcat::mcset pl "extensions" "rozszerzenia" + ::msgcat::mcset pl "green" "zielony" + ::msgcat::mcset pl "ignore" "ignoruj" + ::msgcat::mcset pl "red" "czerwony" + ::msgcat::mcset pl "retry" "potw\u00f3rz" + ::msgcat::mcset pl "yes" "tak" +} diff --git a/ext/tk/sample/msgs_tk/ru.msg b/ext/tk/sample/msgs_tk/ru.msg new file mode 100644 index 0000000000..a1192b7095 --- /dev/null +++ b/ext/tk/sample/msgs_tk/ru.msg @@ -0,0 +1,87 @@ +namespace eval ::tkmsgcat_demo { + ::msgcat::mcset ru "Application Error" "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435" + ::msgcat::mcset ru "Blue" " \u0413\u043e\u043b\u0443\u0431\u043e\u0439" + ::msgcat::mcset ru "Color" "\u0426\u0432\u0435\u0442" + ::msgcat::mcset ru "Delete" "\u0423\u0434\u0430\u043b\u0438\u0442\u044c" + ::msgcat::mcset ru "Error" "\u041e\u0448\u0438\u0431\u043a\u0430" + ::msgcat::mcset ru "Exit" "\u0412\u044b\u0445\u043e\u0434" + ::msgcat::mcset ru "Green" "\u0417\u0435\u043b\u0435\u043d\u044b\u0439" + ::msgcat::mcset ru "Red" "\u041a\u0440\u0430\u0441\u043d\u044b\u0439" + ::msgcat::mcset ru "blue" " \u0433\u043e\u043b\u0443\u0431\u043e\u0439" + ::msgcat::mcset ru "green" " \u0437\u0435\u043b\u0435\u043d\u044b\u0439" + ::msgcat::mcset ru "red" " \u043a\u0440\u0430\u0441\u043d\u044b\u0439" +} + +namespace eval ::tk { + ::msgcat::mcset ru "&Abort" "&\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c" + ::msgcat::mcset ru "About..." "\u041f\u0440\u043e..." + ::msgcat::mcset ru "All Files" "\u0412\u0441\u0435 \u0444\u0430\u0439\u043b\u044b" + ::msgcat::mcset ru "Application Error" "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435" + ::msgcat::mcset ru "&Blue" " &\u0413\u043e\u043b\u0443\u0431\u043e\u0439" + ::msgcat::mcset ru "&Cancel" "\u041e\u0442&\u043c\u0435\u043d\u0430" + ::msgcat::mcset ru "Cannot change to the directory \"%1\$s\".\nPermission denied." \ + "\u041d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \"%1\$s\".\n\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430" + ::msgcat::mcset ru "Choose Directory" "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433" + ::msgcat::mcset ru "Clear" "\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c" + ::msgcat::mcset ru "Color" "\u0426\u0432\u0435\u0442" + ::msgcat::mcset ru "Console" "\u041a\u043e\u043d\u0441\u043e\u043b\u044c" + ::msgcat::mcset ru "Copy" "\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c" + ::msgcat::mcset ru "Cut" "\u0412\u044b\u0440\u0435\u0437\u0430\u0442\u044c" + ::msgcat::mcset ru "Delete" "\u0423\u0434\u0430\u043b\u0438\u0442\u044c" + ::msgcat::mcset ru "Details >>" "\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 >>" + ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "\u041a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \"%1\$s\" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." + ::msgcat::mcset ru "&Directory:" "&\u041a\u0430\u0442\u0430\u043b\u043e\u0433:" + ::msgcat::mcset ru "Error: %1\$s" "\u041e\u0448\u0438\u0431\u043a\u0430: %1\$s" + ::msgcat::mcset ru "Exit" "\u0412\u044b\u0445\u043e\u0434" + ::msgcat::mcset ru "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \ + "\u0424\u0430\u0439\u043b \"%1\$s\" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e?" + ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "\u0424\u0430\u0439\u043b \"%1\$s\" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\n" + ::msgcat::mcset ru "File \"%1\$s\" does not exist." "\u0424\u0430\u0439\u043b \"%1\$s\" \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." + ::msgcat::mcset ru "File &name:" "&\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430:" + ::msgcat::mcset ru "File &names:" "&\u0418\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432:" + ::msgcat::mcset ru "Files of &type:" "&\u0422\u0438\u043f \u0444\u0430\u0439\u043b\u043e\u0432:" + ::msgcat::mcset ru "Fi&les:" "\u0424\u0430\u0439&\u043b\u044b:" + ::msgcat::mcset ru "&Filter" "&\u0424\u0438\u043b\u044c\u0442\u0440" + ::msgcat::mcset ru "Fil&ter:" "\u0424\u0438\u043b\u044c&\u0442\u0440:" + ::msgcat::mcset ru "&Green" " &\u0417\u0435\u043b\u0435\u043d\u044b\u0439" + ::msgcat::mcset ru "Hi" "\u041f\u0440\u0438\u0432\u0435\u0442" + ::msgcat::mcset ru "Hide Console" "\u0421\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c" + ::msgcat::mcset ru "&Ignore" "&\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c" + ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \"%1\$s\"." + ::msgcat::mcset ru "Log Files" "\u0424\u0430\u0439\u043b\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u0430" + ::msgcat::mcset ru "&No" "&\u041d\u0435\u0442" + ::msgcat::mcset ru "&OK" "&\u041e\u041a" + ::msgcat::mcset ru "Ok" "\u0414\u0430" + ::msgcat::mcset ru "Open" "\u041e\u0442\u043a\u0440\u044b\u0442\u044c" + ::msgcat::mcset ru "&Open" "&\u041e\u0442\u043a\u0440\u044b\u0442\u044c" + ::msgcat::mcset ru "Open Multiple Files" "\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432" + ::msgcat::mcset ru "Paste" "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c" + ::msgcat::mcset ru "Quit" "\u0412\u044b\u0445\u043e\u0434" + ::msgcat::mcset ru "&Red" " &\u041a\u0440\u0430\u0441\u043d\u044b\u0439" + ::msgcat::mcset ru "Replace existing file?" "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b?" + ::msgcat::mcset ru "&Retry" "&\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c" + ::msgcat::mcset ru "&Save" "&\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c" + ::msgcat::mcset ru "Save As" "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a" + ::msgcat::mcset ru "Save To Log" "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b" + ::msgcat::mcset ru "Select Log File" "\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b" + ::msgcat::mcset ru "Select a file to source" "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438" + ::msgcat::mcset ru "&Selection:" "&Selection:" + ::msgcat::mcset ru "Skip Messages" "\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f" + ::msgcat::mcset ru "Source..." "\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b..." + ::msgcat::mcset ru "Tcl Scripts" "\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 TCL" + ::msgcat::mcset ru "Tcl for Windows" "TCL \u0434\u043b\u044f Windows" + ::msgcat::mcset ru "Text Files" "\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b" + ::msgcat::mcset ru "&Yes" "&\u0414\u0430" + ::msgcat::mcset ru "abort" "\u043e\u0442\u043c\u0435\u043d\u0430" + ::msgcat::mcset ru "blue" " \u0433\u043e\u043b\u0443\u0431\u043e\u0439" + ::msgcat::mcset ru "cancel" "\u043e\u0442\u043c\u0435\u043d\u0430" + ::msgcat::mcset ru "extension" "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435" + ::msgcat::mcset ru "extensions" "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f" + ::msgcat::mcset ru "green" " \u0437\u0435\u043b\u0435\u043d\u044b\u0439" + ::msgcat::mcset ru "ignore" "\u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c" + ::msgcat::mcset ru "ok" "\u043e\u043a" + ::msgcat::mcset ru "red" " \u043a\u0440\u0430\u0441\u043d\u044b\u0439" + ::msgcat::mcset ru "retry" "\u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c" + ::msgcat::mcset ru "yes" "\u0434\u0430" +} + diff --git a/ext/tk/sample/propagate.rb b/ext/tk/sample/propagate.rb new file mode 100644 index 0000000000..a6fbc9725a --- /dev/null +++ b/ext/tk/sample/propagate.rb @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby +require 'tk' + +TkLabel.new(:text=>"Please click the bottom frame").pack + +f = TkFrame.new(:width=>400, :height=>100, :background=>'yellow', + :relief=>'ridge', :borderwidth=>5).pack + +# TkPack.propagate(f, false) # <== important!! +f.pack_propagate(false) # <== important!! + +list = (1..3).collect{|n| + TkButton.new(f, :text=>"button#{'-X'*n}"){ + command proc{ + puts "button#{'-X'*n}" + self.unpack + } + } +} + +list.unshift(nil) + +f.bind('1', proc{ + w = list.shift + w.unpack if w + list.push(w) + list[0].pack(:expand=>true, :anchor=>:center) if list[0] + }) + +Tk.mainloop diff --git a/ext/tk/sample/safe-tk.rb b/ext/tk/sample/safe-tk.rb index 0a25c804f0..a93707220e 100644 --- a/ext/tk/sample/safe-tk.rb +++ b/ext/tk/sample/safe-tk.rb @@ -10,7 +10,6 @@ safe_slave2 = MultiTkIp.new_safeTk('fill'=>:none, 'expand'=>false) #safe_slave2 = MultiTkIp.new_safeTk('fill'=>:none) #safe_slave2 = MultiTkIp.new_safeTk('expand'=>false) - cmd = Proc.new{|txt| ##################### ## from TkTimer2.rb diff --git a/ext/tk/sample/tkballoonhelp.rb b/ext/tk/sample/tkballoonhelp.rb index 312e376a07..b71c5746db 100644 --- a/ext/tk/sample/tkballoonhelp.rb +++ b/ext/tk/sample/tkballoonhelp.rb @@ -92,7 +92,7 @@ if __FILE__ == $0 TkButton.new('text'=>'This button has another balloon help') {|b| pack('fill'=>'x') TkBalloonHelp.new(b, 'text'=>'configured message', - 'interval'=>500, 'font'=>'courier', + 'interval'=>200, 'font'=>'courier', 'background'=>'gray', 'foreground'=>'red') } Tk.mainloop diff --git a/ext/tk/sample/tkline.rb b/ext/tk/sample/tkline.rb index 2406b0749f..5bdf3aec78 100644 --- a/ext/tk/sample/tkline.rb +++ b/ext/tk/sample/tkline.rb @@ -15,6 +15,8 @@ def start_random end end +Label.new('text'=>'Please press or drag button-1').pack + $c = Canvas.new $c.pack $start_x = start_y = 0 diff --git a/ext/tk/sample/tkmsgcat-load_rb.rb b/ext/tk/sample/tkmsgcat-load_rb.rb new file mode 100644 index 0000000000..6a3289e061 --- /dev/null +++ b/ext/tk/sample/tkmsgcat-load_rb.rb @@ -0,0 +1,102 @@ +#!/usr/bin/env ruby + +require 'tk' + +demo_dir = File.dirname($0) +msgcat_dir = [demo_dir, 'msgs_rb'].join(File::Separator) +top_win = nil +#msgcat = TkMsgCatalog.new('::tk') +msgcat = TkMsgCatalog.new('::tkmsgcat_demo') +default_locale = msgcat.locale +#msgcat.load_rb(msgcat_dir) +msgcat.load(msgcat_dir) + +col_proc = TkComm.install_bind(proc{|w, color, frame, label| + TkComm.window(frame).background(color) + Tk.update + TkComm.window(label).text( + msgcat["%1$s:: %2$s", 'Color', + color.capitalize]) + w.flash; w.flash + Tk.callback_break; + }, "%W") + +del_proc = TkComm.install_cmd(proc{top_win.destroy; top_win = nil}) + +err_proc = TkComm.install_cmd(proc{fail(RuntimeError, + msgcat['Application Error'])}) + +show_sample = proc{|loc| + top_win = TkToplevel.new(:title=>loc) + + msgcat.locale = loc + #msgcat.load_rb(msgcat_dir) + msgcat.load(msgcat_dir) + + TkLabel.new(top_win){ + text "preferences:: #{msgcat.preferences.join(' ')}" + pack(:pady=>10, :padx=>10) + } + + lbl = TkLabel.new(top_win, :text=>msgcat["%1$s:: %2$s", + 'Color', '']).pack(:anchor=>'w') + + bg = TkFrame.new(top_win).pack(:ipadx=>20, :ipady=>10, + :expand=>true, :fill=>:both) + + TkFrame.new(bg){|f| + ['blue', 'green', 'red'].each{|col| + TkButton.new(f, :text=>msgcat[col]){ + bind('ButtonRelease-1', col_proc, "#{col} #{bg.path} #{lbl.path}") + }.pack(:fill=>:x) + } + }.pack(:anchor=>'center', :pady=>15) + + TkFrame.new(top_win){|f| + TkButton.new(f, :text=>msgcat['Delete'], + :command=>del_proc).pack(:side=>:right, :padx=>5) + TkButton.new(f, :text=>msgcat['Error'], + :command=>err_proc).pack(:side=>:left, :padx=>5) + }.pack(:side=>:bottom, :fill=>:x) + + top_win +} + + +# listbox for locale list +TkLabel.new(:text=>"Please click a locale.").pack(:padx=>5, :pady=>3) + +TkFrame.new{|f| + TkButton.new(f, :text=>msgcat['Exit'], + :command=>proc{exit}).pack(:side=>:right, :padx=>5) +}.pack(:side=>:bottom, :fill=>:x) + +f = TkFrame.new.pack(:side=>:top, :fill=>:both, :expand=>true) +lbox = TkListbox.new(f).pack(:side=>:left, :fill=>:both, :expand=>true) +lbox.yscrollbar(TkScrollbar.new(f, :width=>12).pack(:side=>:right, :fill=>:y)) + +lbox.bind('ButtonRelease-1'){|ev| + idx = lbox.index("@#{ev.x},#{ev.y}") + if idx == 0 + loc = default_locale + else + loc = lbox.get(idx) + end + if top_win != nil && top_win.exist? + top_win.destroy + end + top_win = show_sample.call(loc) +} + +lbox.insert('end', 'default') + +Dir.entries(msgcat_dir).sort.each{|f| + if f =~ /^(.*).msg$/ + lbox.insert('end', $1) + end +} + +top_win = show_sample.call(default_locale) + +# start eventloop +Tk.mainloop diff --git a/ext/tk/sample/tkmsgcat-load_rb2.rb b/ext/tk/sample/tkmsgcat-load_rb2.rb new file mode 100644 index 0000000000..720ab94e13 --- /dev/null +++ b/ext/tk/sample/tkmsgcat-load_rb2.rb @@ -0,0 +1,102 @@ +#!/usr/bin/env ruby + +require 'tk' + +demo_dir = File.dirname($0) +msgcat_dir = [demo_dir, 'msgs_rb2'].join(File::Separator) +top_win = nil +#msgcat = TkMsgCatalog.new('::tk') +msgcat = TkMsgCatalog.new('::tkmsgcat_demo') +default_locale = msgcat.locale +#msgcat.load_rb(msgcat_dir) +msgcat.load(msgcat_dir) + +col_proc = TkComm.install_bind(proc{|w, color, frame, label| + TkComm.window(frame).background(color) + Tk.update + TkComm.window(label).text( + msgcat["%1$s:: %2$s", 'Color', + color.capitalize]) + w.flash; w.flash + Tk.callback_break; + }, "%W") + +del_proc = TkComm.install_cmd(proc{top_win.destroy; top_win = nil}) + +err_proc = TkComm.install_cmd(proc{fail(RuntimeError, + msgcat['Application Error'])}) + +show_sample = proc{|loc| + top_win = TkToplevel.new(:title=>loc) + + msgcat.locale = loc + #msgcat.load_rb(msgcat_dir) + msgcat.load(msgcat_dir) + + TkLabel.new(top_win){ + text "preferences:: #{msgcat.preferences.join(' ')}" + pack(:pady=>10, :padx=>10) + } + + lbl = TkLabel.new(top_win, :text=>msgcat["%1$s:: %2$s", + 'Color', '']).pack(:anchor=>'w') + + bg = TkFrame.new(top_win).pack(:ipadx=>20, :ipady=>10, + :expand=>true, :fill=>:both) + + TkFrame.new(bg){|f| + ['blue', 'green', 'red'].each{|col| + TkButton.new(f, :text=>msgcat[col]){ + bind('ButtonRelease-1', col_proc, "#{col} #{bg.path} #{lbl.path}") + }.pack(:fill=>:x) + } + }.pack(:anchor=>'center', :pady=>15) + + TkFrame.new(top_win){|f| + TkButton.new(f, :text=>msgcat['Delete'], + :command=>del_proc).pack(:side=>:right, :padx=>5) + TkButton.new(f, :text=>msgcat['Error'], + :command=>err_proc).pack(:side=>:left, :padx=>5) + }.pack(:side=>:bottom, :fill=>:x) + + top_win +} + + +# listbox for locale list +TkLabel.new(:text=>"Please click a locale.").pack(:padx=>5, :pady=>3) + +TkFrame.new{|f| + TkButton.new(f, :text=>msgcat['Exit'], + :command=>proc{exit}).pack(:side=>:right, :padx=>5) +}.pack(:side=>:bottom, :fill=>:x) + +f = TkFrame.new.pack(:side=>:top, :fill=>:both, :expand=>true) +lbox = TkListbox.new(f).pack(:side=>:left, :fill=>:both, :expand=>true) +lbox.yscrollbar(TkScrollbar.new(f, :width=>12).pack(:side=>:right, :fill=>:y)) + +lbox.bind('ButtonRelease-1'){|ev| + idx = lbox.index("@#{ev.x},#{ev.y}") + if idx == 0 + loc = default_locale + else + loc = lbox.get(idx) + end + if top_win != nil && top_win.exist? + top_win.destroy + end + top_win = show_sample.call(loc) +} + +lbox.insert('end', 'default') + +Dir.entries(msgcat_dir).sort.each{|f| + if f =~ /^(.*).msg$/ + lbox.insert('end', $1) + end +} + +top_win = show_sample.call(default_locale) + +# start eventloop +Tk.mainloop diff --git a/ext/tk/sample/tkmsgcat-load_tk.rb b/ext/tk/sample/tkmsgcat-load_tk.rb new file mode 100644 index 0000000000..8ad26a5f27 --- /dev/null +++ b/ext/tk/sample/tkmsgcat-load_tk.rb @@ -0,0 +1,118 @@ +#!/usr/bin/env ruby + +require 'tk' + +demo_dir = File.dirname($0) +msgcat_dir = [demo_dir, 'msgs_tk'].join(File::Separator) +top_win = nil +#msgcat = TkMsgCatalog.new('::tk') +msgcat = TkMsgCatalog.new('::tkmsgcat_demo') +default_locale = msgcat.locale +msgcat.load_tk(msgcat_dir) + +col_proc = TkComm.install_bind(proc{|w, color, frame, label| + TkComm.window(frame).background(color) + Tk.update + TkComm.window(label).text( + msgcat.mc("%1$s:: %2$s", 'Color', + color.capitalize)) + w.flash; w.flash + Tk.callback_break; + }, "%W") + +del_proc = TkComm.install_cmd(proc{top_win.destroy; top_win = nil}) + +err_proc = TkComm.install_cmd(proc{fail(RuntimeError, + msgcat.mc('Application Error'))}) + +show_sample = proc{|loc| + top_win = TkToplevel.new(:title=>loc) + + msgcat.locale = loc + msgcat.load_tk(msgcat_dir) + + TkLabel.new(top_win){ + text "preferences:: #{msgcat.preferences.join(' ')}" + pack(:pady=>10, :padx=>10) + } + + lbl = TkLabel.new(top_win, :text=>msgcat.mc("%1$s:: %2$s", + 'Color', '')).pack(:anchor=>'w') + + bg = TkFrame.new(top_win).pack(:ipadx=>20, :ipady=>10, + :expand=>true, :fill=>:both) + + TkFrame.new(bg){|f| + ['blue', 'green', 'red'].each{|col| + TkButton.new(f, :text=>msgcat.mc(col)){ + bind('ButtonRelease-1', col_proc, "#{col} #{bg.path} #{lbl.path}") + }.pack(:fill=>:x) +=begin + TkButton.new(f, :text=>msgcat.mc(col), + :command=>proc{ + bg.background col + lbl.text msgcat.mc("%1$s:: %2$s", 'Color', col.capitalize) + }).pack(:fill=>:x) +=end + } + }.pack(:anchor=>'center', :pady=>15) + + TkFrame.new(top_win){|f| + TkButton.new(f, :text=>msgcat.mc('Delete'), + :command=>del_proc).pack(:side=>:right, :padx=>5) + TkButton.new(f, :text=>msgcat.mc('Error'), + :command=>err_proc).pack(:side=>:left, :padx=>5) +=begin + TkButton.new(f, :text=>msgcat.mc('Delete'), + :command=>proc{ + top_win.destroy + top_win = nil + }).pack(:side=>:right, :padx=>5) + TkButton.new(f, :text=>msgcat.mc('Error'), + :command=>proc{ + fail RuntimeError, msgcat.mc('Application Error') + }).pack(:side=>:left, :padx=>5) +=end + }.pack(:side=>:bottom, :fill=>:x) + + top_win +} + + +# listbox for locale list +TkLabel.new(:text=>"Please click a locale.").pack(:padx=>5, :pady=>3) + +TkFrame.new{|f| + TkButton.new(f, :text=>msgcat.mc('Exit'), + :command=>proc{exit}).pack(:side=>:right, :padx=>5) +}.pack(:side=>:bottom, :fill=>:x) + +f = TkFrame.new.pack(:side=>:top, :fill=>:both, :expand=>true) +lbox = TkListbox.new(f).pack(:side=>:left, :fill=>:both, :expand=>true) +lbox.yscrollbar(TkScrollbar.new(f, :width=>12).pack(:side=>:right, :fill=>:y)) + +lbox.bind('ButtonRelease-1'){|ev| + idx = lbox.index("@#{ev.x},#{ev.y}") + if idx == 0 + loc = default_locale + else + loc = lbox.get(idx) + end + if top_win != nil && top_win.exist? + top_win.destroy + end + top_win = show_sample.call(loc) +} + +lbox.insert('end', 'default') + +Dir.entries(msgcat_dir).sort.each{|f| + if f =~ /^(.*).msg$/ + lbox.insert('end', $1) + end +} + +top_win = show_sample.call(default_locale) + +# start eventloop +Tk.mainloop diff --git a/ext/tk/sample/tkmultilistbox.rb b/ext/tk/sample/tkmultilistbox.rb index c3787a0cf0..257cf95c39 100644 --- a/ext/tk/sample/tkmultilistbox.rb +++ b/ext/tk/sample/tkmultilistbox.rb @@ -109,7 +109,9 @@ class TkMultiListbox < TkListbox @v_scroll.set first, last } } - @v_scroll.command proc{|*args| @lbox_list.each{|lbox| lbox.yview *args} } +# @v_scroll.command proc{|*args| @lbox_list.each{|lbox| lbox.yview *args} } + @v_scroll.command proc{|*args| p "";p [@lbox_list, args]; @lbox_list.each{|lbox| lbox.yview *args} } +# @v_scroll.command proc{|*args| p "";p [@lbox_list, args]; @lbox_list.each{|lbox| lbox.yview *args}; p [@lbox_list, args] } # binding for listboxes @mode = {} diff --git a/ext/tk/sample/tktextframe.rb b/ext/tk/sample/tktextframe.rb index 78efdf0970..5d16f2b0be 100644 --- a/ext/tk/sample/tktextframe.rb +++ b/ext/tk/sample/tktextframe.rb @@ -65,9 +65,9 @@ class TkTextFrame < TkText # vertical scrollbar : ON/OFF def vscroll(mode) st = TkGrid.info(@v_scroll) - if mode && st == [] then + if mode && st.size == 0 then @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns') - elsif !mode && st != [] then + elsif !mode && st.size != 0 then @v_scroll.ungrid end self @@ -76,10 +76,10 @@ class TkTextFrame < TkText # horizontal scrollbar : ON/OFF def hscroll(mode, wrap_mode="char") st = TkGrid.info(@h_scroll) - if mode && st == [] then + if mode && st.size == 0 then @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew') wrap 'none' # => self.wrap('none') - elsif !mode && st != [] then + elsif !mode && st.size != 0 then @h_scroll.ungrid wrap wrap_mode # => self.wrap(wrap_mode) end diff --git a/ext/tk/tkutil.c b/ext/tk/tkutil.c index b42069e234..cacc2622f0 100644 --- a/ext/tk/tkutil.c +++ b/ext/tk/tkutil.c @@ -1,6 +1,6 @@ /************************************************ - tk.c - + tkutil.c - $Author$ $Date$ @@ -9,17 +9,36 @@ ************************************************/ #include "ruby.h" +#include "st.h" -static VALUE -tk_eval_cmd(argc, argv) - int argc; - VALUE argv[]; -{ - VALUE cmd, rest; +static VALUE cMethod; - rb_scan_args(argc, argv, "1*", &cmd, &rest); - return rb_eval_cmd(cmd, rest, 0); -} +static VALUE cTclTkLib; + +static VALUE cTkObject; +static VALUE cTkCallbackEntry; + +static VALUE TK_None; + +static VALUE cCB_SUBST; +static VALUE cSUBST_INFO; + +static ID ID_split_tklist; +static ID ID_toUTF8; +static ID ID_fromUTF8; +static ID ID_path; +static ID ID_to_eval; +static ID ID_to_s; +static ID ID_install_cmd; +static ID ID_merge_tklist; +static ID ID_call; + +static ID ID_SUBST_INFO; + +static VALUE CALLBACK_TABLE; +static unsigned long CALLBACK_ID_NUM = 0; + +/*************************************/ static VALUE tk_s_new(argc, argv, klass) @@ -33,13 +52,1133 @@ tk_s_new(argc, argv, klass) return obj; } +/*************************************/ + +static VALUE +tkNone_to_s(self) + VALUE self; +{ + return rb_str_new2("None"); +} + +/*************************************/ + +static VALUE +tk_eval_cmd(argc, argv, self) + int argc; + VALUE argv[]; + VALUE self; +{ + volatile VALUE cmd, rest, arg; + volatile VALUE ret; + int status; + + rb_scan_args(argc, argv, "1*", &cmd, &rest); + return rb_eval_cmd(cmd, rest, 0); +} + +static VALUE +tk_do_callback(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ +#if 0 + volatile VALUE id; + volatile VALUE rest; + + rb_scan_args(argc, argv, "1*", &id, &rest); + return rb_apply(rb_hash_aref(CALLBACK_TABLE, id), ID_call, rest); +#endif + return rb_funcall2(rb_hash_aref(CALLBACK_TABLE, argv[0]), + ID_call, argc - 1, argv + 1); +} + +static char *cmd_id_head = "ruby_cmd TkUtil callback "; +static char *cmd_id_prefix = "cmd"; + +static VALUE +tk_install_cmd_core(cmd) + VALUE cmd; +{ + volatile VALUE id_num; + + id_num = ULONG2NUM(CALLBACK_ID_NUM++); + id_num = rb_funcall(id_num, ID_to_s, 0, 0); + id_num = rb_str_append(rb_str_new2(cmd_id_prefix), id_num); + rb_hash_aset(CALLBACK_TABLE, id_num, cmd); + return rb_str_append(rb_str_new2(cmd_id_head), id_num); +} + +static VALUE +tk_install_cmd(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + volatile VALUE cmd; + +#if 0 + if (rb_scan_args(argc, argv, "01", &cmd) == 0) { + cmd = rb_block_proc(); + } + return tk_install_cmd_core(cmd); +#endif + if (argc == 0) { + cmd = rb_block_proc(); + } else { + cmd = argv[0]; + } + return tk_install_cmd_core(cmd); +} + +static VALUE +tk_uninstall_cmd(self, cmd_id) + VALUE self; + VALUE cmd_id; +{ + int head_len = strlen(cmd_id_head); + int prefix_len = strlen(cmd_id_prefix); + + StringValue(cmd_id); + if (strncmp(cmd_id_head, RSTRING(cmd_id)->ptr, head_len) != 0) { + return Qnil; + } + if (strncmp(cmd_id_prefix, + RSTRING(cmd_id)->ptr + head_len, prefix_len) != 0) { + return Qnil; + } + + return rb_hash_delete(CALLBACK_TABLE, + rb_str_new2(RSTRING(cmd_id)->ptr + head_len)); +} + +static VALUE +tk_toUTF8(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + return rb_funcall2(cTclTkLib, ID_toUTF8, argc, argv); +} + +static VALUE +tk_fromUTF8(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + return rb_funcall2(cTclTkLib, ID_fromUTF8, argc, argv); +} + +static VALUE +fromDefaultEnc_toUTF8(str, self) + VALUE str; + VALUE self; +{ + VALUE argv[1]; + + argv[0] = str; + return tk_toUTF8(1, argv, self); +} + +static VALUE +fromUTF8_toDefaultEnc(str, self) + VALUE str; + VALUE self; +{ + VALUE argv[1]; + + argv[0] = str; + return tk_fromUTF8(1, argv, self); +} + + +static int +to_strkey(key, value, hash) + VALUE key; + VALUE value; + VALUE hash; +{ + if (key == Qundef) return ST_CONTINUE; + rb_hash_aset(hash, rb_funcall(key, ID_to_s, 0, 0), value); + return ST_CONTINUE; +} + +static VALUE +tk_symbolkey2str(self, keys) + VALUE self; + VALUE keys; +{ + volatile VALUE new_keys = rb_hash_new(); + + st_foreach(RHASH(keys)->tbl, to_strkey, new_keys); + return new_keys; +} + +static VALUE get_eval_string_core _((VALUE, VALUE, VALUE)); +static VALUE ary2list _((VALUE, VALUE)); +static VALUE hash2list _((VALUE, VALUE)); + +static VALUE +ary2list(ary, self) + VALUE ary; + VALUE self; +{ + int idx, size; + volatile VALUE val; + volatile VALUE dst; + + size = RARRAY(ary)->len; + dst = rb_ary_new2(size); + RARRAY(dst)->len = 0; + for(idx = 0; idx < size; idx++) { + val = RARRAY(ary)->ptr[idx]; + switch(TYPE(val)) { + case T_ARRAY: + RARRAY(dst)->ptr[RARRAY(dst)->len++] = ary2list(val, self); + break; + + case T_HASH: + RARRAY(dst)->ptr[RARRAY(dst)->len++] = hash2list(val, self); + break; + + default: + if (val != TK_None) { + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = get_eval_string_core(val, Qnil, self); + } + } + } + return rb_apply(cTclTkLib, ID_merge_tklist, dst); +} + +static VALUE +key2keyname(key) + VALUE key; +{ + return rb_str_append(rb_str_new2("-"), rb_funcall(key, ID_to_s, 0, 0)); +} + +static VALUE +assoc2kv(assoc, ary, self) + VALUE assoc; + VALUE ary; + VALUE self; +{ + int i, j, len; + volatile VALUE pair; + volatile VALUE val; + volatile VALUE dst = rb_ary_new2(2 * RARRAY(assoc)->len); + + len = RARRAY(assoc)->len; + + for(i = 0; i < len; i++) { + pair = RARRAY(assoc)->ptr[i]; + if (TYPE(pair) != T_ARRAY) { + RARRAY(dst)->ptr[RARRAY(dst)->len++] = key2keyname(pair); + continue; + } + switch(RARRAY(assoc)->len) { + case 2: + RARRAY(dst)->ptr[RARRAY(dst)->len++] = RARRAY(pair)->ptr[2]; + + case 1: + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = key2keyname(RARRAY(pair)->ptr[0]); + + case 0: + continue; + + default: + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = key2keyname(RARRAY(pair)->ptr[0]); + + val = rb_ary_new2(RARRAY(pair)->len - 1); + RARRAY(val)->len = 0; + for(j = 1; j < RARRAY(pair)->len; j++) { + RARRAY(val)->ptr[RARRAY(val)->len++] = RARRAY(pair)->ptr[j]; + } + + RARRAY(dst)->ptr[RARRAY(dst)->len++] = val; + } + } + + if (NIL_P(ary)) { + return dst; + } else { + return rb_ary_plus(ary, dst); + } +} + +static VALUE +assoc2kv_enc(assoc, ary, self) + VALUE assoc; + VALUE ary; + VALUE self; +{ + int i, j, len; + volatile VALUE pair; + volatile VALUE val; + volatile VALUE dst = rb_ary_new2(2 * RARRAY(assoc)->len); + + len = RARRAY(assoc)->len; + + for(i = 0; i < len; i++) { + pair = RARRAY(assoc)->ptr[i]; + if (TYPE(pair) != T_ARRAY) { + RARRAY(dst)->ptr[RARRAY(dst)->len++] = key2keyname(pair); + continue; + } + switch(RARRAY(assoc)->len) { + case 2: + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = get_eval_string_core(RARRAY(pair)->ptr[2], Qtrue, self); + + case 1: + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = key2keyname(RARRAY(pair)->ptr[0]); + + case 0: + continue; + + default: + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = key2keyname(RARRAY(pair)->ptr[0]); + + val = rb_ary_new2(RARRAY(pair)->len - 1); + RARRAY(val)->len = 0; + for(j = 1; j < RARRAY(pair)->len; j++) { + RARRAY(val)->ptr[RARRAY(val)->len++] = RARRAY(pair)->ptr[j]; + } + + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = get_eval_string_core(val, Qtrue, self); + } + } + + if (NIL_P(ary)) { + return dst; + } else { + return rb_ary_plus(ary, dst); + } +} + +static int +push_kv(key, val, ary) + VALUE key; + VALUE val; + VALUE ary; +{ + if (key == Qundef) return ST_CONTINUE; +#if 0 + rb_ary_push(ary, key2keyname(key)); + if (val != TK_None) rb_ary_push(ary, val); +#endif + RARRAY(ary)->ptr[RARRAY(ary)->len++] = key2keyname(key); + if (val != TK_None) RARRAY(ary)->ptr[RARRAY(ary)->len++] = val; + + return ST_CONTINUE; +} + +static VALUE +hash2kv(hash, ary, self) + VALUE hash; + VALUE ary; + VALUE self; +{ + volatile VALUE dst = rb_ary_new2(2 * RHASH(hash)->tbl->num_entries); + + RARRAY(dst)->len = 0; + + st_foreach(RHASH(hash)->tbl, push_kv, dst); + + if (NIL_P(ary)) { + return dst; + } else { + return rb_ary_plus(ary, dst); + } +} + +static int +push_kv_enc(key, val, args) + VALUE key; + VALUE val; + VALUE args; +{ + volatile VALUE ary = RARRAY(args)->ptr[0]; + + if (key == Qundef) return ST_CONTINUE; +#if 0 + rb_ary_push(ary, key2keyname(key)); + if (val != TK_None) { + rb_ary_push(ary, get_eval_string_core(val, Qtrue, + RARRAY(args)->ptr[1])); + } +#endif + RARRAY(ary)->ptr[RARRAY(ary)->len++] = key2keyname(key); + + if (val == TK_None) return ST_CONTINUE; + + RARRAY(ary)->ptr[RARRAY(ary)->len++] + = get_eval_string_core(val, Qtrue, RARRAY(args)->ptr[1]); + + return ST_CONTINUE; +} + +static VALUE +hash2kv_enc(hash, ary, self) + VALUE hash; + VALUE ary; + VALUE self; +{ + volatile VALUE args = rb_ary_new2(2); + volatile VALUE dst = rb_ary_new2(2 * RHASH(hash)->tbl->num_entries); + + RARRAY(dst)->len = 0; + + RARRAY(args)->ptr[0] = dst; + RARRAY(args)->ptr[1] = self; + RARRAY(args)->len = 2; + st_foreach(RHASH(hash)->tbl, push_kv_enc, args); + + if (NIL_P(ary)) { + return dst; + } else { + return rb_ary_plus(ary, dst); + } +} + +static VALUE +hash2list(hash, self) + VALUE hash; + VALUE self; +{ + return ary2list(hash2kv(hash, Qnil, self), self); +} + + +static VALUE +hash2list_enc(hash, self) + VALUE hash; + VALUE self; +{ + return ary2list(hash2kv_enc(hash, Qnil, self), self); +} + +static VALUE +tk_hash_kv(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + volatile VALUE hash, enc_flag, ary; + + ary = Qnil; + enc_flag = Qnil; + switch(argc) { + case 3: + ary = argv[2]; + case 2: + enc_flag = argv[1]; + case 1: + hash = argv[0]; + break; + case 0: + rb_raise(rb_eArgError, "too few arguments"); + default: /* >= 3 */ + rb_raise(rb_eArgError, "too many arguments"); + } + + switch(TYPE(hash)) { + case T_ARRAY: + if (RTEST(enc_flag)) { + return assoc2kv_enc(hash, ary, self); + } else { + return assoc2kv(hash, ary, self); + } + + case T_HASH: + if (RTEST(enc_flag)) { + return hash2kv_enc(hash, ary, self); + } else { + return hash2kv(hash, ary, self); + } + + case T_NIL: + if (NIL_P(ary)) { + return rb_ary_new(); + } else { + return ary; + } + + default: + if (hash == TK_None) { + if (NIL_P(ary)) { + return rb_ary_new(); + } else { + return ary; + } + } + rb_raise(rb_eArgError, "Hash is expected for 1st argument"); + } +} + +static VALUE +get_eval_string_core(obj, enc_flag, self) + VALUE obj; + VALUE enc_flag; + VALUE self; +{ + switch(TYPE(obj)) { + case T_FLOAT: + case T_FIXNUM: + case T_BIGNUM: + return rb_funcall(obj, ID_to_s, 0, 0); + + case T_STRING: + if (RTEST(enc_flag)) { + if (rb_respond_to(self, ID_toUTF8)) { + return rb_funcall(self, ID_toUTF8, 1, obj); + } else { + return fromDefaultEnc_toUTF8(obj, self); + } + } else { + return obj; + } + + case T_SYMBOL: + if (RTEST(enc_flag)) { + if (rb_respond_to(self, ID_toUTF8)) { + return rb_funcall(self, ID_toUTF8, 1, + rb_str_new2(rb_id2name(SYM2ID(obj)))); + } else { + return fromDefaultEnc_toUTF8(rb_str_new2(rb_id2name(SYM2ID(obj))), self); + } + } else { + return rb_str_new2(rb_id2name(SYM2ID(obj))); + } + + case T_HASH: + if (RTEST(enc_flag)) { + return hash2list_enc(obj, self); + } else { + return hash2list(obj, self); + } + + case T_ARRAY: + if (RTEST(enc_flag)) { + return fromDefaultEnc_toUTF8(ary2list(obj, self), self); + } else { + return ary2list(obj, self); + } + + case T_FALSE: + return rb_str_new2("0"); + + case T_TRUE: + return rb_str_new2("1"); + + case T_NIL: + return rb_str_new2(""); + + default: + if (rb_obj_is_kind_of(obj, cTkObject)) { + /* return rb_str_new3(rb_funcall(obj, ID_path, 0, 0)); */ + return get_eval_string_core(rb_funcall(obj, ID_path, 0, 0), + enc_flag, self); + } + + if (rb_obj_is_kind_of(obj, rb_cProc) + || rb_obj_is_kind_of(obj, cMethod) + || rb_obj_is_kind_of(obj, cTkCallbackEntry)) { + if (rb_respond_to(self, ID_install_cmd)) { + return rb_funcall(self, ID_install_cmd, 1, obj); + } else { + return tk_install_cmd(obj); + } + } + + if (obj == TK_None) return Qnil; + + if (rb_respond_to(obj, ID_to_eval)) { + /* return rb_funcall(obj, ID_to_eval, 0, 0); */ + return get_eval_string_core(rb_funcall(obj, ID_to_eval, 0, 0), + enc_flag, self); + } else if (rb_respond_to(obj, ID_path)) { + /* return rb_funcall(obj, ID_path, 0, 0); */ + return get_eval_string_core(rb_funcall(obj, ID_path, 0, 0), + enc_flag, self); + } else if (rb_respond_to(obj, ID_to_s)) { + return rb_funcall(obj, ID_to_s, 0, 0); + } + } + + rb_warning("fail to convert '%s' to string for Tk", + RSTRING(rb_funcall(obj, rb_intern("inspect"), 0, 0))->ptr); + + return obj; +} + +static VALUE +tk_get_eval_string(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + volatile VALUE obj, enc_flag; + + if (rb_scan_args(argc, argv, "11", &obj, &enc_flag) == 1) { + enc_flag = Qnil; + } + + return get_eval_string_core(obj, enc_flag, self); +} + +static VALUE +tk_get_eval_enc_str(self, obj) + VALUE self; + VALUE obj; +{ + if (obj == TK_None) { + return obj; + } else { + return get_eval_string_core(obj, Qtrue, self); + } +} + +static VALUE +tk_conv_args(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + int idx; + volatile VALUE dst; + volatile VALUE head, enc_flag, rest; + + if (argc < 2) { + rb_raise(rb_eArgError, "too few arguments"); + } + dst = rb_ary_new2(argc - 2); + RARRAY(dst)->len = 0; + for(idx = 2; idx < argc; idx++) { + if (argv[idx] != TK_None) { + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = get_eval_string_core(argv[idx], argv[1], self); + } + } + + return rb_ary_plus(argv[0], dst); +} + + +/*************************************/ + +static VALUE +tcl2rb_bool(self, value) + VALUE self; + VALUE value; +{ + if (TYPE(value) == T_FIXNUM) { + if (NUM2INT(value) == 0) { + return Qfalse; + } else { + return Qtrue; + } + } + + rb_check_type(value, T_STRING); + + if (RSTRING(value)->ptr[0] == '\0' + || strcmp(RSTRING(value)->ptr, "0") == 0 + || strcmp(RSTRING(value)->ptr, "no") == 0 + || strcmp(RSTRING(value)->ptr, "false") == 0) { + return Qfalse; + } else { + return Qtrue; + } +} + +static VALUE +tkstr_to_dec(value) + VALUE value; +{ + return rb_cstr_to_inum(RSTRING(value)->ptr, 10, 1); +} + +static VALUE +tkstr_to_int(value) + VALUE value; +{ + return rb_cstr_to_inum(RSTRING(value)->ptr, 0, 1); +} + +static VALUE +tkstr_to_float(value) + VALUE value; +{ + return rb_float_new(rb_cstr_to_dbl(RSTRING(value)->ptr, 1)); +} + +static VALUE +tkstr_invalid_numstr(value) + VALUE value; +{ + rb_raise(rb_eArgError, + "invalid value for Number: '%s'", RSTRING(value)->ptr); + return Qnil; /*dummy*/ +} + +static VALUE +tkstr_rescue_float(value) + VALUE value; +{ + return rb_rescue2(tkstr_to_float, value, + tkstr_invalid_numstr, value, + rb_eArgError, 0); +} + +static VALUE +tkstr_to_number(value) + VALUE value; +{ + rb_check_type(value, T_STRING); + + return rb_rescue2(tkstr_to_int, value, + tkstr_rescue_float, value, + rb_eArgError, 0); +} + +static VALUE +tcl2rb_number(self, value) + VALUE self; + VALUE value; +{ + return tkstr_to_number(value); +} + +static VALUE +tkstr_to_str(value) + VALUE value; +{ + char * ptr; + int len; + + ptr = RSTRING(value)->ptr; + len = RSTRING(value)->len; + + if (len > 1 && *ptr == '{' && *(ptr + len - 1) == '}') { + return rb_str_new(ptr + 1, len - 2); + } + return value; +} + +static VALUE +tcl2rb_string(self, value) + VALUE self; + VALUE value; +{ + rb_check_type(value, T_STRING); + + return tkstr_to_str(value); +} + +static VALUE +tcl2rb_num_or_str(self, value) + VALUE self; + VALUE value; +{ + rb_check_type(value, T_STRING); + + return rb_rescue2(tkstr_to_number, value, + tkstr_to_str, value, + rb_eArgError, 0); +} + + +/*************************************/ + +struct cbsubst_info { + int size; + char *key; + char *type; + ID *ivar; + VALUE proc; +}; + +static void +subst_mark(ptr) + struct cbsubst_info *ptr; +{ + rb_gc_mark(ptr->proc); +} + +static void +subst_free(ptr) + struct cbsubst_info *ptr; +{ + if (ptr) { + if (ptr->key != (char*)NULL) free(ptr->key); + if (ptr->type != (char*)NULL) free(ptr->type); + if (ptr->ivar != (ID*)NULL) free(ptr->ivar); + free(ptr); + } +} + +static void +cbsubst_init() +{ + struct cbsubst_info *inf; + ID *ivar; + volatile VALUE proc; + + inf = ALLOC(struct cbsubst_info); + + inf->size = 0; + + inf->key = ALLOC_N(char, 1); + inf->key = ALLOC_N(char, 1); + inf->key[0] = '\0'; + + inf->type = ALLOC_N(char, 1); + inf->type[0] = '\0'; + + ivar = ALLOC_N(ID, 1); + inf->ivar = ivar; + + proc = rb_hash_new(); + inf->proc = proc; + + rb_const_set(cCB_SUBST, ID_SUBST_INFO, + Data_Wrap_Struct(cSUBST_INFO, subst_mark, subst_free, inf)); +} + +static VALUE +cbsubst_initialize(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; +{ + struct cbsubst_info *inf; + volatile VALUE proc; + int idx; + + Data_Get_Struct(rb_const_get(rb_obj_class(self), ID_SUBST_INFO), + struct cbsubst_info, inf); + + for(idx = 0; idx < argc; idx++) { + rb_ivar_set(self, inf->ivar[idx], argv[idx]); + } + + return self; +} + +static VALUE +cbsubst_get_subst_key(self, str) + VALUE self; + VALUE str; +{ + volatile VALUE list; + volatile VALUE ret; + int i, len; + char *buf, *ptr; + + list = rb_funcall(cTclTkLib, ID_split_tklist, 1, str); + + len = RARRAY(list)->len; + buf = ALLOC_N(char, len + 1); + + for(i = 0; i < len; i++) { + ptr = RSTRING(RARRAY(list)->ptr[i])->ptr; + if (*ptr == '%' && *(ptr + 2) == '\0') { + *(buf + i) = *(ptr + 1); + } else { + *(buf + i) = ' '; + } + } + *(buf + len) = '\0'; + + ret = rb_str_new2(buf); + free(buf); + return ret; +} + +static VALUE +cbsubst_get_all_subst_keys(self) + VALUE self; +{ + struct cbsubst_info *inf; + char *buf, *ptr; + int i, len; + volatile VALUE ret; + + Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), + struct cbsubst_info, inf); + + len = strlen(inf->key); + buf = ALLOC_N(char, 3*len); + ptr = buf; + for(i = 0; i < len; i++) { + *(ptr++) = '%'; + *(ptr++) = *(inf->key + i); + *(ptr++) = ' '; + } + *(buf + 3*len) = '\0'; + + ret = rb_ary_new3(2, rb_str_new2(inf->key), rb_str_new2(buf)); + + free(buf); + + return ret; +} + +static VALUE +cbsubst_table_setup(self, key_inf, proc_inf) + VALUE self; + VALUE key_inf; + VALUE proc_inf; +{ + struct cbsubst_info *subst_inf; + int idx; + int len = RARRAY(key_inf)->len; + char *key = ALLOC_N(char, len + 1); + char *type = ALLOC_N(char, len + 1); + ID *ivar = ALLOC_N(ID, len + 1); + volatile VALUE proc = rb_hash_new(); + volatile VALUE inf; + + /* init */ + subst_inf = ALLOC(struct cbsubst_info); + subst_inf->size = len; + subst_inf->key = key; + subst_inf->type = type; + subst_inf->ivar = ivar; + subst_inf->proc = proc; + + /* + * keys : array of [subst, type, ivar] + * subst ==> char code + * type ==> char code + * ivar ==> symbol + */ + for(idx = 0; idx < len; idx++) { + inf = RARRAY(key_inf)->ptr[idx]; + if (TYPE(inf) != T_ARRAY) continue; + *(key + idx) = (char)NUM2INT(RARRAY(inf)->ptr[0]); + *(type + idx) = (char)NUM2INT(RARRAY(inf)->ptr[1]); + + *(ivar + idx) + = rb_intern( + RSTRING( + rb_str_cat2(rb_str_new2("@"), + rb_id2name(SYM2ID(RARRAY(inf)->ptr[2]))) + )->ptr + ); + + rb_attr(self, SYM2ID(RARRAY(inf)->ptr[2]), 1, 0, Qtrue); + } + *(key + len) = '\0'; + *(type + len) = '\0'; + + /* + * procs : array of [type, proc] + * type ==> char code + * proc ==> proc/method/obj (must respond to 'call') + */ + len = RARRAY(proc_inf)->len; + for(idx = 0; idx < len; idx++) { + inf = RARRAY(proc_inf)->ptr[idx]; + if (TYPE(inf) != T_ARRAY) continue; + rb_hash_aset(proc, RARRAY(inf)->ptr[0], RARRAY(inf)->ptr[1]); + } + + rb_const_set(self, ID_SUBST_INFO, + Data_Wrap_Struct(cSUBST_INFO, subst_mark, + subst_free, subst_inf)); + + return self; +} + +static VALUE +cbsubst_scan_args(self, arg_key, val_ary) + VALUE self; + VALUE arg_key; + VALUE val_ary; +{ + struct cbsubst_info *inf; + int idx; + int len = RARRAY(val_ary)->len; + char c; + char *ptr; + volatile VALUE dst = rb_ary_new2(len); + volatile VALUE proc; + + Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), + struct cbsubst_info, inf); + + RARRAY(dst)->len = 0; + for(idx = 0; idx < len; idx++) { + if (idx >= RSTRING(arg_key)->len) { + proc = Qnil; + } else if (*(RSTRING(arg_key)->ptr + idx) == ' ') { + proc = Qnil; + } else { + ptr = strchr(inf->key, *(RSTRING(arg_key)->ptr + idx)); + if (ptr == (char*)NULL) { + proc = Qnil; + } else { + c = *(inf->type + (ptr - inf->key)); + proc = rb_hash_aref(inf->proc, INT2FIX(c)); + } + } + + if (NIL_P(proc)) { + RARRAY(dst)->ptr[RARRAY(dst)->len++] = RARRAY(val_ary)->ptr[idx]; + } else { + RARRAY(dst)->ptr[RARRAY(dst)->len++] + = rb_funcall(proc, ID_call, 1, RARRAY(val_ary)->ptr[idx]); + } + } + + return dst; +} + +static VALUE +cbsubst_inspect(self) + VALUE self; +{ + return rb_str_new2("CallbackSubst"); +} + +static VALUE +substinfo_inspect(self) + VALUE self; +{ + return rb_str_new2("SubstInfo"); +} + +/*************************************/ + +static VALUE +tk_cbe_inspect(self) + VALUE self; +{ + return rb_str_new2("TkCallbackEntry"); +} + +/*************************************/ + +static VALUE +tkobj_path(self) + VALUE self; +{ + return rb_ivar_get(self, ID_path); +} + +/*************************************/ + void Init_tkutil() { - VALUE mTK = rb_define_module("TkUtil"); + volatile VALUE tmp; + VALUE cTK = rb_define_class("TkKernel", rb_cObject); + VALUE mTK = rb_define_module("TkUtil"); - rb_define_singleton_method(mTK, "eval_cmd", tk_eval_cmd, -1); + /* --------------------- */ + rb_global_variable(&cMethod); + cMethod = rb_const_get(rb_cObject, rb_intern("Method")); + ID_path = rb_intern("path"); + ID_to_eval = rb_intern("to_eval"); + ID_to_s = rb_intern("to_s"); + ID_install_cmd = rb_intern("install_cmd"); + ID_merge_tklist = rb_intern("_merge_tklist"); + ID_call = rb_intern("call"); + + /* --------------------- */ + cCB_SUBST = rb_define_class_under(mTK, "CallbackSubst", rb_cObject); + rb_define_singleton_method(cCB_SUBST, "inspect", cbsubst_inspect, 0); + + cSUBST_INFO = rb_define_class_under(cCB_SUBST, "Info", rb_cObject); + rb_define_singleton_method(cSUBST_INFO, "inspect", substinfo_inspect, 0); + + ID_SUBST_INFO = rb_intern("SUBST_INFO"); + rb_define_singleton_method(cCB_SUBST, "scan_args", cbsubst_scan_args, 2); + rb_define_singleton_method(cCB_SUBST, "_get_subst_key", + cbsubst_get_subst_key, 1); + rb_define_singleton_method(cCB_SUBST, "_get_all_subst_keys", + cbsubst_get_all_subst_keys, 0); + rb_define_singleton_method(cCB_SUBST, "_setup_subst_table", + cbsubst_table_setup, 2); + + rb_define_method(cCB_SUBST, "initialize", cbsubst_initialize, -1); + + cbsubst_init(); + + /* --------------------- */ + rb_global_variable(&cTkCallbackEntry); + cTkCallbackEntry = rb_define_class("TkCallbackEntry", cTK); + rb_define_singleton_method(cTkCallbackEntry, "inspect", tk_cbe_inspect, 0); + + /* --------------------- */ + rb_global_variable(&cTkObject); + cTkObject = rb_define_class("TkObject", cTK); + rb_define_method(cTkObject, "path", tkobj_path, 0); + + /* --------------------- */ + rb_require("tcltklib"); + rb_global_variable(&cTclTkLib); + cTclTkLib = rb_const_get(rb_cObject, rb_intern("TclTkLib")); + ID_split_tklist = rb_intern("_split_tklist"); + ID_toUTF8 = rb_intern("_toUTF8"); + ID_fromUTF8 = rb_intern("_fromUTF8"); + + /* --------------------- */ rb_define_singleton_method(cTK, "new", tk_s_new, -1); + + /* --------------------- */ + rb_global_variable(&TK_None); + TK_None = rb_obj_alloc(rb_cObject); + rb_define_const(mTK, "None", TK_None); + rb_define_singleton_method(TK_None, "to_s", tkNone_to_s, 0); + rb_define_singleton_method(TK_None, "inspect", tkNone_to_s, 0); + OBJ_FREEZE(TK_None); + + /* --------------------- */ + rb_global_variable(&CALLBACK_TABLE); + CALLBACK_TABLE = rb_hash_new(); + + /* --------------------- */ + rb_define_singleton_method(mTK, "eval_cmd", tk_eval_cmd, -1); + rb_define_singleton_method(mTK, "callback", tk_do_callback, -1); + rb_define_singleton_method(mTK, "install_cmd", tk_install_cmd, -1); + rb_define_singleton_method(mTK, "uninstall_cmd", tk_uninstall_cmd, 1); + rb_define_singleton_method(mTK, "_symbolkey2str", tk_symbolkey2str, 1); + rb_define_singleton_method(mTK, "hash_kv", tk_hash_kv, -1); + rb_define_singleton_method(mTK, "_get_eval_string", + tk_get_eval_string, -1); + rb_define_singleton_method(mTK, "_get_eval_enc_str", + tk_get_eval_enc_str, 1); + + rb_define_singleton_method(mTK, "bool", tcl2rb_bool, 1); + rb_define_singleton_method(mTK, "number", tcl2rb_number, 1); + rb_define_singleton_method(mTK, "string", tcl2rb_string, 1); + rb_define_singleton_method(mTK, "num_or_str", tcl2rb_num_or_str, 1); + + rb_define_method(mTK, "_toUTF8", tk_toUTF8, -1); + rb_define_method(mTK, "_fromUTF8", tk_fromUTF8, -1); + rb_define_method(mTK, "_symbolkey2str", tk_symbolkey2str, 1); + rb_define_method(mTK, "hash_kv", tk_hash_kv, -1); + rb_define_method(mTK, "_get_eval_string", tk_get_eval_string, -1); + rb_define_method(mTK, "_get_eval_enc_str", tk_get_eval_enc_str, 1); + rb_define_method(mTK, "_conv_args", tk_conv_args, -1); + + rb_define_method(mTK, "bool", tcl2rb_bool, 1); + rb_define_method(mTK, "number", tcl2rb_number, 1); + rb_define_method(mTK, "string", tcl2rb_string, 1); + rb_define_method(mTK, "num_or_str", tcl2rb_num_or_str, 1); + + /* --------------------- */ }