diff options
Diffstat (limited to 'ruby_1_8_6/ext/tk/lib')
322 files changed, 53890 insertions, 0 deletions
diff --git a/ruby_1_8_6/ext/tk/lib/README b/ruby_1_8_6/ext/tk/lib/README new file mode 100644 index 0000000000..5918fe4bf0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/README @@ -0,0 +1,30 @@ +README this file +multi-tk.rb multiple Tk interpreter (included safe-Tk) support +remotei-tk.rb control remote Tk interpreter on the other process support +tk.rb Tk interface + +tk/ library files construct Ruby/Tk + +tkextlib/ non-standard Tcl/Tk extension support libraries + +********************************************************************* +*** The followings exists for backward compatibility only. +*** The only thing which they work is that requires current +*** library files ( tk/*.rb ). +********************************************************************* +tkafter.rb handles Tcl after +tkbgerror.rb Tk error module +tkcanvas.rb Tk canvas interface +tkclass.rb provides generic names for Tk classes +tkconsole.rb console command support +tkdialog.rb Tk dialog class +tkentry.rb Tk entry class +tkfont.rb Tk font support +tkmacpkg.rb Mac resource support +tkmenubar.rb TK menubar utility +tkmngfocus.rb focus manager +tkpalette.rb pallete support +tkscrollbox.rb scroll box, also example of compound widget +tktext.rb text classes +tkvirtevent.rb virtual event support +tkwinpkg.rb Win DDE and registry support diff --git a/ruby_1_8_6/ext/tk/lib/multi-tk.rb b/ruby_1_8_6/ext/tk/lib/multi-tk.rb new file mode 100644 index 0000000000..78ed1aa6ee --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/multi-tk.rb @@ -0,0 +1,3233 @@ +# +# multi-tk.rb - supports multi Tk interpreters +# by Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> + +require 'tcltklib' +require 'tkutil' +require 'thread' + +if defined? Tk + fail RuntimeError,"'multi-tk' library must be required before requiring 'tk'" +end + +################################################ +# ignore exception on the mainloop? + +TclTkLib.mainloop_abort_on_exception = true +# TclTkLib.mainloop_abort_on_exception = false +# TclTkLib.mainloop_abort_on_exception = nil + + +################################################ +# add ThreadGroup check to TclTkIp.new +class << TclTkIp + alias __new__ new + private :__new__ + + def new(*args) + if Thread.current.group != ThreadGroup::Default + raise SecurityError, 'only ThreadGroup::Default can call TclTkIp.new' + end + __new__(*args) + end +end + + +################################################ +# use pseudo-toplevel feature of MultiTkIp ? +if (!defined?(Use_PseudoToplevel_Feature_of_MultiTkIp) || + Use_PseudoToplevel_Feature_of_MultiTkIp) + module MultiTkIp_PseudoToplevel_Evaluable + #def pseudo_toplevel_eval(body = Proc.new) + # Thread.current[:TOPLEVEL] = self + # begin + # body.call + # ensure + # Thread.current[:TOPLEVEL] = nil + # end + #end + + def pseudo_toplevel_evaluable? + @pseudo_toplevel_evaluable + end + + def pseudo_toplevel_evaluable=(mode) + @pseudo_toplevel_evaluable = (mode)? true: false + end + + def self.extended(mod) + mod.__send__(:extend_object, mod) + mod.instance_variable_set('@pseudo_toplevel_evaluable', true) + end + end + + class Object + alias __method_missing_alias_for_MultiTkIp__ method_missing + private :__method_missing_alias_for_MultiTkIp__ + + def method_missing(id, *args) + begin + has_top = (top = MultiTkIp.__getip.__pseudo_toplevel) && + top.respond_to?(:pseudo_toplevel_evaluable?) && + top.pseudo_toplevel_evaluable? && + top.respond_to?(id) + rescue Exception => e + has_top = false + end + + if has_top + top.__send__(id, *args) + else + __method_missing_alias_for_MultiTkIp__(id, *args) + end + end + end +else + # dummy + module MultiTkIp_PseudoToplevel_Evaluable + def pseudo_toplevel_evaluable? + false + end + end +end + +################################################ +# exceptiopn to treat the return value from IP +class MultiTkIp_OK < Exception + def self.send(thread, ret=nil) + thread.raise self.new(ret) + end + + def initialize(ret=nil) + super('succeed') + @return_value = ret + end + + attr_reader :return_value + alias value return_value +end +MultiTkIp_OK.freeze + + +################################################ +# methods for construction +class MultiTkIp + BASE_DIR = File.dirname(__FILE__) + + @@SLAVE_IP_ID = ['slave'.freeze, '0'.taint].freeze + + @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE) + + @@INIT_IP_ENV = [].taint unless defined?(@@INIT_IP_ENV) # table of Procs + @@ADD_TK_PROCS = [].taint unless defined?(@@ADD_TK_PROCS) # table of [name, args, body] + + @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST) + + unless defined?(@@TK_CMD_TBL) + @@TK_CMD_TBL = Object.new.taint + + @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint) + + class << @@TK_CMD_TBL + allow = [ + '__send__', '__id__', 'freeze', 'inspect', 'kind_of?', + '[]', '[]=', 'delete', 'each', 'has_key?' + ] + instance_methods.each{|m| undef_method(m) unless allow.index(m)} + + def kind_of?(klass) + @tbl.kind_of?(klass) + end + + def inspect + if Thread.current.group == ThreadGroup::Default + @tbl.inspect + else + ip = MultiTkIp.__getip + @tbl.reject{|idx, ent| ent.respond_to?(:ip) && ent.ip != ip}.inspect + end + end + + def [](idx) + return unless (ent = @tbl[idx]) + if Thread.current.group == ThreadGroup::Default + ent + elsif ent.respond_to?(:ip) + (ent.ip == MultiTkIp.__getip)? ent: nil + else + ent + end + end + + def []=(idx,val) + if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default + fail SecurityError,"cannot change the entried command" + end + @tbl[idx] = val + end + + def delete(idx, &blk) + # if gets an entry, is permited to delete + if self[idx] + @tbl.delete(idx) + elsif blk + blk.call(idx) + else + nil + end + end + + def each(&blk) + if Thread.current.group == ThreadGroup::Default + @tbl.each(&blk) + else + ip = MultiTkIp.__getip + @tbl.each{|idx, ent| + blk.call(idx, ent) unless ent.respond_to?(:ip) && ent.ip != ip + } + end + self + end + + def has_key?(k) + @tbl.has_key?(k) + end + alias include? has_key? + alias key? has_key? + alias member? has_key? + end + + @@TK_CMD_TBL.freeze + end + + ###################################### + + @@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){ + def initialize(ip, cmd) + @ip = ip + @cmd = cmd + freeze + end + attr_reader :ip, :cmd + def inspect + cmd.inspect + end + def call(*args) + unless @ip.deleted? + current = Thread.current + backup_ip = current['callback_ip'] + current['callback_ip'] = @ip + begin + ret = @ip.cb_eval(@cmd, *args) + fail ret if ret.kind_of?(Exception) + ret + rescue TkCallbackBreak, TkCallbackContinue => e + fail e + rescue SecurityError => e + # in 'exit', 'exit!', and 'abort' : security error --> delete IP + if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/ + @ip.delete + elsif @ip.safe? + if @ip.respond_to?(:cb_error) + @ip.cb_error(e) + else + nil # ignore + end + else + fail e + end + rescue Exception => e + fail e if e.message =~ /^TkCallback/ + + if @ip.safe? + if @ip.respond_to?(:cb_error) + @ip.cb_error(e) + else + nil # ignore + end + else + fail e + end + ensure + current['callback_ip'] = backup_ip + end + end + end + }.freeze + + ###################################### + + 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 + + def _check_and_return(thread, exception, wait=0) + unless thread + unless exception.kind_of?(MultiTkIp_OK) + msg = "#{exception.class}: #{exception.message}" + + if @interp.deleted? + warn("Warning (#{self}): " + msg) + return nil + end + + if safe? + warn("Warning (#{self}): " + msg) if $DEBUG + return nil + end + + begin + @interp._eval_without_enc(@interp._merge_tklist('bgerror', msg)) + rescue Exception => e + warn("Warning (#{self}): " + msg) + end + end + return nil + end + + if wait == 0 + # no wait + Thread.pass + if thread.stop? + thread.raise exception + end + return thread + end + + # wait to stop the caller thread + wait.times{ + if thread.stop? + # ready to send exception + thread.raise exception + return thread + end + + # wait + Thread.pass + } + + # unexpected error + thread.raise RuntimeError, "the thread may not wait for the return value" + return thread + end + + ###################################### + + def set_cb_error(cmd = Proc.new) + @cb_error_proc[0] = cmd + end + + def cb_error(e) + if @cb_error_proc[0].respond_to?(:call) + @cb_error_proc[0].call(e) + end + end + + ###################################### + + def set_safe_level(safe) + if safe > @safe_level[0] + @safe_level[0] = safe + @cmd_queue.enq([@system, 'set_safe_level', safe]) + end + @safe_level[0] + end + def safe_level=(safe) + set_safe_level(safe) + end + def self.set_safe_level(safe) + __getip.set_safe_level(safe) + end + def self.safe_level=(safe) + self.set_safe_level(safe) + end + def safe_level + @safe_level[0] + end + def self.safe_level + __getip.safe_level + end + + def wait_on_mainloop? + @wait_on_mainloop[0] + end + def wait_on_mainloop=(bool) + @wait_on_mainloop[0] = bool + end + + def running_mainloop? + @wait_on_mainloop[1] > 0 + end + + def _destroy_slaves_of_slaveIP(ip) + unless ip.deleted? + # ip._split_tklist(ip._invoke('interp', 'slaves')).each{|name| + ip._split_tklist(ip._invoke_without_enc('interp', 'slaves')).each{|name| + name = _fromUTF8(name) + begin + # ip._eval_without_enc("#{name} eval {foreach i [after info] {after cancel $i}}") + after_ids = ip._eval_without_enc("#{name} eval {after info}") + ip._eval_without_enc("#{name} eval {foreach i {#{after_ids}} {after cancel $i}}") + rescue Exception + end + begin + # ip._invoke('interp', 'eval', name, 'destroy', '.') + ip._invoke(name, 'eval', 'destroy', '.') + rescue Exception + end + + # safe_base? + if ip._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0' + begin + ip._eval_without_enc("::safe::interpDelete #{name}") + rescue Exception + end + end +=begin + if ip._invoke('interp', 'exists', name) == '1' + begin + ip._invoke(name, 'eval', 'exit') + rescue Exception + end + end +=end + unless ip.deleted? + if ip._invoke('interp', 'exists', name) == '1' + begin + ip._invoke('interp', 'delete', name) + rescue Exception + end + end + end + } + end + end + + def _receiver_eval_proc_core(safe_level, thread, cmd, *args) + begin + #ret = proc{$SAFE = safe_level; cmd.call(*args)}.call + #ret = cmd.call(safe_level, *args) + normal_ret = false + ret = catch(:IRB_EXIT) do # IRB hack + retval = cmd.call(safe_level, *args) + normal_ret = true + retval + end + unless normal_ret + # catch IRB_EXIT + exit(ret) + end + ret + rescue SystemExit => e + # delete IP + unless @interp.deleted? + @slave_ip_tbl.each{|name, subip| + _destroy_slaves_of_slaveIP(subip) + begin + # subip._eval_without_enc("foreach i [after info] {after cancel $i}") + after_ids = subip._eval_without_enc("after info") + subip._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}") + rescue Exception + end +=begin + begin + subip._invoke('destroy', '.') unless subip.deleted? + rescue Exception + end +=end + # safe_base? + if @interp._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0' + begin + @interp._eval_without_enc("::safe::interpDelete #{name}") + rescue Exception + else + next if subip.deleted? + end + end + if subip.respond_to?(:safe_base?) && subip.safe_base? && + !subip.deleted? + # do 'exit' to call the delete_hook procedure + begin + subip._eval_without_enc('exit') + rescue Exception + end + else + begin + subip.delete unless subip.deleted? + rescue Exception + end + end + } + + begin + # @interp._eval_without_enc("foreach i [after info] {after cancel $i}") + after_ids = @interp._eval_without_enc("after info") + @interp._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}") + rescue Exception + end + begin + @interp._invoke('destroy', '.') unless @interp.deleted? + rescue Exception + end + if @safe_base && !@interp.deleted? + # do 'exit' to call the delete_hook procedure + @interp._eval_without_enc('exit') + else + @interp.delete unless @interp.deleted? + end + end + + if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/ + _check_and_return(thread, MultiTkIp_OK.new($3 == 'exit')) + else + _check_and_return(thread, MultiTkIp_OK.new(nil)) + end + + # if master? && !safe? && allow_ruby_exit? + if !@interp.deleted? && master? && !safe? && allow_ruby_exit? +=begin + ObjectSpace.each_object(TclTkIp){|obj| + obj.delete unless obj.deleted? + } +=end + #exit(e.status) + fail e + end + # break + + rescue SecurityError => e + # in 'exit', 'exit!', and 'abort' : security error --> delete IP + if e.backtrace[0] =~ /^(.+?):(\d+):in `(exit|exit!|abort)'/ + ret = ($3 == 'exit') + unless @interp.deleted? + @slave_ip_tbl.each{|name, subip| + _destroy_slaves_of_slaveIP(subip) + begin + # subip._eval_without_enc("foreach i [after info] {after cancel $i}") + after_ids = subip._eval_without_enc("after info") + subip._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}") + rescue Exception + end +=begin + begin + subip._invoke('destroy', '.') unless subip.deleted? + rescue Exception + end +=end + # safe_base? + if @interp._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0' + begin + @interp._eval_without_enc("::safe::interpDelete #{name}") + rescue Exception + else + next if subip.deleted? + end + end + if subip.respond_to?(:safe_base?) && subip.safe_base? && + !subip.deleted? + # do 'exit' to call the delete_hook procedure + begin + subip._eval_without_enc('exit') + rescue Exception + end + else + begin + subip.delete unless subip.deleted? + rescue Exception + end + end + } + + begin + # @interp._eval_without_enc("foreach i [after info] {after cancel $i}") + after_ids = @interp._eval_without_enc("after info") + @interp._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}") + rescue Exception + end +=begin + begin + @interp._invoke('destroy', '.') unless @interp.deleted? + rescue Exception + end +=end + if @safe_base && !@interp.deleted? + # do 'exit' to call the delete_hook procedure + @interp._eval_without_enc('exit') + else + @interp.delete unless @interp.deleted? + end + end + _check_and_return(thread, MultiTkIp_OK.new(ret)) + # break + + else + # raise security error + _check_and_return(thread, e) + end + + rescue Exception => e + # raise exception + begin + bt = _toUTF8(e.backtrace.join("\n")) + bt.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + bt = e.backtrace.join("\n") + end + begin + @interp._set_global_var('errorInfo', bt) + rescue Exception + end + _check_and_return(thread, e) + + else + # no exception + _check_and_return(thread, MultiTkIp_OK.new(ret)) + end + end + + def _receiver_eval_proc(last_thread, safe_level, thread, cmd, *args) + if thread + Thread.new{ + last_thread.join if last_thread + unless @interp.deleted? + _receiver_eval_proc_core(safe_level, thread, cmd, *args) + end + } + else + Thread.new{ + unless @interp.deleted? + _receiver_eval_proc_core(safe_level, thread, cmd, *args) + end + } + last_thread + end + end + + private :_receiver_eval_proc, :_receiver_eval_proc_core + + def _receiver_mainloop(check_root) + if @evloop_thread[0] && @evloop_thread[0].alive? + @evloop_thread[0] + else + @evloop_thread[0] = Thread.new{ + while !@interp.deleted? + #if check_root + # inf = @interp._invoke_without_enc('info', 'command', '.') + # break if !inf.kind_of?(String) || inf != '.' + #end + break if check_root && !@interp.has_mainwindow? + sleep 0.5 + end + } + @evloop_thread[0] + end + end + + def _create_receiver_and_watchdog(lvl = $SAFE) + lvl = $SAFE if lvl < $SAFE + + # command-procedures receiver + receiver = Thread.new(lvl){|safe_level| + last_thread = {} + + loop do + break if @interp.deleted? + thread, cmd, *args = @cmd_queue.deq + if thread == @system + # control command + case cmd + when 'set_safe_level' + begin + safe_level = args[0] if safe_level < args[0] + rescue Exception + end + when 'call_mainloop' + thread = args.shift + _check_and_return(thread, + MultiTkIp_OK.new(_receiver_mainloop(*args))) + else + # ignore + end + + else + # procedure + last_thread[thread] = _receiver_eval_proc(last_thread[thread], + safe_level, thread, + cmd, *args) + end + end + } + + # watchdog of receiver + watchdog = Thread.new{ + begin + loop do + sleep 1 + receiver.kill if @interp.deleted? + break unless receiver.alive? + end + rescue Exception + # ignore all kind of Exception + end + # receiver is dead + loop do + thread, cmd, *args = @cmd_queue.deq + next unless thread + if thread.alive? + if @interp.deleted? + thread.raise RuntimeError, 'the interpreter is already deleted' + else + thread.raise RuntimeError, + 'the interpreter no longer receives command procedures' + end + end + end + } + + # return threads + [receiver, watchdog] + end + private :_check_and_return, :_create_receiver_and_watchdog + + ###################################### + + if self.const_defined? :DEFAULT_MASTER_NAME + name = DEFAULT_MASTER_NAME.to_s + else + name = nil + end + if self.const_defined?(:DEFAULT_MASTER_OPTS) && + DEFAULT_MASTER_OPTS.kind_of?(Hash) + keys = DEFAULT_MASTER_OPTS + else + keys = {} + end + + @@DEFAULT_MASTER = self.allocate + @@DEFAULT_MASTER.instance_eval{ + @tk_windows = {}.taint + + @tk_table_list = [].taint + + @slave_ip_tbl = {}.taint + + @slave_ip_top = {}.taint + + @evloop_thread = [].taint + + unless keys.kind_of? Hash + fail ArgumentError, "expecting a Hash object for the 2nd argument" + end + + @interp = TclTkIp.new(name, _keys2opts(keys)) + @ip_name = nil + + @callback_status = [].taint + + @system = Object.new + + @wait_on_mainloop = [true, 0].taint + + @threadgroup = Thread.current.group + + @safe_base = false + + @safe_level = [$SAFE] + + @cmd_queue = Queue.new + + @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog(@safe_level[0]) + + @threadgroup.add @cmd_receiver + @threadgroup.add @receiver_watchdog + + # NOT enclose @threadgroup for @@DEFAULT_MASTER + + @@IP_TABLE[ThreadGroup::Default] = self + @@IP_TABLE[@threadgroup] = self + + ################################# + + @pseudo_toplevel = [false, nil] + + def self.__pseudo_toplevel + Thread.current.group == ThreadGroup::Default && + MultiTkIp.__getip == @@DEFAULT_MASTER && + self.__pseudo_toplevel_evaluable? && @pseudo_toplevel[1] + end + + def self.__pseudo_toplevel=(m) + unless (Thread.current.group == ThreadGroup::Default && + MultiTkIp.__getip == @@DEFAULT_MASTER) + fail SecurityError, "no permission to manipulate" + end + + # if m.kind_of?(Module) && m.respond_to?(:pseudo_toplevel_evaluable?) + if m.respond_to?(:pseudo_toplevel_evaluable?) + @pseudo_toplevel[0] = true + @pseudo_toplevel[1] = m + else + fail ArgumentError, 'fail to set pseudo-toplevel' + end + self + end + + def self.__pseudo_toplevel_evaluable? + begin + @pseudo_toplevel[0] && @pseudo_toplevel[1].pseudo_toplevel_evaluable? + rescue Exception + false + end + end + + def self.__pseudo_toplevel_evaluable=(mode) + unless (Thread.current.group == ThreadGroup::Default && + MultiTkIp.__getip == @@DEFAULT_MASTER) + fail SecurityError, "no permission to manipulate" + end + + @pseudo_toplevel[0] = (mode)? true: false + end + + ################################# + + @assign_request = Class.new(Exception){ + def self.new(target, ret) + obj = super() + obj.target = target + obj.ret = ret + obj + end + attr_accessor :target, :ret + } + + @assign_thread = Thread.new{ + loop do + begin + Thread.stop + rescue @assign_request=>req + begin + req.ret[0] = req.target.instance_eval{ + @cmd_receiver, @receiver_watchdog = + _create_receiver_and_watchdog(@safe_level[0]) + @threadgroup.add @cmd_receiver + @threadgroup.add @receiver_watchdog + @threadgroup.enclose + true + } + rescue Exception=>e + begin + req.ret[0] = e + rescue Exception + # ignore + end + end + rescue Exception + # ignore + end + end + } + + def self.assign_receiver_and_watchdog(target) + ret = [nil] + @assign_thread.raise(@assign_request.new(target, ret)) + while ret[0] == nil + unless @assign_thread.alive? + raise RuntimeError, 'lost the thread to assign a receiver and a watchdog thread' + end + end + if ret[0].kind_of?(Exception) + raise ret[0] + else + ret[0] + end + end + + ################################# + + @init_ip_env_queue = Queue.new + Thread.new{ + current = Thread.current + loop { + mtx, ret, table, script = @init_ip_env_queue.deq + begin + ret[0] = table.each{|tg, ip| ip._init_ip_env(script) } + rescue Exception => e + ret[0] = e + ensure + mtx.unlock + end + } + } + + def self.__init_ip_env__(table, script) + ret = [] + mtx = Mutex.new.lock + @init_ip_env_queue.enq([mtx, ret, table, script]) + mtx.lock + if ret[0].kind_of?(Exception) + raise ret[0] + else + ret[0] + end + end + + ################################# + + class << self + undef :instance_eval + end + } + + @@DEFAULT_MASTER.freeze # defend against modification + + ###################################### + + def self.inherited(subclass) + # trust if on ThreadGroup::Default or @@DEFAULT_MASTER's ThreadGroup + if @@IP_TABLE[Thread.current.group] == @@DEFAULT_MASTER + begin + class << subclass + self.methods.each{|m| + begin + unless m == '__id__' || m == '__send__' || m == 'freeze' + undef_method(m) + end + rescue Exception + # ignore all exceptions + end + } + end + ensure + subclass.freeze + fail SecurityError, + "cannot create subclass of MultiTkIp on a untrusted ThreadGroup" + end + end + end + + ###################################### + + @@SAFE_OPT_LIST = [ + 'accessPath'.freeze, + 'statics'.freeze, + 'nested'.freeze, + 'deleteHook'.freeze + ].freeze + + def _parse_slaveopts(keys) + name = nil + safe = false + safe_opts = {} + tk_opts = {} + + keys.each{|k,v| + k_str = k.to_s + if k_str == 'name' + name = v + elsif k_str == 'safe' + safe = v + elsif @@SAFE_OPT_LIST.member?(k_str) + safe_opts[k_str] = v + else + tk_opts[k_str] = v + end + } + + 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('') + @@SLAVE_IP_ID[1].succ! + name.freeze + end + private :_create_slave_ip_name + + ###################################### + + def __check_safetk_optkeys(optkeys) + # based on 'safetk.tcl' + new_keys = {} + optkeys.each{|k,v| new_keys[k.to_s] = v} + + # check 'display' + if !new_keys.key?('display') + begin + #new_keys['display'] = @interp._invoke('winfo screen .') + new_keys['display'] = @interp._invoke('winfo', 'screen', '.') + rescue + if ENV[DISPLAY] + new_keys['display'] = ENV[DISPLAY] + elsif !new_keys.key?('use') + warn "Warning: no screen info or ENV[DISPLAY], so use ':0.0'" + new_keys['display'] = ':0.0' + end + end + end + + # check 'use' + if new_keys.key?('use') + # given 'use' + case new_keys['use'] + when TkWindow + new_keys['use'] = TkWinfo.id(new_keys['use']) + #assoc_display = @interp._eval('winfo screen .') + assoc_display = @interp._invoke('winfo', 'screen', '.') + when /^\..*/ + new_keys['use'] = @interp._invoke('winfo', 'id', new_keys['use']) + assoc_display = @interp._invoke('winfo', 'screen', new_keys['use']) + else + begin + pathname = @interp._invoke('winfo', 'pathname', new_keys['use']) + assoc_display = @interp._invoke('winfo', 'screen', pathname) + rescue + assoc_display = new_keys['display'] + end + end + + # match display? + if assoc_display != new_keys['display'] + if optkeys.key?(:display) || optkeys.key?('display') + fail RuntimeError, + "conflicting 'display'=>#{new_keys['display']} " + + "and display '#{assoc_display}' on 'use'=>#{new_keys['use']}" + else + new_keys['display'] = assoc_display + end + end + end + + # return + new_keys + end + private :__check_safetk_optkeys + + def __create_safetk_frame(slave_ip, slave_name, app_name, keys) + # display option is used by ::safe::loadTk + loadTk_keys = {} + loadTk_keys['display'] = keys['display'] + dup_keys = keys.dup + + # keys for toplevel : allow followings + toplevel_keys = {} + ['height', 'width', 'background', 'menu'].each{|k| + toplevel_keys[k] = dup_keys.delete(k) if dup_keys.key?(k) + } + toplevel_keys['classname'] = 'SafeTk' + toplevel_keys['screen'] = dup_keys.delete('display') + + # other keys used by pack option of container frame + + # create toplevel widget + begin + top = TkToplevel.new(toplevel_keys) + rescue NameError => e + fail e unless @interp.safe? + fail SecurityError, "unable create toplevel on the safe interpreter" + end + msg = "Untrusted Ruby/Tk applet (#{slave_name})" + if app_name.kind_of?(String) + top.title "#{app_name} (#{slave_name})" + else + top.title msg + end + + # 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 + slave_ip._eval_without_enc('exit') + end + begin + top.destroy if top.winfo_exist? + rescue + # ignore + end + } + 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) + + TkFrame.new(fc, :bd=>0){|f| + TkButton.new(f, + :text=>'Delete', :bd=>1, :padx=>2, :pady=>0, + :highlightthickness=>0, :command=>slave_delete_proc + ).pack(:side=>:right, :fill=>:both) + f.pack(:side=>:right, :fill=>:both, :expand=>true) + } + + TkLabel.new(fc, :text=>msg, :padx=>2, :pady=>0, + :anchor=>:w).pack(:side=>:left, :fill=>:both, :expand=>true) + + fc.pack(:side=>:bottom, :fill=>:x) + } + + # container frame for slave interpreter + dup_keys['fill'] = :both unless dup_keys.key?('fill') + dup_keys['expand'] = true unless dup_keys.key?('expand') + c = TkFrame.new(top, :container=>true).pack(dup_keys) + c.bind('Destroy', proc{top.destroy}) + + # return keys + loadTk_keys['use'] = TkWinfo.id(c) + [loadTk_keys, top.path] + end + private :__create_safetk_frame + + def __create_safe_slave_obj(safe_opts, app_name, tk_opts) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + # safe interpreter + ip_name = _create_slave_ip_name + slave_ip = @interp.create_slave(ip_name, true) + @slave_ip_tbl[ip_name] = slave_ip + def slave_ip.safe_base? + true + end + + @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 + + def __create_trusted_slave_obj(name, keys) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + ip_name = _create_slave_ip_name + slave_ip = @interp.create_slave(ip_name, false) + slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String) + slave_ip._invoke('set', 'argv', _keys2opts(keys)) + @interp._invoke('load', '', 'Tk', ip_name) + @slave_ip_tbl[ip_name] = slave_ip + [slave_ip, ip_name] + end + + ###################################### + + def _create_slave_object(keys={}) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + ip = MultiTkIp.new_slave(self, keys={}) + @slave_ip_tbl[ip.name] = ip + end + + ###################################### + + def initialize(master, safeip=true, keys={}) + if $SAFE >= 4 + fail SecurityError, "cannot create a new interpreter at level #{$SAFE}" + end + + if safeip == nil && $SAFE >= 2 + fail SecurityError, "cannot create a master-ip at level #{$SAFE}" + end + + if master.deleted? && safeip == nil + fail RuntimeError, "cannot create a slave of a deleted interpreter" + end + + if !master.deleted? && !master.master? && master.safe? + fail SecurityError, "safe-slave-ip cannot create a new interpreter" + end + + if safeip == nil && !master.master? + fail SecurityError, "slave-ip cannot create a master-ip" + end + + unless keys.kind_of? Hash + fail ArgumentError, "expecting a Hash object for the 2nd argument" + end + + @tk_windows = {} + @tk_table_list = [] + @slave_ip_tbl = {} + @slave_ip_top = {} + @cb_error_proc = [] + @evloop_thread = [] + + @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? + @cb_error_proc.taint unless @cb_error_proc.tainted? + @evloop_thread.taint unless @evloop_thread.tainted? + + @callback_status = [] + + name, safe, safe_opts, tk_opts = _parse_slaveopts(keys) + + safe = 4 if safe && !safe.kind_of?(Fixnum) + + @safe_base = false + + if safeip == nil + # create master-ip + @interp = TclTkIp.new(name, _keys2opts(tk_opts)) + + @ip_name = nil + if safe + safe = $SAFE if safe < $SAFE + @safe_level = [safe] + else + @safe_level = [$SAFE] + end + else + # create slave-ip + if safeip || master.safe? + @safe_base = true + @interp, @ip_name = master.__create_safe_slave_obj(safe_opts, + name, tk_opts) + if safe + safe = master.safe_level if safe < master.safe_level + @safe_level = [safe] + else + @safe_level = [4] + end + else + @interp, @ip_name = master.__create_trusted_slave_obj(name, tk_opts) + if safe + safe = master.safe_level if safe < master.safe_level + @safe_level = [safe] + else + @safe_level = [master.safe_level] + end + end + @set_alias_proc = proc{|name| + master._invoke('interp', 'alias', @ip_name, name, '', name) + }.freeze + end + + @system = Object.new + + @wait_on_mainloop = [true, 0].taint + # @wait_on_mainloop = [false, 0].taint + + @threadgroup = ThreadGroup.new + + @pseudo_toplevel = [false, nil] + + @cmd_queue = Queue.new + +=begin + @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog(@safe_level[0]) + + @threadgroup.add @cmd_receiver + @threadgroup.add @receiver_watchdog + + @threadgroup.enclose +=end + @@DEFAULT_MASTER.assign_receiver_and_watchdog(self) + + @@IP_TABLE[@threadgroup] = self + _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS) + @@TK_TABLE_LIST.size.times{ + (tbl = {}).tainted? || tbl.taint + @tk_table_list << tbl + } + + class << self + undef :instance_eval + end + + # dummy call for initialization + self.eval_proc{ Tk.tk_call('set', 'tcl_patchLevel') } + + self.freeze # defend against modification + end + + ###################################### + + def _default_delete_hook(slave) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @slave_ip_tbl.delete(slave) + top = @slave_ip_top.delete(slave) + if top.kind_of?(String) + # call default hook of safetk.tcl (ignore exceptions) + if top == '' + 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 {} #{top} #{slave}") + rescue + warn("Waring: fail to call '::safe::tkDelete'") if $DEBUG + begin + @interp._eval("destroy #{top}") + rescue + warn("Waring: fail to destroy toplevel") if $DEBUG + end + end + end + end + end + +end + + +# get target IP +class MultiTkIp + def self._ip_id_ + __getip._ip_id_ + end + def _ip_id_ + # for RemoteTkIp + '' + end + + def self.__getip + current = Thread.current + if TclTkLib.mainloop_thread? != false && current['callback_ip'] + return current['callback_ip'] + end + if current.group == ThreadGroup::Default + @@DEFAULT_MASTER + else + ip = @@IP_TABLE[current.group] + unless ip + fail SecurityError, + "cannot call Tk methods on #{Thread.current.inspect}" + end + ip + end + end +end + + +# aliases of constructor +class << MultiTkIp + alias __new new + private :__new + + + def new_master(safe=nil, keys={}) + if safe.kind_of?(Hash) + keys = safe + elsif safe.kind_of?(Integer) + raise ArgumentError, "unexpected argument(s)" unless keys.kind_of?(Hash) + if !keys.key?(:safe) && !keys.key?('safe') + keys[:safe] = safe + end + elsif safe == nil + # do nothing + else + raise ArgumentError, "unexpected argument(s)" + end + + ip = __new(__getip, nil, keys) + #ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? + if block_given? + Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)} + end + ip + end + + alias new new_master + + def new_slave(safe=nil, keys={}) + if safe.kind_of?(Hash) + keys = safe + elsif safe.kind_of?(Integer) + raise ArgumentError, "unexpected argument(s)" unless keys.kind_of?(Hash) + if !keys.key?(:safe) && !keys.key?('safe') + keys[:safe] = safe + end + elsif safe == nil + # do nothing + else + raise ArgumentError, "unexpected argument(s)" + end + + ip = __new(__getip, false, keys) + # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? + if block_given? + Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)} + end + ip + end + alias new_trusted_slave new_slave + + def new_safe_slave(safe=4, keys={}) + if safe.kind_of?(Hash) + keys = safe + elsif safe.kind_of?(Integer) + raise ArgumentError, "unexpected argument(s)" unless keys.kind_of?(Hash) + if !keys.key?(:safe) && !keys.key?('safe') + keys[:safe] = safe + end + else + raise ArgumentError, "unexpected argument(s)" + end + + ip = __new(__getip, true, keys) + # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given? + if block_given? + Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)} + end + ip + end + alias new_safeTk new_safe_slave +end + + +# get info +class MultiTkIp + def inspect + s = self.to_s.chop! + if self.manipulable? + if master? + if @interp.deleted? + s << ':deleted-master' + else + s << ':master' + end + else + if @interp.deleted? + s << ':deleted-slave' + elsif @interp.safe? + s << ':safe-slave' + else + s << ':trusted-slave' + end + end + end + s << '>' + end + + def master? + if @ip_name + false + else + true + end + end + def self.master? + __getip.master? + end + + def slave? + not master? + end + def self.slave? + not self.master? + end + + def alive? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + begin + return false unless @cmd_receiver.alive? + return false if @interp.deleted? + return false if @interp._invoke('interp', 'exists', '') == '0' + rescue Exception + return false + end + true + end + def self.alive? + __getip.alive? + end + + def path + @ip_name || '' + end + def self.path + __getip.path + end + def ip_name + @ip_name || '' + end + def self.ip_name + __getip.ip_name + end + def to_eval + @ip_name || '' + end + def self.to_eval + __getip.to_eval + end + + def slaves(all = false) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp','slaves').split.map!{|name| + if @slave_ip_tbl.key?(name) + @slave_ip_tbl[name] + elsif all + name + else + nil + end + }.compact! + end + def self.slaves(all = false) + __getip.slaves(all) + end + + def manipulable? + return true if (Thread.current.group == ThreadGroup::Default) + ip = MultiTkIp.__getip + (ip == self) || ip._is_master_of?(@interp) + end + def self.manipulable? + true + end + + def _is_master_of?(tcltkip_obj) + tcltkip_obj.slave_of?(@interp) + end + protected :_is_master_of? +end + + +# instance methods to treat tables +class MultiTkIp + def _tk_cmd_tbl + tbl = {} + MultiTkIp.tk_cmd_tbl.each{|id, ent| tbl[id] = ent if ent.ip == self } + tbl + end + + def _tk_windows + @tk_windows + end + + def _tk_table_list + @tk_table_list + end + + def _add_new_tables + (@@TK_TABLE_LIST.size - @tk_table_list.size).times{ + (tbl = {}).tainted? || tbl.taint + @tk_table_list << tbl + } + end + + def _init_ip_env(script) + self.eval_proc{script.call(self)} + end + + def _add_tk_procs(name, args, body) + return if slave? + @interp._invoke('proc', name, args, body) if args && body + @interp._invoke('interp', 'slaves').split.each{|slave| + @interp._invoke('interp', 'alias', slave, name, '', name) + } + end + + def _remove_tk_procs(*names) + return if slave? + names.each{|name| + name = name.to_s + @interp._invoke('rename', name, '') + @interp._invoke('interp', 'slaves').split.each{|slave| + @interp._invoke('interp', 'alias', slave, name, '') rescue nil + } + } + end + + def _init_ip_internal(init_ip_env, add_tk_procs) + #init_ip_env.each{|script| self.eval_proc{script.call(self)}} + init_ip_env.each{|script| self._init_ip_env(script)} + add_tk_procs.each{|name, args, body| + if master? + @interp._invoke('proc', name, args, body) if args && body + else + @set_alias_proc.call(name) + end + } + end +end + + +# class methods to treat tables +class MultiTkIp + def self.tk_cmd_tbl + @@TK_CMD_TBL + end + def self.tk_windows + __getip._tk_windows + end + def self.tk_object_table(id) + __getip._tk_table_list[id] + end + def self.create_table + if __getip.slave? + begin + raise SecurityError, "slave-IP has no permission creating a new table" + rescue SecurityError => e + #p e.backtrace + # Is called on a Ruby/Tk library? + caller_info = e.backtrace[1] + if caller_info =~ %r{^#{MultiTkIp::BASE_DIR}/(tk|tkextlib)/[^:]+\.rb:} + # Probably, caller is a Ruby/Tk library --> allow creating + else + raise e + end + end + end + + id = @@TK_TABLE_LIST.size + obj = Object.new + @@TK_TABLE_LIST << obj + obj.instance_eval <<-EOD + def self.method_missing(m, *args) + MultiTkIp.tk_object_table(#{id}).__send__(m, *args) + end + EOD + obj.freeze + @@IP_TABLE.each{|tg, ip| ip._add_new_tables } + return obj + end + + def self.init_ip_env(script = Proc.new) + @@INIT_IP_ENV << script + if __getip.slave? + begin + raise SecurityError, "slave-IP has no permission initializing IP env" + rescue SecurityError => e + #p e.backtrace + # Is called on a Ruby/Tk library? + caller_info = e.backtrace[1] + if caller_info =~ %r{^#{MultiTkIp::BASE_DIR}/(tk|tkextlib)/[^:]+\.rb:} + # Probably, caller is a Ruby/Tk library --> allow creating + else + raise e + end + end + end + + # @@IP_TABLE.each{|tg, ip| + # ip._init_ip_env(script) + # } + @@DEFAULT_MASTER.__init_ip_env__(@@IP_TABLE, script) + end + + def self.add_tk_procs(name, args=nil, body=nil) + if name.kind_of?(Array) # => an array of [name, args, body] + name.each{|param| self.add_tk_procs(*param)} + else + name = name.to_s + @@ADD_TK_PROCS << [name, args, body] + @@IP_TABLE.each{|tg, ip| + ip._add_tk_procs(name, args, body) + } + end + end + + def self.remove_tk_procs(*names) + names.each{|name| + name = name.to_s + @@ADD_TK_PROCS.delete_if{|elem| + elem.kind_of?(Array) && elem[0].to_s == name + } + } + @@IP_TABLE.each{|tg, ip| + ip._remove_tk_procs(*names) + } + end + + def self.init_ip_internal + __getip._init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS) + end +end + + +# for callback operation +class MultiTkIp + def self.cb_entry_class + @@CB_ENTRY_CLASS + end + def self.get_cb_entry(cmd) + @@CB_ENTRY_CLASS.new(__getip, cmd).freeze + end + +=begin + def cb_eval(cmd, *args) + #self.eval_callback{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) } + #ret = self.eval_callback{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) } + ret = self.eval_callback(*args){|safe, *params| + $SAFE=safe if $SAFE < safe + TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params)) + } + if ret.kind_of?(Exception) + raise ret + end + ret + end +=end + def cb_eval(cmd, *args) + self.eval_callback(*args){|safe, *params| + $SAFE=safe if $SAFE < safe + # TkUtil.eval_cmd(cmd, *params) + TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params)) + } + end +=begin + def cb_eval(cmd, *args) + @callback_status[0] ||= TkVariable.new + @callback_status[1] ||= TkVariable.new + st, val = @callback_status + th = Thread.new{ + self.eval_callback(*args){|safe, *params| + #p [status, val, safe, *params] + $SAFE=safe if $SAFE < safe + begin + TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params)) + rescue TkCallbackContinue + st.value = 4 + rescue TkCallbackBreak + st.value = 3 + rescue TkCallbackReturn + st.value = 2 + rescue Exception => e + val.value = e.message + st.value = 1 + else + st.value = 0 + end + } + } + begin + st.wait + status = st.numeric + retval = val.value + rescue => e + fail e + end + + if status == 1 + fail RuntimeError, retval + elsif status == 2 + fail TkCallbackReturn, "Tk callback returns 'return' status" + elsif status == 3 + fail TkCallbackBreak, "Tk callback returns 'break' status" + elsif status == 4 + fail TkCallbackContinue, "Tk callback returns 'continue' status" + else + '' + end + end +=end + +end + +# pseudo-toplevel operation support +class MultiTkIp + # instance method + def __pseudo_toplevel + ip = MultiTkIp.__getip + (ip == @@DEFAULT_MASTER || ip == self) && + self.__pseudo_toplevel_evaluable? && @pseudo_toplevel[1] + end + + def __pseudo_toplevel=(m) + unless (Thread.current.group == ThreadGroup::Default && + MultiTkIp.__getip == @@DEFAULT_MASTER) + fail SecurityError, "no permission to manipulate" + end + + # if m.kind_of?(Module) && m.respond_to?(:pseudo_toplevel_evaluable?) + if m.respond_to?(:pseudo_toplevel_evaluable?) + @pseudo_toplevel[0] = true + @pseudo_toplevel[1] = m + else + fail ArgumentError, 'fail to set pseudo-toplevel' + end + self + end + + def __pseudo_toplevel_evaluable? + begin + @pseudo_toplevel[0] && @pseudo_toplevel[1].pseudo_toplevel_evaluable? + rescue Exception + false + end + end + + def __pseudo_toplevel_evaluable=(mode) + unless (Thread.current.group == ThreadGroup::Default && + MultiTkIp.__getip == @@DEFAULT_MASTER) + fail SecurityError, "no permission to manipulate" + end + + @pseudo_toplevel[0] = (mode)? true: false + end +end + +# evaluate a procedure on the proper interpreter +class MultiTkIp + # instance method + def eval_proc_core(req_val, cmd, *args) + # check + raise SecurityError, "no permission to manipulate" unless self.manipulable? + unless cmd.kind_of?(Proc) || cmd.kind_of?(Method) + raise RuntimeError, "A Proc/Method object is expected for the 'cmd' argument" + end + + # on IP thread + if @cmd_receiver == Thread.current || + (!req_val && TclTkLib.mainloop_thread? != false) # callback + begin + ret = cmd.call(safe_level, *args) + rescue SystemExit => e + # 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 + if $DEBUG + warn("Warning: " + e.class.inspect + + ((e.message.length > 0)? ' "' + e.message + '"': '') + + " on " + self.inspect) + end +=begin + begin + bt = _toUTF8(e.backtrace.join("\n")) + bt.instance_variable_set(:@encoding, 'utf-8') + rescue Exception + bt = e.backtrace.join("\n") + end + begin + @interp._set_global_var('errorInfo', bt) + rescue Exception + end +=end + ret = e + end + return ret + end + + # send cmd to the proc-queue + unless req_val + begin + @cmd_queue.enq([nil, cmd, *args]) + rescue Exception => e + # ignore + if $DEBUG + warn("Warning: " + e.class.inspect + + ((e.message.length > 0)? ' "' + e.message + '"': '') + + " on " + self.inspect) + end + return e + end + return nil + end + + # send and get return value by exception + begin + @cmd_queue.enq([Thread.current, cmd, *args]) + Thread.stop + rescue MultiTkIp_OK => ret + # return value + return ret.value + rescue SystemExit => e + # exit IP + warn("Warning: " + $! + " on " + self.inspect) if $DEBUG + begin + self._eval_without_enc('exit') + rescue Exception + end + if !self.deleted? && !safe? && allow_ruby_exit? + self.delete + fail e + else + self.delete + end + rescue Exception => e + if $DEBUG + warn("Warning: " + e.class.inspect + + ((e.message.length > 0)? ' "' + e.message + '"': '') + + " on " + self.inspect) + end + return e + end + return nil + end + private :eval_proc_core + + def eval_callback(*args) + if block_given? + cmd = Proc.new + else + cmd = args.shift + end + current = Thread.current + backup_ip = current['callback_ip'] + current['callback_ip'] = self + begin + eval_proc_core(false, cmd, *args) + ensure + current['callback_ip'] = backup_ip + end + end + + def eval_proc(*args) + # The scope of the eval-block of 'eval_proc' method is different from + # the external. If you want to pass local values to the eval-block, + # use arguments of eval_proc method. They are passed to block-arguments. + if block_given? + cmd = Proc.new + else + unless (cmd = args.shift) + fail ArgumentError, "A Proc or Method object is expected for 1st argument" + end + end + if TclTkLib.mainloop_thread? == true + # call from eventloop + current = Thread.current + backup_ip = current['callback_ip'] + current['callback_ip'] = self + begin + eval_proc_core(false, + proc{|safe, *params| + $SAFE=safe if $SAFE < safe + cmd.call(*params) + }, *args) + ensure + current['callback_ip'] = backup_ip + end + else + eval_proc_core(true, + proc{|safe, *params| + $SAFE=safe if $SAFE < safe + Thread.new(*params, &cmd).value + }, + *args) + end + end + alias call eval_proc + + def bg_eval_proc(*args) + if block_given? + cmd = Proc.new + else + unless (cmd = args.shift) + fail ArgumentError, "A Proc or Method object is expected for 1st argument" + end + end + Thread.new{ + eval_proc(cmd, *args) +=begin + eval_proc_core(false, + proc{|safe, *params| + $SAFE=safe if $SAFE < safe + Thread.new(*params, &cmd).value + }, + safe_level, *args) +=end + } + end + alias background_eval_proc bg_eval_proc + alias thread_eval_proc bg_eval_proc + alias bg_call bg_eval_proc + alias background_call bg_eval_proc + + def eval_string(cmd, *eval_args) + # cmd string ==> proc + unless cmd.kind_of?(String) + raise RuntimeError, "A String object is expected for the 'cmd' argument" + end + + eval_proc_core(true, + proc{|safe| + Kernel.eval("$SAFE=#{safe} if $SAFE < #{safe};" << cmd, + *eval_args) + }) + end + alias eval_str eval_string + + def bg_eval_string(cmd, *eval_args) + # cmd string ==> proc + unless cmd.kind_of?(String) + raise RuntimeError, "A String object is expected for the 'cmd' argument" + end + Thread.new{ + eval_proc_core(true, + proc{|safe| + Kernel.eval("$SAFE=#{safe} if $SAFE < #{safe};" << cmd, + *eval_args) + }) + } + end + alias background_eval_string bg_eval_string + alias bg_eval_str bg_eval_string + alias background_eval_str bg_eval_string + + def eval(*args, &blk) + if block_given? + eval_proc(*args, &blk) + elsif args[0] + if args[0].respond_to?(:call) + eval_proc(*args) + else + eval_string(*args) + end + else + fail ArgumentError, "no argument to eval" + end + end + + def bg_eval(*args, &blk) + if block_given? + bg_eval_proc(*args, &blk) + elsif args[0] + if args[0].respond_to?(:call) + bg_eval_proc(*args) + else + bg_eval_string(*args) + end + else + fail ArgumentError, "no argument to eval" + end + end + alias background_eval bg_eval +end + +class << MultiTkIp + # class method + def eval_proc(*args, &blk) + # class ==> interp object + __getip.eval_proc(*args, &blk) + end + alias call eval_proc + + def bg_eval_proc(*args, &blk) + # class ==> interp object + __getip.bg_eval_proc(*args, &blk) + end + alias background_eval_proc bg_eval_proc + alias thread_eval_proc bg_eval_proc + alias bg_call bg_eval_proc + alias background_call bg_eval_proc + + def eval_string(cmd, *eval_args) + # class ==> interp object + __getip.eval_string(cmd, *eval_args) + end + alias eval_str eval_string + + def bg_eval_string(cmd, *eval_args) + # class ==> interp object + __getip.bg_eval_string(cmd, *eval_args) + end + alias background_eval_string bg_eval_string + alias bg_eval_str bg_eval_string + alias background_eval_str bg_eval_string + + def eval(*args, &blk) + # class ==> interp object + __getip.eval(*args, &blk) + end + def bg_eval(*args, &blk) + # class ==> interp object + __getip.bg_eval(*args, &blk) + end + alias background_eval bg_eval +end + + +# event loop +# all master/slave IPs are controled by only one event-loop +class << MultiTkIp + def mainloop(check_root = true) + __getip.mainloop(check_root) + end + def mainloop_watchdog(check_root = true) + __getip.mainloop_watchdog(check_root) + end + def do_one_event(flag = TclTkLib::EventFlag::ALL) + __getip.do_one_event(flag) + end + def 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) + TclTkLib.mainloop_abort_on_exception=(mode) + end + def set_eventloop_tick(tick) + __getip.set_eventloop_tick(tick) + end + def get_eventloop_tick + __getip.get_eventloop_tick + end + def set_no_event_wait(tick) + __getip.set_no_event_wait(tick) + end + def get_no_event_wait + __getip.get_no_event_wait + end + def set_eventloop_weight(loop_max, no_event_tick) + __getip.set_eventloop_weight(loop_max, no_event_tick) + end + def get_eventloop_weight + __getip.get_eventloop_weight + end +end + +# class methods to delegate to TclTkIp +class << MultiTkIp + def method_missing(id, *args) + __getip.__send__(id, *args) + end + + def make_safe + __getip.make_safe + end + + def safe? + __getip.safe? + end + + def safe_base? + begin + __getip.safe_base? + rescue + false + end + end + + def allow_ruby_exit? + __getip.allow_ruby_exit? + end + + def allow_ruby_exit= (mode) + __getip.allow_ruby_exit = mode + end + + def delete + __getip.delete + end + + def deleted? + __getip.deleted? + end + + def has_mainwindow? + __getip.has_mainwindow? + end + + def invalid_namespace? + __getip.invalid_namespace? + end + + def abort(msg = nil) + __getip.abort(msg) + end + + def exit(st = true) + __getip.exit(st) + end + + def exit!(st = false) + __getip.exit!(st) + end + + def restart(app_name = nil, keys = {}) + init_ip_internal + + __getip._invoke('set', 'argv0', app_name) if app_name + if keys.kind_of?(Hash) + __getip._invoke('set', 'argv', _keys2opts(keys)) + end + + __getip.restart + end + + def _eval(str) + __getip._eval(str) + end + + def _invoke(*args) + __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=nil) + __getip._toUTF8(str, encoding) + end + + def _fromUTF8(str, encoding=nil) + __getip._fromUTF8(str, encoding) + end + + def _thread_vwait(var) + __getip._thread_vwait(var) + end + + def _thread_tkwait(mode, target) + __getip._thread_tkwait(mode, target) + end + + 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 _make_menu_embeddable(menu_path) + __getip._make_menu_embeddable(menu_path) + 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 + + def _create_console + __getip._create_console + end +end + + +# wrap methods on TclTkLib : not permit calling TclTkLib module methods +class << TclTkLib + def mainloop(check_root = true) + MultiTkIp.mainloop(check_root) + end + def mainloop_watchdog(check_root = true) + MultiTkIp.mainloop_watchdog(check_root) + end + 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 set_eventloop_tick(tick) + MultiTkIp.set_eventloop_tick(tick) + end + def get_eventloop_tick + MultiTkIp.get_eventloop_tick + end + def set_no_event_wait(tick) + MultiTkIp.set_no_event_wait(tick) + end + def get_no_event_wait + MultiTkIp.get_no_event_wait + end + def set_eventloop_weight(loop_max, no_event_tick) + MultiTkIp.set_eventloop_weight(loop_max, no_event_tick) + end + def get_eventloop_weight + MultiTkIp.get_eventloop_weight + end + def restart(*args) + MultiTkIp.restart(*args) + 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) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + #return self if self.slave? + #return self if self != @@DEFAULT_MASTER + if self != @@DEFAULT_MASTER + if @wait_on_mainloop[0] + begin + @wait_on_mainloop[1] += 1 + if $SAFE >= 4 + _receiver_mainloop(check_root).join + else + @cmd_queue.enq([@system, 'call_mainloop', + Thread.current, check_root]) + Thread.stop + end + rescue MultiTkIp_OK => ret + # return value + if ret.value.kind_of?(Thread) + return ret.value.value + else + return ret.value + end + rescue SystemExit => e + # exit IP + warn("Warning: " + $! + " on " + self.inspect) if $DEBUG + begin + self._eval_without_enc('exit') + rescue Exception + end + self.delete + rescue StandardError => e + if $DEBUG + warn("Warning: " + e.class.inspect + + ((e.message.length > 0)? ' "' + e.message + '"': '') + + " on " + self.inspect) + end + return e + rescue Exception => e + return e + ensure + @wait_on_mainloop[1] -= 1 + end + end + return + end + + unless restart_on_dead + @wait_on_mainloop[1] += 1 +=begin + begin + @interp.mainloop(check_root) + rescue StandardError => e + if $DEBUG + warn("Warning: " + e.class.inspect + + ((e.message.length > 0)? ' "' + e.message + '"': '') + + " on " + self.inspect) + end + end +=end + begin + @interp.mainloop(check_root) + ensure + @wait_on_mainloop[1] -= 1 + end + else + loop do + break unless self.alive? + if check_root + begin + break if TclTkLib.num_of_mainwindows == 0 + rescue StandardError + break + end + end + break if @interp.deleted? + begin + @wait_on_mainloop[1] += 1 + @interp.mainloop(check_root) + rescue StandardError => e + if TclTkLib.mainloop_abort_on_exception != nil + #STDERR.print("Warning: Tk mainloop receives ", $!.class.inspect, + # " exception (ignore) : ", $!.message, "\n"); + if $DEBUG + warn("Warning: Tk mainloop receives " << e.class.inspect << + " exception (ignore) : " << e.message); + end + end + #raise e + rescue Exception => e +=begin + if TclTkLib.mainloop_abort_on_exception != nil + #STDERR.print("Warning: Tk mainloop receives ", $!.class.inspect, + # " exception (ignore) : ", $!.message, "\n"); + if $DEBUG + warn("Warning: Tk mainloop receives " << e.class.inspect << + " exception (ignore) : " << e.message); + end + end +=end + raise e + ensure + @wait_on_mainloop[1] -= 1 + Thread.pass # avoid eventloop conflict + end + end + end + self + end + + def make_safe + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.make_safe + end + + def safe? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.safe? + end + + def safe_base? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @safe_base + end + + def allow_ruby_exit? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.allow_ruby_exit? + end + + def allow_ruby_exit= (mode) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.allow_ruby_exit = mode + end + + def delete + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @slave_ip_tbl.each{|name, subip| + _destroy_slaves_of_slaveIP(subip) +=begin + begin + subip._invoke('destroy', '.') unless subip.deleted? + rescue Exception + end +=end + begin + # subip._eval_without_enc("foreach i [after info] {after cancel $i}") + unless subip.deleted? + after_ids = subip._eval_without_enc("after info") + subip._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}") + end + rescue Exception + end + + # safe_base? + if @interp._eval_without_enc("catch {::safe::interpConfigure #{name}}") == '0' + begin + @interp._eval_without_enc("::safe::interpDelete #{name}") + rescue Exception + else + next if subip.deleted? + end + end + if subip.respond_to?(:safe_base?) && subip.safe_base? && + !subip.deleted? + # do 'exit' to call the delete_hook procedure + begin + subip._eval_without_enc('exit') + rescue Exception + end + else + begin + subip.delete unless subip.deleted? + rescue Exception + end + end + } + + begin + # @interp._eval_without_enc("foreach i [after info] {after cancel $i}") + after_ids = @interp._eval_without_enc("after info") + @interp._eval_without_enc("foreach i {#{after_ids}} {after cancel $i}") + rescue Exception + end + + begin + @interp._invoke('destroy', '.') unless @interp.deleted? + rescue Exception + end + + if @safe_base && !@interp.deleted? + # do 'exit' to call the delete_hook procedure + @interp._eval_without_enc('exit') + end + @interp.delete + self + end + + def deleted? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.deleted? + end + + def has_mainwindow? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.has_mainwindow? + end + + def invalid_namespace? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.invalid_namespace? + end + + def abort(msg = nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if master? && !safe? && allow_ruby_exit? + if msg + Kernel.abort(msg) + else + Kernel.abort + end + else + # ignore msg + delete + 1 + end + end + + def exit(st = true) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if master? && !safe? && allow_ruby_exit? + Kernel.exit(st) + else + delete + st + end + end + + def exit!(st = false) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if master? && !safe? && allow_ruby_exit? + Kernel.exit!(st) + else + delete + st + end + end + + def restart(app_name = nil, keys = {}) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS) + + @interp._invoke('set', 'argv0', app_name) if app_name + if keys.kind_of?(Hash) + @interp._invoke('set', 'argv', _keys2opts(keys)) + end + + @interp.restart + end + + def __eval(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.__eval(str) + end + + def __invoke(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.__invoke(*args) + end + + def _eval(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._eval(str) + end + + def _invoke(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke(*args) + end + + def _eval_without_enc(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._eval_without_enc(str) + end + + def _invoke_without_enc(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke_without_enc(*args) + end + + def _eval_with_enc(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._eval_with_enc(str) + end + + def _invoke_with_enc(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke_with_enc(*args) + end + + def _toUTF8(str, encoding=nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._toUTF8(str, encoding) + end + + def _fromUTF8(str, encoding=nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._fromUTF8(str, encoding) + end + + def _thread_vwait(var) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._thread_vwait(var) + end + + def _thread_tkwait(mode, target) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._thread_tkwait(mode, target) + end + + def _return_value + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._return_value + end + + def _get_variable(var, flag) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._get_variable(var, flag) + end + def _get_variable2(var, idx, flag) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._get_variable2(var, idx, flag) + end + def _set_variable(var, value, flag) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._set_variable(var, value, flag) + end + def _set_variable2(var, idx, value, flag) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._set_variable2(var, idx, value, flag) + end + def _unset_variable(var, flag) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._unset_variable(var, flag) + end + def _unset_variable2(var, idx, flag) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._unset_variable2(var, idx, flag) + end + + def _get_global_var(var) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._get_global_var(var) + end + def _get_global_var2(var, idx) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._get_global_var2(var, idx) + end + def _set_global_var(var, value) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._set_global_var(var, value) + end + def _set_global_var2(var, idx, value) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._set_global_var2(var, idx, value) + end + def _unset_global_var(var) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._unset_global_var(var) + end + def _unset_global_var2(var, idx) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._unset_global_var2(var, idx) + end + + def _make_menu_embeddable(menu_path) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._make_menu_embeddable(menu_path) + end + + def _split_tklist(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._split_tklist(str) + end + def _merge_tklist(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._merge_tklist(*args) + end + def _conv_listelement(arg) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._conv_listelement(arg) + end +end + + +# interp command support +class MultiTkIp + def _lst2ary(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 + brace = 1 + str.each_byte {|c| + i += 1 + brace += 1 if c == ?{ + brace -= 1 if c == ?} + break if brace == 0 + } + if i == 0 + list.push '' + elsif str[0, i] == ' ' + list.push ' ' + else + list.push str[0..i-1] + end + #list += _lst2ary(str[i+1..-1]) + list.concat(_lst2ary(str[i+1..-1])) + list + end + private :_lst2ary + + def _slavearg(slave) + if slave.kind_of?(MultiTkIp) + slave.path + elsif slave.kind_of?(String) + slave + else + slave.to_s + end + end + private :_slavearg + + def alias_info(slave, cmd_name) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + _lst2ary(@interp._invoke('interp', 'alias', _slavearg(slave), cmd_name)) + end + def self.alias_info(slave, cmd_name) + __getip.alias_info(slave, cmd_name) + end + + def alias_delete(slave, cmd_name) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'alias', _slavearg(slave), cmd_name, '') + self + end + def self.alias_delete(slave, cmd_name) + __getip.alias_delete(slave, cmd_name) + self + end + + def def_alias(slave, new_cmd, org_cmd, *args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + ret = @interp._invoke('interp', 'alias', _slavearg(slave), new_cmd, + '', org_cmd, *args) + (ret == new_cmd)? self: nil + end + def self.def_alias(slave, new_cmd, org_cmd, *args) + ret = __getip.def_alias(slave, new_cmd, org_cmd, *args) + (ret == new_cmd)? self: nil + end + + def aliases(slave = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + _lst2ary(@interp._invoke('interp', 'aliases', _slavearg(slave))) + end + def self.aliases(slave = '') + __getip.aliases(slave) + end + + def delete_slaves(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + slaves = args.collect{|s| _slavearg(s)} + @interp._invoke('interp', 'delete', *slaves) if slaves.size > 0 + self + end + def self.delete_slaves(*args) + __getip.delete_slaves(*args) + self + end + + def exist?(slave = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + ret = @interp._invoke('interp', 'exists', _slavearg(slave)) + (ret == '1')? true: false + end + def self.exist?(slave = '') + __getip.exist?(slave) + end + + def delete_cmd(slave, cmd) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + slave_invoke = @interp._invoke('list', 'rename', cmd, '') + @interp._invoke('interp', 'eval', _slavearg(slave), slave_invoke) + self + end + def self.delete_cmd(slave, cmd) + __getip.delete_cmd(slave, cmd) + self + end + + def expose_cmd(slave, cmd, aliasname = nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if aliasname + @interp._invoke('interp', 'expose', _slavearg(slave), cmd, aliasname) + else + @interp._invoke('interp', 'expose', _slavearg(slave), cmd) + end + self + end + def self.expose_cmd(slave, cmd, aliasname = nil) + __getip.expose_cmd(slave, cmd, aliasname) + self + end + + def hide_cmd(slave, cmd, aliasname = nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if aliasname + @interp._invoke('interp', 'hide', _slavearg(slave), cmd, aliasname) + else + @interp._invoke('interp', 'hide', _slavearg(slave), cmd) + end + self + end + def self.hide_cmd(slave, cmd, aliasname = nil) + __getip.hide_cmd(slave, cmd, aliasname) + self + end + + def hidden_cmds(slave = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + _lst2ary(@interp._invoke('interp', 'hidden', _slavearg(slave))) + end + def self.hidden_cmds(slave = '') + __getip.hidden_cmds(slave) + end + + def invoke_hidden(slave, cmd, *args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = [] + end + keys << _slavearg(slave) + if Tk::TCL_MAJOR_VERSION > 8 || + (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5) + keys << '--' + end + keys << cmd + keys.concat(args) + @interp._invoke('interp', 'invokehidden', *keys) + end + def self.invoke_hidden(slave, cmd, *args) + __getip.invoke_hidden(slave, cmd, *args) + end + + def invoke_hidden_on_global(slave, cmd, *args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = [] + end + keys << _slavearg(slave) + keys << '-global' + if Tk::TCL_MAJOR_VERSION > 8 || + (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5) + keys << '--' + end + keys << cmd + keys.concat(args) + @interp._invoke('interp', 'invokehidden', *keys) + end + def self.invoke_hidden_on_global(slave, cmd, *args) + __getip.invoke_hidden_on_global(slave, cmd, *args) + end + + def invoke_hidden_on_namespace(slave, ns, cmd, *args) + # for Tcl8.5 or later + raise SecurityError, "no permission to manipulate" unless self.manipulable? + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = [] + end + keys << _slavearg(slave) + keys << '-namespace' << TkComm._get_eval_string(ns) + keys << '--' << cmd + keys.concat(args) + @interp._invoke('interp', 'invokehidden', *keys) + end + def self.invoke_hidden_on_namespace(slave, ns, cmd, *args) + __getip.invoke_hidden_on_namespace(slave, ns, cmd, *args) + end + + def mark_trusted(slave = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'marktrusted', _slavearg(slave)) + self + end + def self.mark_trusted(slave = '') + __getip.mark_trusted(slave) + self + end + + def set_bgerror_handler(cmd = Proc.new, slave = nil, &b) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + unless TkComm._callback_entry?(cmd) + if !slave && b + slave = cmd + cmd = Proc.new(&b) + end + end + slave = '' unless slave + + @interp._invoke('interp', 'bgerror', _slavearg(slave), cmd) + end + def self.bgerror(cmd = Proc.new, slave = nil, &b) + __getip.bgerror(cmd, slave, &b) + end + + def get_bgerror_handler(slave = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + procedure(@interp._invoke('interp', 'bgerror', _slavearg(slave))) + end + def self.bgerror(slave = '') + __getip.bgerror(slave) + end + + def set_limit(limit_type, slave = '', opts = {}) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'limit', _slavearg(slave), limit_type, opts) + end + def self.set_limit(limit_type, slave = '', opts = {}) + __getip.set_limit(limit_type, slave, opts) + end + + def get_limit(limit_type, slave = '', slot = nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + if slot + num_or_str(@interp._invoke('interp', 'limit', _slavearg(slave), + limit_type, slot)) + else + l = @interp._split_tklist(@interp._invoke_without_enc('interp', 'limit', + _slavearg(slave), + limit_type)) + l.map!{|s| _fromUTF8(s)} + r = {} + until l.empty? + key = l.shift[1..-1] + val = l.shift + val = num_or_str(val) if val + r[key] = val + end + r + end + end + def self.get_limit(limit_type, slave = '', slot = nil) + __getip.get_limit(limit_type, slave, slot) + end + + def recursion_limit(slave = '', limit = None) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + 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 = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'target', _slavearg(slave), aliascmd) + end + def self.alias_target(aliascmd, slave = '') + __getip.alias_target(aliascmd, slave) + end + + def share_stdin(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'share', src, 'stdin', dist) + self + end + def self.share_stdin(dist, src = '') + __getip.share_stdin(dist, src) + self + end + + def share_stdout(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'share', src, 'stdout', dist) + self + end + def self.share_stdout(dist, src = '') + __getip.share_stdout(dist, src) + self + end + + def share_stderr(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'share', src, 'stderr', dist) + self + end + def self.share_stderr(dist, src = '') + __getip.share_stderr(dist, src) + self + end + + def transfer_stdin(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'transfer', src, 'stdin', dist) + self + end + def self.transfer_stdin(dist, src = '') + __getip.transfer_stdin(dist, src) + self + end + + def transfer_stdout(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'transfer', src, 'stdout', dist) + self + end + def self.transfer_stdout(dist, src = '') + __getip.transfer_stdout(dist, src) + self + end + + def transfer_stderr(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'transfer', src, 'stderr', dist) + self + end + def self.transfer_stderr(dist, src = '') + __getip.transfer_stderr(dist, src) + self + end + + def share_stdio(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'share', src, 'stdin', dist) + @interp._invoke('interp', 'share', src, 'stdout', dist) + @interp._invoke('interp', 'share', src, 'stderr', dist) + self + end + def self.share_stdio(dist, src = '') + __getip.share_stdio(dist, src) + self + end + + def transfer_stdio(dist, src = '') + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._invoke('interp', 'transfer', src, 'stdin', dist) + @interp._invoke('interp', 'transfer', src, 'stdout', dist) + @interp._invoke('interp', 'transfer', src, 'stderr', dist) + self + end + def self.transfer_stdio(dist, src = '') + __getip.transfer_stdio(dist, src) + self + end +end + + +# Safe Base :: manipulating safe interpreter +class MultiTkIp + def safeip_configure(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 + ' ' + _keys2opts(slot)) + 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' +=begin + if conf[1] =~ /^rb_out\S* (c(_\d+_)?\d+)/ + ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$1] +=end + if conf[1] =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ + ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$4] + 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' +=begin + if v =~ /^rb_out\S* (c(_\d+_)?\d+)/ + ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$1] +=end + if v =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ + ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$4] + else + ret[k[1..-1]] = v + end + else + ret[k[1..-1]] = v + end + } + end + ret + end + + def safeip_delete + ip = MultiTkIp.__getip + ip._eval("::safe::interpDelete " + @ip_name) + end + + def safeip_add_to_access_path(dir) + ip = MultiTkIp.__getip + ip._eval("::safe::interpAddToAccessPath #{@ip_name} #{dir}") + end + + def safeip_find_in_access_path(dir) + ip = MultiTkIp.__getip + ip._eval("::safe::interpFindInAccessPath #{@ip_name} #{dir}") + end + + def safeip_set_log_cmd(cmd = Proc.new) + ip = MultiTkIp.__getip + ip._eval("::safe::setLogCmd #{@ip_name} #{_get_eval_string(cmd)}") + end +end + + +# encoding convert +class MultiTkIp + def encoding + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.encoding + end + def encoding=(enc) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.encoding = enc + end + + def encoding_convertfrom(str, enc=None) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.encoding_convertfrom(str, enc) + end + alias encoding_convert_from encoding_convertfrom + + def encoding_convertto(str, enc=None) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp.encoding_convertto(str, enc) + end + alias encoding_convert_to encoding_convertto +end + + +# remove methods for security +class MultiTkIp + # undef_method :instance_eval + undef_method :instance_variable_get + undef_method :instance_variable_set +end + + +# end of MultiTkIp definition + +# defend against modification +#MultiTkIp.freeze +#TclTkLib.freeze + +######################################## +# start Tk which depends on MultiTkIp +module TkCore + INTERP = MultiTkIp +end +require 'tk' diff --git a/ruby_1_8_6/ext/tk/lib/remote-tk.rb b/ruby_1_8_6/ext/tk/lib/remote-tk.rb new file mode 100644 index 0000000000..70115a60aa --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/remote-tk.rb @@ -0,0 +1,526 @@ +# +# remote-tk.rb - supports to control remote Tk interpreters +# by Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> + +if defined? MultiTkIp + fail RuntimeError, "'remote-tk' library must be required before requiring 'multi-tk'" +end + +class MultiTkIp; end +class RemoteTkIp < MultiTkIp; end + +class MultiTkIp + @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE) + @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST) + def self._IP_TABLE; @@IP_TABLE; end + def self._TK_TABLE_LIST; @@TK_TABLE_LIST; end + + @flag = true + def self._DEFAULT_MASTER + # work only once + if @flag + @flag = nil + @@DEFAULT_MASTER + else + nil + end + end +end +class RemoteTkIp + @@IP_TABLE = MultiTkIp._IP_TABLE unless defined?(@@IP_TABLE) + @@TK_TABLE_LIST = MultiTkIp._TK_TABLE_LIST unless defined?(@@TK_TABLE_LIST) +end +class << MultiTkIp + undef _IP_TABLE + undef _TK_TABLE_LIST +end + +require 'multi-tk' + +class RemoteTkIp + if defined?(@@DEFAULT_MASTER) + MultiTkIp._DEFAULT_MASTER + else + @@DEFAULT_MASTER = MultiTkIp._DEFAULT_MASTER + end +end + + +############################### + +class << RemoteTkIp + undef new_master, new_slave, new_safe_slave + undef new_trusted_slave, new_safeTk + + def new(*args, &b) + ip = __new(*args) + ip.eval_proc(&b) if b + ip + end +end + +class RemoteTkIp + def initialize(remote_ip, displayof=nil, timeout=5) + if $SAFE >= 4 + fail SecurityError, "cannot access another interpreter at level #{$SAFE}" + end + + @interp = MultiTkIp.__getip + if @interp.safe? + fail SecurityError, "safe-IP cannot create RemoteTkIp" + end + + + @interp.allow_ruby_exit = false + @appname = @interp._invoke('tk', 'appname') + @remote = remote_ip.to_s.dup.freeze + if displayof.kind_of?(TkWindow) + @displayof = displayof.path.dup.freeze + else + @displayof = nil + end + if self.deleted? + fail RuntimeError, "no Tk application named \"#{@remote}\"" + end + + @tk_windows = {} + @tk_table_list = [] + @slave_ip_tbl = {} + @slave_ip_top = {} + + @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? + + @system = Object.new + + @threadgroup = ThreadGroup.new + + @safe_level = [$SAFE] + + @wait_on_mainloop = [true, 0] + + @cmd_queue = Queue.new + +=begin + @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog() + + @threadgroup.add @cmd_receiver + @threadgroup.add @receiver_watchdog + + @threadgroup.enclose +=end + @@DEFAULT_MASTER.assign_receiver_and_watchdog(self) + + @@IP_TABLE[@threadgroup] = self + @@TK_TABLE_LIST.size.times{ + (tbl = {}).tainted? || tbl.taint + @tk_table_list << tbl + } + + @ret_val = TkVariable.new + if timeout > 0 && ! _available_check(timeout) + fail RuntimeError, "cannot create connection" + end + @ip_id = _create_connection + + class << self + undef :instance_eval + end + + self.freeze # defend against modification + end + + def manipulable? + return true if (Thread.current.group == ThreadGroup::Default) + MultiTkIp.__getip == @interp && ! @interp.safe? + end + def self.manipulable? + true + end + + def _is_master_of?(tcltkip_obj) + tcltkip_obj == @interp + end + protected :_is_master_of? + + def _ip_id_ + @ip_id + end + + def _available_check(timeout = 5) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + return nil if timeout < 1 + @ret_val.value = '' + @interp._invoke('send', '-async', @remote, + 'send', '-async', Tk.appname, + "set #{@ret_val.id} ready") + Tk.update + if @ret_val != 'ready' + (1..(timeout*5)).each{ + sleep 0.2 + Tk.update + break if @ret_val == 'ready' + } + end + @ret_val.value == 'ready' + end + private :_available_check + + def _create_connection + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + ip_id = '_' + @interp._invoke('send', @remote, <<-'EOS') + '_' + if {[catch {set _rubytk_control_ip_id_} ret] != 0} { + set _rubytk_control_ip_id_ 0 + } else { + set _rubytk_control_ip_id_ [expr $ret + 1] + } + return $_rubytk_control_ip_id_ + EOS + + @interp._invoke('send', @remote, <<-EOS) + proc rb_out#{ip_id} args { + send #{@appname} rb_out \$args + } + EOS + + ip_id + end + private :_create_connection + + def _appsend(enc_mode, async, *cmds) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + p ['_appsend', [@remote, @displayof], enc_mode, async, cmds] if $DEBUG + if $SAFE >= 4 + fail SecurityError, "cannot send commands at level 4" + elsif $SAFE >= 1 && cmds.find{|obj| obj.tainted?} + fail SecurityError, "cannot send tainted commands at level #{$SAFE}" + end + + cmds = @interp._merge_tklist(*TkUtil::_conv_args([], enc_mode, *cmds)) + if @displayof + if async + @interp.__invoke('send', '-async', '-displayof', @displayof, + '--', @remote, *cmds) + else + @interp.__invoke('send', '-displayof', @displayof, + '--', @remote, *cmds) + end + else + if async + @interp.__invoke('send', '-async', '--', @remote, *cmds) + else + @interp.__invoke('send', '--', @remote, *cmds) + end + end + end + private :_appsend + + def ready?(timeout=5) + if timeout < 0 + fail ArgumentError, "timeout must be positive number" + end + _available_check(timeout) + end + + def is_rubytk? + return false if _appsend(false, false, 'info', 'command', 'ruby') == "" + [ _appsend(false, false, 'ruby', 'RUBY_VERSION'), + _appsend(false, false, 'set', 'tk_patchLevel') ] + end + + def appsend(async, *args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + if async != true && async != false && async != nil + args.unshift(async) + async = false + end + if @displayof + Tk.appsend_displayof(@remote, @displayof, async, *args) + else + Tk.appsend(@remote, async, *args) + end + end + + def rb_appsend(async, *args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + if async != true && async != false && async != nil + args.unshift(async) + async = false + end + if @displayof + Tk.rb_appsend_displayof(@remote, @displayof, async, *args) + else + Tk.rb_appsend(@remote, async, *args) + end + end + + def create_slave(name, safe=false) + if safe + safe_opt = '' + else + safe_opt = '-safe' + end + _appsend(false, false, "interp create #{safe_opt} -- #{name}") + end + + def make_safe + fail RuntimeError, 'cannot change safe mode of the remote interpreter' + end + + def safe? + _appsend(false, false, 'interp issafe') + end + + def safe_base? + false + end + + def allow_ruby_exit? + false + end + + def allow_ruby_exit= (mode) + fail RuntimeError, 'cannot change mode of the remote interpreter' + end + + def delete + _appsend(false, true, 'exit') + end + + def deleted? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + if @displayof + lst = @interp._invoke_without_enc('winfo', 'interps', + '-displayof', @displayof) + else + lst = @interp._invoke_without_enc('winfo', 'interps') + end + # unless @interp._split_tklist(lst).index(@remote) + unless @interp._split_tklist(lst).index(_toUTF8(@remote)) + true + else + false + end + end + + def has_mainwindow? + raise SecurityError, "no permission to manipulate" unless self.manipulable? + + begin + inf = @interp._invoke_without_enc('info', 'command', '.') + rescue Exception + return nil + end + if !inf.kind_of?(String) || inf != '.' + false + else + true + end + end + + def invalid_namespace? + false + end + + def restart + fail RuntimeError, 'cannot restart the remote interpreter' + end + + def __eval(str) + _appsend(false, false, str) + end + def _eval(str) + _appsend(nil, false, str) + end + def _eval_without_enc(str) + _appsend(false, false, str) + end + def _eval_with_enc(str) + _appsend(true, false, str) + end + + def _invoke(*args) + _appsend(nil, false, *args) + end + + def __invoke(*args) + _appsend(false, false, *args) + end + def _invoke(*args) + _appsend(nil, false, *args) + end + def _invoke_without_enc(*args) + _appsend(false, false, *args) + end + def _invoke_with_enc(*args) + _appsend(true, false, *args) + end + + def _toUTF8(str, encoding=nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._toUTF8(str, encoding) + end + + def _fromUTF8(str, encoding=nil) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._fromUTF8(str, encoding) + end + + def _thread_vwait(var_name) + _appsend(false, 'thread_vwait', varname) + end + + def _thread_tkwait(mode, target) + _appsend(false, 'thread_tkwait', mode, target) + end + + def _return_value + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._return_value + end + + def _get_variable(var_name, flag) + # ignore flag + _appsend(false, 'set', TkComm::_get_eval_string(var_name)) + end + def _get_variable2(var_name, index_name, flag) + # ignore flag + _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})") + end + + def _set_variable(var_name, value, flag) + # ignore flag + _appsend(false, 'set', TkComm::_get_eval_string(var_name), TkComm::_get_eval_string(value)) + end + def _set_variable2(var_name, index_name, value, flag) + # ignore flag + _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})", TkComm::_get_eval_string(value)) + end + + def _unset_variable(var_name, flag) + # ignore flag + _appsend(false, 'unset', TkComm::_get_eval_string(var_name)) + end + def _unset_variable2(var_name, index_name, flag) + # ignore flag + _appsend(false, 'unset', "#{var_name}(#{index_name})") + end + + def _get_global_var(var_name) + _appsend(false, 'set', TkComm::_get_eval_string(var_name)) + end + def _get_global_var2(var_name, index_name) + _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})") + end + + def _set_global_var(var_name, value) + _appsend(false, 'set', TkComm::_get_eval_string(var_name), TkComm::_get_eval_string(value)) + end + def _set_global_var2(var_name, index_name, value) + _appsend(false, 'set', "#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})", TkComm::_get_eval_string(value)) + end + + def _unset_global_var(var_name) + _appsend(false, 'unset', TkComm::_get_eval_string(var_name)) + end + def _unset_global_var2(var_name, index_name) + _appsend(false, 'unset', "#{var_name}(#{index_name})") + end + + def _split_tklist(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._split_tklist(str) + end + + def _merge_tklist(*args) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._merge_tklist(*args) + end + + def _conv_listelement(str) + raise SecurityError, "no permission to manipulate" unless self.manipulable? + @interp._conv_listelement(str) + end + + def _create_console + fail RuntimeError, 'not support "_create_console" on the remote interpreter' + end + + def mainloop + fail RuntimeError, 'not support "mainloop" on the remote interpreter' + end + def mainloop_watchdog + fail RuntimeError, 'not support "mainloop_watchdog" on the remote interpreter' + end + def do_one_evant(flag = nil) + fail RuntimeError, 'not support "do_one_event" on the remote interpreter' + end + def mainloop_abort_on_exception + fail RuntimeError, 'not support "mainloop_abort_on_exception" on the remote interpreter' + end + def mainloop_abort_on_exception=(mode) + fail RuntimeError, 'not support "mainloop_abort_on_exception=" on the remote interpreter' + end + def set_eventloop_tick(*args) + fail RuntimeError, 'not support "set_eventloop_tick" on the remote interpreter' + end + def get_eventloop_tick + fail RuntimeError, 'not support "get_eventloop_tick" on the remote interpreter' + end + def set_no_event_wait(*args) + fail RuntimeError, 'not support "set_no_event_wait" on the remote interpreter' + end + def get_no_event_wait + fail RuntimeError, 'not support "get_no_event_wait" on the remote interpreter' + end + def set_eventloop_weight(*args) + fail RuntimeError, 'not support "set_eventloop_weight" on the remote interpreter' + end + def get_eventloop_weight + fail RuntimeError, 'not support "get_eventloop_weight" on the remote interpreter' + end +end + +class << RemoteTkIp + def mainloop(*args) + fail RuntimeError, 'not support "mainloop" on the remote interpreter' + end + def mainloop_watchdog(*args) + fail RuntimeError, 'not support "mainloop_watchdog" on the remote interpreter' + end + def do_one_evant(flag = nil) + fail RuntimeError, 'not support "do_one_event" on the remote interpreter' + end + def mainloop_abort_on_exception + fail RuntimeError, 'not support "mainloop_abort_on_exception" on the remote interpreter' + end + def mainloop_abort_on_exception=(mode) + fail RuntimeError, 'not support "mainloop_abort_on_exception=" on the remote interpreter' + end + def set_eventloop_tick(*args) + fail RuntimeError, 'not support "set_eventloop_tick" on the remote interpreter' + end + def get_eventloop_tick + fail RuntimeError, 'not support "get_eventloop_tick" on the remote interpreter' + end + def set_no_event_wait(*args) + fail RuntimeError, 'not support "set_no_event_wait" on the remote interpreter' + end + def get_no_event_wait + fail RuntimeError, 'not support "get_no_event_wait" on the remote interpreter' + end + def set_eventloop_weight(*args) + fail RuntimeError, 'not support "set_eventloop_weight" on the remote interpreter' + end + def get_eventloop_weight + fail RuntimeError, 'not support "get_eventloop_weight" on the remote interpreter' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tcltk.rb b/ruby_1_8_6/ext/tk/lib/tcltk.rb new file mode 100644 index 0000000000..1a6694dbff --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tcltk.rb @@ -0,0 +1,367 @@ +# tof + +#### tcltk library, more direct manipulation of tcl/tk +#### Sep. 5, 1997 Y. Shigehiro + +require "tcltklib" + +################ + +# module TclTk: collection of tcl/tk utilities (supplies namespace.) +module TclTk + + # initialize Hash to hold unique symbols and such + @namecnt = {} + + # initialize Hash to hold callbacks + @callback = {} +end + +# TclTk.mainloop(): call TclTkLib.mainloop() +def TclTk.mainloop() + print("mainloop: start\n") if $DEBUG + TclTkLib.mainloop() + print("mainloop: end\n") if $DEBUG +end + +# TclTk.deletecallbackkey(ca): remove callback from TclTk module +# this does not remove callbacks from tcl/tk interpreter +# without calling this method, TclTkInterpreter will not be GCed +# ca: callback(TclTkCallback) +def TclTk.deletecallbackkey(ca) + print("deletecallbackkey: ", ca.to_s(), "\n") if $DEBUG + @callback.delete(ca.to_s) +end + +# TclTk.dcb(ca, wid, W): call TclTk.deletecallbackkey() for each callbacks +# in an array. +# this is for callback for top-level <Destroy> +# ca: array of callbacks(TclTkCallback) +# wid: top-level widget(TclTkWidget) +# w: information about window given by %W(String) +def TclTk.dcb(ca, wid, w) + if wid.to_s() == w + ca.each{|i| + TclTk.deletecallbackkey(i) + } + end +end + +# TclTk._addcallback(ca): register callback +# ca: callback(TclTkCallback) +def TclTk._addcallback(ca) + print("_addcallback: ", ca.to_s(), "\n") if $DEBUG + @callback[ca.to_s()] = ca +end + +# TclTk._callcallback(key, arg): invoke registered callback +# key: key to select callback (to_s value of the TclTkCallback) +# arg: parameter from tcl/tk interpreter +def TclTk._callcallback(key, arg) + print("_callcallback: ", @callback[key].inspect, "\n") if $DEBUG + @callback[key]._call(arg) + # throw out callback value + # should return String to satisfy rb_eval_string() + return "" +end + +# TclTk._newname(prefix): generate unique name(String) +# prefix: prefix of the unique name +def TclTk._newname(prefix) + # generated name counter is stored in @namecnt + if !@namecnt.key?(prefix) + # first appearing prefix, initialize + @namecnt[prefix] = 1 + else + # already appeared prefix, generate next name + @namecnt[prefix] += 1 + end + return "#{prefix}#{@namecnt[prefix]}" +end + +################ + +# class TclTkInterpreter: tcl/tk interpreter +class TclTkInterpreter + + # initialize(): + def initialize() + # generate interpreter object + @ip = TclTkIp.new() + + # add ruby_fmt command to tcl interpreter + # ruby_fmt command format arguments by `format' and call `ruby' command + # (notice ruby command receives only one argument) + if $DEBUG + @ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt $args\" ; set cmd [list ruby [format $fmt $args]] ; uplevel $cmd }") + else + @ip._eval("proc ruby_fmt {fmt args} { set cmd [list ruby [format $fmt $args]] ; uplevel $cmd }") + end + + # @ip._get_eval_string(*args): generate string to evaluate in tcl interpreter + # *args: script which is going to be evaluated under tcl/tk + def @ip._get_eval_string(*args) + argstr = "" + args.each{|arg| + argstr += " " if argstr != "" + # call to_eval if it is defined + if (arg.respond_to?(:to_eval)) + argstr += arg.to_eval() + else + # call to_s unless defined + argstr += arg.to_s() + end + } + return argstr + end + + # @ip._eval_args(*args): evaluate string under tcl/tk interpreter + # returns result string. + # *args: script which is going to be evaluated under tcl/tk + def @ip._eval_args(*args) + # calculate the string to eval in the interpreter + argstr = _get_eval_string(*args) + + # evaluate under the interpreter + print("_eval: \"", argstr, "\"") if $DEBUG + res = _eval(argstr) + if $DEBUG + print(" -> \"", res, "\"\n") + elsif _return_value() != 0 + print(res, "\n") + end + fail(%Q/can't eval "#{argstr}"/) if _return_value() != 0 #' + return res + end + + # generate tcl/tk command object and register in the hash + @commands = {} + # for all commands registered in tcl/tk interpreter: + @ip._eval("info command").split(/ /).each{|comname| + if comname =~ /^[.]/ + # if command is a widget (path), generate TclTkWidget, + # and register it in the hash + @commands[comname] = TclTkWidget.new(@ip, comname) + else + # otherwise, generate TclTkCommand + @commands[comname] = TclTkCommand.new(@ip, comname) + end + } + end + + # commands(): returns hash of the tcl/tk commands + def commands() + return @commands + end + + # rootwidget(): returns root widget(TclTkWidget) + def rootwidget() + return @commands["."] + end + + # _tcltkip(): returns @ip(TclTkIp) + def _tcltkip() + return @ip + end + + # method_missing(id, *args): execute undefined method as tcl/tk command + # id: method symbol + # *args: method arguments + def method_missing(id, *args) + # if command named by id registered, then execute it + if @commands.key?(id.id2name) + return @commands[id.id2name].e(*args) + else + # otherwise, exception + super + end + end +end + +# class TclTkObject: base class of the tcl/tk objects +class TclTkObject + + # initialize(ip, exp): + # ip: interpreter(TclTkIp) + # exp: tcl/tk representation + def initialize(ip, exp) + fail("type is not TclTkIp") if !ip.kind_of?(TclTkIp) + @ip = ip + @exp = exp + end + + # to_s(): returns tcl/tk representation + def to_s() + return @exp + end +end + +# class TclTkCommand: tcl/tk commands +# you should not call TclTkCommand.new() +# commands are created by TclTkInterpreter:initialize() +class TclTkCommand < TclTkObject + + # e(*args): execute command. returns String (e is for exec or eval) + # *args: command arguments + def e(*args) + return @ip._eval_args(to_s(), *args) + end +end + +# class TclTkLibCommand: tcl/tk commands in the library +class TclTkLibCommand < TclTkCommand + + # initialize(ip, name): + # ip: interpreter(TclTkInterpreter) + # name: command name (String) + def initialize(ip, name) + super(ip._tcltkip, name) + end +end + +# class TclTkVariable: tcl/tk variable +class TclTkVariable < TclTkObject + + # initialize(interp, dat): + # interp: interpreter(TclTkInterpreter) + # dat: the value to set(String) + # if nil, not initialize variable + def initialize(interp, dat) + # auto-generate tcl/tk representation (variable name) + exp = TclTk._newname("v_") + # initialize TclTkObject + super(interp._tcltkip(), exp) + # safe this for `set' command + @set = interp.commands()["set"] + # set value + set(dat) if dat + end + + # although you can set/refer variable by using set in tcl/tk, + # we provide the method for accessing variables + + # set(data): set tcl/tk variable using `set' + # data: new value + def set(data) + @set.e(to_s(), data.to_s()) + end + + # get(): read tcl/tk variable(String) using `set' + def get() + return @set.e(to_s()) + end +end + +# class TclTkWidget: tcl/tk widget +class TclTkWidget < TclTkCommand + + # initialize(*args): + # *args: parameters + def initialize(*args) + if args[0].kind_of?(TclTkIp) + # in case the 1st argument is TclTkIp: + + # Wrap tcl/tk widget by TclTkWidget + # (used in TclTkInterpreter#initialize()) + + # need two arguments + fail("illegal # of parameter") if args.size != 2 + + # ip: interpreter(TclTkIp) + # exp: tcl/tk representation + ip, exp = args + + # initialize TclTkObject + super(ip, exp) + elsif args[0].kind_of?(TclTkInterpreter) + # in case 1st parameter is TclTkInterpreter: + + # generate new widget from parent widget + + # interp: interpreter(TclTkInterpreter) + # parent: parent widget + # command: widget generating tk command(label Åù) + # *args: argument to the command + interp, parent, command, *args = args + + # generate widget name + exp = parent.to_s() + exp += "." if exp !~ /[.]$/ + exp += TclTk._newname("w_") + # initialize TclTkObject + super(interp._tcltkip(), exp) + # generate widget + res = @ip._eval_args(command, exp, *args) +# fail("can't create Widget") if res != exp + # for tk_optionMenu, it is legal res != exp + else + fail("first parameter is not TclTkInterpreter") + end + end +end + +# class TclTkCallback: tcl/tk callbacks +class TclTkCallback < TclTkObject + + # initialize(interp, pr, arg): + # interp: interpreter(TclTkInterpreter) + # pr: callback procedure(Proc) + # arg: string to pass as block parameters of pr + # bind command of tcl/tk uses % replacement for parameters + # pr can receive replaced data using block parameter + # its format is specified by arg string + # You should not specify arg for the command like + # scrollbar with -command option, which receives parameters + # without specifying any replacement + def initialize(interp, pr, arg = nil) + # auto-generate tcl/tk representation (variable name) + exp = TclTk._newname("c_") + # initialize TclTkObject + super(interp._tcltkip(), exp) + # save parameters + @pr = pr + @arg = arg + # register in the module + TclTk._addcallback(self) + end + + # to_eval(): retuens string representation for @ip._eval_args + def to_eval() + if @arg + # bind replaces %s before calling ruby_fmt, so %%s is used + s = %Q/{ruby_fmt {TclTk._callcallback("#{to_s()}", "%%s")} #{@arg}}/ + else + s = %Q/{ruby_fmt {TclTk._callcallback("#{to_s()}", "%s")}}/ + end + + return s + end + + # _call(arg): invoke callback + # arg: callback parameter + def _call(arg) + @pr.call(arg) + end +end + +# class TclTkImage: tcl/tk images +class TclTkImage < TclTkCommand + + # initialize(interp, t, *args): + # generating image is done by TclTkImage.new() + # destrying is done by image delete (inconsistent, sigh) + # interp: interpreter(TclTkInterpreter) + # t: image type (photo, bitmap, etc.) + # *args: command argument + def initialize(interp, t, *args) + # auto-generate tcl/tk representation + exp = TclTk._newname("i_") + # initialize TclTkObject + super(interp._tcltkip(), exp) + # generate image + res = @ip._eval_args("image create", t, exp, *args) + fail("can't create Image") if res != exp + end +end + +# eof diff --git a/ruby_1_8_6/ext/tk/lib/tk.rb b/ruby_1_8_6/ext/tk/lib/tk.rb new file mode 100644 index 0000000000..32b5e20bc5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk.rb @@ -0,0 +1,4617 @@ +# +# tk.rb - Tk interface module using tcltklib +# $Date$ +# by Yukihiro Matsumoto <matz@netlab.jp> + +# use Shigehiro's tcltklib +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 + + def _ip_id_ + # for RemoteTkIp + '' + end +end + +# define TkComm module (step 1: basic functions) +module TkComm + include TkUtil + extend TkUtil + + WidgetClassNames = {}.taint + TkExtlibAutoloadModule = [].taint + + # None = Object.new ### --> definition is moved to TkUtil module + # def None.to_s + # 'None' + # end + # None.freeze + + #Tk_CMDTBL = {} + #Tk_WINDOWS = {} + Tk_IDs = ["00000".taint, "00000".taint].freeze # [0]-cmdid, [1]-winid + + # for backward compatibility + Tk_CMDTBL = Object.new + def Tk_CMDTBL.method_missing(id, *args) + TkCore::INTERP.tk_cmd_tbl.__send__(id, *args) + end + Tk_CMDTBL.freeze + Tk_WINDOWS = Object.new + def Tk_WINDOWS.method_missing(id, *args) + TkCore::INTERP.tk_windows.__send__(id, *args) + end + Tk_WINDOWS.freeze + + self.instance_eval{ + @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| + c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! + end + frames + end + private :error_at + + def _genobj_for_tkwidget(path) + return TkRoot.new if path == '.' + + begin + #tk_class = TkCore::INTERP._invoke('winfo', 'class', path) + tk_class = Tk.ip_invoke_without_enc('winfo', 'class', path) + rescue + return path + end + + if ruby_class = WidgetClassNames[tk_class] + ruby_class_name = ruby_class.name + # gen_class_name = ruby_class_name + 'GeneratedOnTk' + gen_class_name = ruby_class_name + classname_def = '' + else # ruby_class == nil + mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)} + mods.each{|mod| + begin + mod.const_get(tk_class) # auto_load + break if (ruby_class = WidgetClassNames[tk_class]) + rescue LoadError + # ignore load error + end + } + + unless ruby_class + std_class = 'Tk' << tk_class + if Object.const_defined?(std_class) + Object.const_get(std_class) # auto_load + ruby_class = WidgetClassNames[tk_class] + end + end + + if ruby_class + # found + ruby_class_name = ruby_class.name + gen_class_name = ruby_class_name + classname_def = '' + else + # unknown + ruby_class_name = 'TkWindow' + gen_class_name = 'TkWidget_' + tk_class + classname_def = "WidgetClassName = '#{tk_class}'.freeze" + end + end + +################################### +=begin + if ruby_class = WidgetClassNames[tk_class] + ruby_class_name = ruby_class.name + # gen_class_name = ruby_class_name + 'GeneratedOnTk' + gen_class_name = ruby_class_name + classname_def = '' + else + mod = TkExtlibAutoloadModule.find{|m| m.const_defined?(tk_class)} + if mod + ruby_class_name = mod.name + '::' + tk_class + gen_class_name = ruby_class_name + classname_def = '' + elsif Object.const_defined?('Tk' + tk_class) + ruby_class_name = 'Tk' + tk_class + # gen_class_name = ruby_class_name + 'GeneratedOnTk' + gen_class_name = ruby_class_name + classname_def = '' + else + ruby_class_name = 'TkWindow' + # gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk' + gen_class_name = 'TkWidget_' + tk_class + classname_def = "WidgetClassName = '#{tk_class}'.freeze" + end + end +=end + +=begin + unless Object.const_defined? gen_class_name + Object.class_eval "class #{gen_class_name}<#{ruby_class_name} + #{classname_def} + end" + end + Object.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', + 'without_creating'=>true)" +=end + base = Object + gen_class_name.split('::').each{|klass| + next if klass == '' + if base.const_defined?(klass) + base = base.class_eval klass + else + base = base.class_eval "class #{klass}<#{ruby_class_name} + #{classname_def} + end + #{klass}" + end + } + base.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', + 'without_creating'=>true)" + end + private :_genobj_for_tkwidget + module_function :_genobj_for_tkwidget + + def _at(x,y=nil) + if y + "@#{Integer(x)},#{Integer(y)}" + else + "@#{Integer(x)}" + end + end + module_function :_at + + def tk_tcl2ruby(val, enc_mode = false, listobj = true) +=begin + if val =~ /^rb_out\S* (c(_\d+_)?\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 +=end + if val =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ + return TkCore::INTERP.tk_cmd_tbl[$4] + end + #if val.include? ?\s + # return val.split.collect{|v| tk_tcl2ruby(v)} + #end + case val + when /\A@font\S+\z/ + TkFont.get_obj(val) + when /\A-?\d+\z/ + val.to_i + when /\A\.\S*\z/ + #Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) + TkCore::INTERP.tk_windows[val]? + TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val) + when /\Ai(_\d+_)?\d+\z/ + TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val + when /\A-?\d+\.?\d*(e[-+]?\d+)?\z/ + val.to_f + when /\\ / + val.gsub(/\\ /, ' ') + when /[^\\] / + if listobj + #tk_split_escstr(val).collect{|elt| + # tk_tcl2ruby(elt, enc_mode, listobj) + #} + val = _toUTF8(val) unless enc_mode + tk_split_escstr(val, false, false).collect{|elt| + tk_tcl2ruby(elt, true, listobj) + } + elsif enc_mode + _fromUTF8(val) + else + val + end + else + if enc_mode + _fromUTF8(val) + else + val + end + end + end + + private :tk_tcl2ruby + module_function :tk_tcl2ruby + #private_class_method :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, src_enc=true, dst_enc=true) + str = _toUTF8(str) if src_enc + if dst_enc + TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)} + else + TkCore::INTERP._split_tklist(str) + end + end + + def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true) + # return [] if str == "" + # list = TkCore::INTERP._split_tklist(str) + str = _toUTF8(str) if src_enc + + if depth == 0 + return "" if str == "" + list = [str] + else + return [] if str == "" + list = TkCore::INTERP._split_tklist(str) + end + if list.size == 1 + # tk_tcl2ruby(list[0], nil, false) + tk_tcl2ruby(list[0], dst_enc, false) + else + list.collect{|token| tk_split_sublist(token, depth - 1, false, dst_enc)} + end + end + + def tk_split_list(str, depth=0, src_enc=true, dst_enc=true) + return [] if str == "" + str = _toUTF8(str) if src_enc + TkCore::INTERP._split_tklist(str).map!{|token| + tk_split_sublist(token, depth - 1, false, dst_enc) + } + end + + def tk_split_simplelist(str, src_enc=true, dst_enc=true) + #lst = TkCore::INTERP._split_tklist(str) + #if (lst.size == 1 && lst =~ /^\{.*\}$/) + # TkCore::INTERP._split_tklist(str[1..-2]) + #else + # lst + #end + + str = _toUTF8(str) if src_enc + if dst_enc + TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)} + else + TkCore::INTERP._split_tklist(str) + end + end + + def array2tk_list(ary, enc=nil) + return "" if ary.size == 0 + + sys_enc = TkCore::INTERP.encoding + sys_enc = TclTkLib.encoding_system unless sys_enc + + dst_enc = (enc == nil)? sys_enc: enc + + dst = ary.collect{|e| + if e.kind_of? Array + s = array2tk_list(e, enc) + elsif e.kind_of? Hash + tmp_ary = [] + #e.each{|k,v| tmp_ary << k << v } + e.each{|k,v| tmp_ary << "-#{_get_eval_string(k)}" << v } + s = array2tk_list(tmp_ary, enc) + else + s = _get_eval_string(e, enc) + end + + if dst_enc != true && dst_enc != false + if (s_enc = s.instance_variable_get(:@encoding)) + s_enc = s_enc.to_s + else + s_enc = sys_enc + end + dst_enc = true if s_enc != dst_enc + end + + s + } + + if sys_enc && dst_enc + dst.map!{|s| _toUTF8(s)} + ret = TkCore::INTERP._merge_tklist(*dst) + if dst_enc.kind_of?(String) + ret = _fromUTF8(ret, dst_enc) + ret.instance_variable_set(:@encoding, dst_enc) + else + ret.instance_variable_set(:@encoding, 'utf-8') + end + ret + else + TkCore::INTERP._merge_tklist(*dst) + end + end + +else + ########################################################################### + # use Ruby script version of split_list (traditional methods) + ########################################################################### + + def tk_split_escstr(str, src_enc=true, dst_enc=true) + return [] if str == "" + list = [] + token = nil + escape = false + brace = 0 + str.split('').each {|c| + brace += 1 if c == '{' && !escape + brace -= 1 if c == '}' && !escape + if brace == 0 && c == ' ' && !escape + list << token.gsub(/^\{(.*)\}$/, '\1') if token + token = nil + else + token = (token || "") << c + end + escape = (c == '\\' && !escape) + } + list << token.gsub(/^\{(.*)\}$/, '\1') if token + list + end + + def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true) + #return [] if str == "" + #return [tk_split_sublist(str[1..-2])] if str =~ /^\{.*\}$/ + #list = tk_split_escstr(str) + if depth == 0 + return "" if str == "" + str = str[1..-2] if str =~ /^\{.*\}$/ + list = [str] + else + return [] if str == [] + return [tk_split_sublist(str[1..-2], depth - 1)] if str =~ /^\{.*\}$/ + list = tk_split_escstr(str) + end + if list.size == 1 + tk_tcl2ruby(list[0], nil, false) + else + list.collect{|token| tk_split_sublist(token, depth - 1)} + end + end + + def tk_split_list(str, depth=0, src_enc=true, dst_enc=true) + return [] if str == "" + tk_split_escstr(str).collect{|token| + tk_split_sublist(token, depth - 1) + } + end +=begin + def tk_split_list(str) + return [] if str == "" + idx = str.index('{') + while idx and idx > 0 and str[idx-1] == ?\\ + idx = str.index('{', idx+1) + end + unless idx + list = tk_tcl2ruby(str) + unless Array === list + list = [list] + end + return list + end + + list = tk_tcl2ruby(str[0,idx]) + list = [] if list == "" + 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 str.size == i + 1 + return tk_split_list(str[0, i]) + end + if str[0, i] == ' ' + list.push ' ' + else + list.push tk_split_list(str[0, i]) + end + list += tk_split_list(str[i+1..-1]) + list + end +=end + + def tk_split_simplelist(str, src_enc=true, dst_enc=true) + return [] if str == "" + list = [] + token = nil + escape = false + brace = 0 + str.split('').each {|c| + if c == '\\' && !escape + escape = true + token = (token || "") << c if brace > 0 + next + end + brace += 1 if c == '{' && !escape + brace -= 1 if c == '}' && !escape + if brace == 0 && c == ' ' && !escape + list << token.gsub(/^\{(.*)\}$/, '\1') if token + token = nil + else + token = (token || "") << c + end + escape = false + } + list << token.gsub(/^\{(.*)\}$/, '\1') if token + list + end + + def array2tk_list(ary, enc=nil) + ary.collect{|e| + if e.kind_of? Array + "{#{array2tk_list(e, enc)}}" + elsif e.kind_of? Hash + # "{#{e.to_a.collect{|ee| array2tk_list(ee)}.join(' ')}}" + e.each{|k,v| tmp_ary << "-#{_get_eval_string(k)}" << v } + array2tk_list(tmp_ary, enc) + else + s = _get_eval_string(e, enc) + (s.index(/\s/) || s.size == 0)? "{#{s}}": s + 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' + true + else + false + end + end + + def number(val) + case val + when /^-?\d+$/ + val.to_i + when /^-?\d+\.?\d*(e[-+]?\d+)?$/ + val.to_f + else + fail(ArgumentError, "invalid value for Number:'#{val}'") + end + end + def string(val) + if val == "{}" + '' + elsif val[0] == ?{ && val[-1] == ?} + val[1..-2] + else + val + end + end + def num_or_str(val) + begin + number(val) + rescue ArgumentError + string(val) + end + end +=end + + def list(val, depth=0, enc=true) + tk_split_list(val, depth, enc, enc) + end + def simplelist(val, src_enc=true, dst_enc=true) + tk_split_simplelist(val, src_enc, dst_enc) + end + def window(val) + if val =~ /^\./ + #Tk_WINDOWS[val]? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) + TkCore::INTERP.tk_windows[val]? + TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val) + else + nil + end + end + def image_obj(val) + if val =~ /^i(_\d+_)?\d+$/ + TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val + else + val + end + end + def procedure(val) +=begin + if val =~ /^rb_out\S* (c(_\d+_)?\d+)/ + #Tk_CMDTBL[$1] + #TkCore::INTERP.tk_cmd_tbl[$1] + TkCore::INTERP.tk_cmd_tbl[$1].cmd +=end + if val =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ + return TkCore::INTERP.tk_cmd_tbl[$4].cmd + else + #nil + val + end + end + private :bool, :number, :string, :num_or_str + private :list, :simplelist, :window, :procedure + module_function :bool, :number, :num_or_str, :string + module_function :list, :simplelist, :window, :image_obj, :procedure + + def subst(str, *opts) + # opts := :nobackslashes | :nocommands | novariables + tk_call('subst', + *(opts.collect{|opt| + opt = opt.to_s + (opt[0] == ?-)? opt: '-' << opt + } << str)) + end + + 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 + + def _callback_entry_class?(cls) + cls <= Proc || cls <= Method || cls <= TkCallbackEntry + end + private :_callback_entry_class? + module_function :_callback_entry_class? + + def _callback_entry?(obj) + obj.kind_of?(Proc) || obj.kind_of?(Method) || obj.kind_of?(TkCallbackEntry) + end + private :_callback_entry? + module_function :_callback_entry? + +=begin + ### --> definition is moved to TkUtil module + def _get_eval_string(str, enc_mode = nil) + return nil if str == None + 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, 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 + str = "" + elsif str == false + str = "0" + elsif str == true + 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 = _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 + +=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, enc_mode)} + else + _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]) + id = "c" + TkCore::INTERP._ip_id_ + TkComm::Tk_IDs[0] + end + def _next_cmd_id + id = _curr_cmd_id + #Tk_IDs[0] += 1 + TkComm::Tk_IDs[0].succ! + id + end + private :_curr_cmd_id, :_next_cmd_id + module_function :_curr_cmd_id, :_next_cmd_id + + def install_cmd(cmd) + return '' if cmd == '' + begin + ns = TkCore::INTERP._invoke_without_enc('namespace', 'current') + ns = nil if ns == '::' # for backward compatibility + rescue + # probably, Tcl7.6 + ns = nil + end + id = _next_cmd_id + #Tk_CMDTBL[id] = 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); + if ns + 'rb_out' << TkCore::INTERP._ip_id_ << ' ' << ns << ' ' << id + else + 'rb_out' << TkCore::INTERP._ip_id_ << ' ' << id + end + end + def uninstall_cmd(id) + #id = $1 if /rb_out\S* (c(_\d+_)?\d+)/ =~ id + id = $4 if id =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ + #Tk_CMDTBL.delete(id) + TkCore::INTERP.tk_cmd_tbl.delete(id) + end + # 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]) + #Tk_IDs[1] += 1 + name = "w" + Tk_IDs[1] + Tk_IDs[1].succ! + end + if name[0] == ?. + @path = name.dup + elsif !ppath or ppath == "." + @path = Kernel.format(".%s", name); + else + @path = Kernel.format("%s.%s", ppath, name) + end + #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" + TkCore::INTERP._ip_id_ + 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) + TkCore::INTERP.tk_windows.delete(@path) + end + private :install_win, :uninstall_win + + def _epath(win) + if win.kind_of?(TkObject) + win.epath + elsif win.respond_to?(:epath) + win.epath + else + 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 + context = context.path + end + if context.kind_of? Array + context = context.collect{|ev| + if ev.kind_of? TkVirtualEvent + ev.path + else + ev + end + }.join("><") + end + if /,/ =~ context + context = context.split(/\s*,\s*/).join("><") + else + context + end + end + + def _bind_core(mode, what, context, cmd, *args) + id = install_bind(cmd, *args) if cmd + begin + tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", + mode + id])) + rescue + uninstall_cmd(id) if cmd + fail + end + end + + def _bind(what, context, cmd, *args) + _bind_core('', what, context, cmd, *args) + end + + def _bind_append(what, context, cmd, *args) + _bind_core('+', what, context, cmd, *args) + end + + def _bind_remove(what, context) + tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", ''])) + end + + def _bindinfo(what, context=nil) + if context + tk_call_without_enc(*what+["<#{tk_event_sequence(context)}>"]) .collect {|cmdline| +=begin + if cmdline =~ /^rb_out\S* (c(?:_\d+_)?\d+)\s+(.*)$/ + #[Tk_CMDTBL[$1], $2] + [TkCore::INTERP.tk_cmd_tbl[$1], $2] +=end + if cmdline =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ + [TkCore::INTERP.tk_cmd_tbl[$4], $5] + else + cmdline + end + } + else + tk_split_simplelist(tk_call_without_enc(*what)).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 + + def _bind_core_for_event_class(klass, mode, what, context, cmd, *args) + id = install_bind_for_event_class(klass, cmd, *args) if cmd + begin + tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", + mode + id])) + rescue + uninstall_cmd(id) if cmd + fail + end + end + + def _bind_for_event_class(klass, what, context, cmd, *args) + _bind_core_for_event_class(klass, '', what, context, cmd, *args) + end + + def _bind_append_for_event_class(klass, what, context, cmd, *args) + _bind_core_for_event_class(klass, '+', what, context, cmd, *args) + end + + def _bind_remove_for_event_class(klass, what, context) + _bind_remove(what, context) + end + + def _bindinfo_for_event_class(klass, what, context=nil) + _bindinfo(what, context) + end + + private :tk_event_sequence + private :_bind_core, :_bind, :_bind_append, :_bind_remove, :_bindinfo + private :_bind_core_for_event_class, :_bind_for_event_class, + :_bind_append_for_event_class, :_bind_remove_for_event_class, + :_bindinfo_for_event_class + + #def bind(tagOrClass, context, cmd=Proc.new, *args) + # _bind(["bind", tagOrClass], context, cmd, *args) + # tagOrClass + #end + def bind(tagOrClass, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind(["bind", tagOrClass], context, cmd, *args) + tagOrClass + end + + #def bind_append(tagOrClass, context, cmd=Proc.new, *args) + # _bind_append(["bind", tagOrClass], context, cmd, *args) + # tagOrClass + #end + def bind_append(tagOrClass, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append(["bind", tagOrClass], context, cmd, *args) + tagOrClass + end + + def bind_remove(tagOrClass, context) + _bind_remove(['bind', tagOrClass], context) + tagOrClass + end + + def bindinfo(tagOrClass, context=nil) + _bindinfo(['bind', tagOrClass], context) + end + + #def bind_all(context, cmd=Proc.new, *args) + # _bind(['bind', 'all'], context, cmd, *args) + # TkBindTag::ALL + #end + def bind_all(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind(['bind', 'all'], context, cmd, *args) + TkBindTag::ALL + end + + #def bind_append_all(context, cmd=Proc.new, *args) + # _bind_append(['bind', 'all'], context, cmd, *args) + # TkBindTag::ALL + #end + def bind_append_all(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append(['bind', 'all'], context, cmd, *args) + TkBindTag::ALL + end + + def bind_remove_all(context) + _bind_remove(['bind', 'all'], context) + TkBindTag::ALL + end + + def bindinfo_all(context=nil) + _bindinfo(['bind', 'all'], context) + end +end + + +module TkCore + include TkComm + extend TkComm + + unless self.const_defined? :INTERP + if self.const_defined? :IP_NAME + name = IP_NAME.to_s + else + #name = nil + name = $0 + end + if self.const_defined? :IP_OPTS + if IP_OPTS.kind_of?(Hash) + opts = hash_kv(IP_OPTS).join(' ') + else + opts = IP_OPTS.to_s + end + else + opts = '' + end + + INTERP = TclTkIp.new(name, opts) + + def INTERP.__getip + self + end + + INTERP.instance_eval{ + @tk_cmd_tbl = {}.taint + def @tk_cmd_tbl.[]=(idx,val) + if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default + fail SecurityError,"cannot change the entried command" + end + super(idx,val) + end + + @tk_windows = {}.taint + + @tk_table_list = [].taint + + @init_ip_env = [].taint # table of Procs + @add_tk_procs = [].taint # table of [name, args, body] + + @cb_entry_class = Class.new(TkCallbackEntry){ + class << self + def inspect + sprintf("#<Class(TkCallbackEntry):%0x>", self.__id__) + end + alias to_s inspect + end + + def initialize(ip, cmd) + @ip = ip + @cmd = cmd + end + attr_reader :ip, :cmd + def call(*args) + @ip.cb_eval(@cmd, *args) + end + def inspect + sprintf("#<cb_entry:%0x>", 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 + def INTERP.tk_windows + @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 + def INTERP.create_table + 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 + 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) + TkUtil._get_eval_string(TkUtil.eval_cmd(cmd, *args)) + end + + def INTERP.init_ip_env(script = Proc.new) + @init_ip_env << script + script.call(self) + end + def INTERP.add_tk_procs(name, args = nil, body = nil) + if name.kind_of?(Array) + name.each{|param| self.add_tk_procs(*param)} + else + name = name.to_s + @add_tk_procs << [name, args, body] + self._invoke('proc', name, args, body) if args && body + end + end + def INTERP.remove_tk_procs(*names) + names.each{|name| + name = name.to_s + @add_tk_procs.delete_if{|elem| + elem.kind_of?(Array) && elem[0].to_s == name + } + self._invoke('rename', name, '') + } + end + def INTERP.init_ip_internal + ip = self + @init_ip_env.each{|script| script.call(ip)} + @add_tk_procs.each{|name,args,body| ip._invoke('proc',name,args,body)} + end + end + + WIDGET_DESTROY_HOOK = '<WIDGET_DESTROY_HOOK>' + INTERP._invoke_without_enc('event', 'add', + "<#{WIDGET_DESTROY_HOOK}>", '<Destroy>') + INTERP._invoke_without_enc('bind', 'all', "<#{WIDGET_DESTROY_HOOK}>", + install_cmd(proc{|path| + unless TkCore::INTERP.deleted? + begin + if (widget=TkCore::INTERP.tk_windows[path]) + if widget.respond_to?(:__destroy_hook__) + widget.__destroy_hook__ + end + end + rescue Exception=>e + p e if $DEBUG + end + end + }) << ' %W') + + INTERP.add_tk_procs(TclTkLib::FINALIZE_PROC_NAME, '', + "bind all <#{WIDGET_DESTROY_HOOK}> {}") + + INTERP.add_tk_procs('rb_out', 'ns args', <<-'EOL') + if [regexp {^::} $ns] { + set cmd {namespace eval $ns {ruby_cmd TkCore callback} $args} + } else { + set cmd {eval {ruby_cmd TkCore callback} $ns $args} + } + if {[set st [catch $cmd 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') + 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 +=end +=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 + + at_exit{ INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) } + + EventFlag = TclTkLib::EventFlag + + def callback_break + fail TkCallbackBreak, "Tk callback returns 'break' status" + end + + def callback_continue + fail TkCallbackContinue, "Tk callback returns 'continue' status" + end + + def callback_return + fail TkCallbackReturn, "Tk callback returns 'return' status" + end + + def TkCore.callback(*arg) + begin + if TkCore::INTERP.tk_cmd_tbl.kind_of?(Hash) + #TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) + normal_ret = false + ret = catch(:IRB_EXIT) do # IRB hack + retval = TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) + normal_ret = true + retval + end + unless normal_ret + # catch IRB_EXIT + exit(ret) + end + ret + end + rescue SystemExit=>e + exit(e.status) + rescue Interrupt=>e + fail(e) + 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 + # TkCore::INTERP._set_global_var('errorInfo', msg) + # fail(e) + 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)) + # 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)) + end + + def after(ms, cmd=Proc.new) + crit_bup = Thread.critical + Thread.critical = true + + myid = _curr_cmd_id + cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret}) + + Thread.critical = crit_bup + + tk_call_without_enc("after",ms,cmdid) # return id +# return +# if false #defined? Thread +# Thread.start do +# ms = Float(ms)/1000 +# ms = 10 if ms == 0 +# sleep ms/1000 +# cmd.call +# end +# else +# cmdid = install_cmd(cmd) +# tk_call("after",ms,cmdid) +# end + end + + def after_idle(cmd=Proc.new) + crit_bup = Thread.critical + Thread.critical = true + + myid = _curr_cmd_id + cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret}) + + Thread.critical = crit_bup + + tk_call_without_enc('after','idle',cmdid) + end + + def after_cancel(afterId) + tk_call_without_enc('after','cancel',afterId) + end + + def windowingsystem + tk_call_without_enc('tk', 'windowingsystem') + end + + def scaling(scale=nil) + if scale + tk_call_without_enc('tk', 'scaling', scale) + else + Float(number(tk_call_without_enc('tk', 'scaling'))) + end + end + def scaling_displayof(win, scale=nil) + if scale + tk_call_without_enc('tk', 'scaling', '-displayof', win, scale) + else + Float(number(tk_call_without_enc('tk', '-displayof', win, 'scaling'))) + end + end + + def inactive + Integer(tk_call_without_enc('tk', 'inactive')) + end + def inactive_displayof(win) + Integer(tk_call_without_enc('tk', 'inactive', '-displayof', win)) + end + def reset_inactive + tk_call_without_enc('tk', 'inactive', 'reset') + end + def reset_inactive_displayof(win) + tk_call_without_enc('tk', 'inactive', '-displayof', win, 'reset') + end + + def appname(name=None) + tk_call('tk', 'appname', name) + end + + def appsend_deny + tk_call('rename', 'send', '') + end + + def appsend(interp, async, *args) + if $SAFE >= 4 + fail SecurityError, "cannot send Tk commands at level 4" + elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} + fail SecurityError, "cannot send tainted Tk commands at level #{$SAFE}" + end + if async != true && async != false && async != nil + args.unshift(async) + async = false + end + if async + tk_call('send', '-async', '--', interp, *args) + else + tk_call('send', '--', interp, *args) + end + end + + def rb_appsend(interp, async, *args) + if $SAFE >= 4 + fail SecurityError, "cannot send Ruby commands at level 4" + elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} + fail SecurityError, "cannot send tainted Ruby commands at level #{$SAFE}" + end + if async != true && async != false && async != nil + args.unshift(async) + async = false + end + #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} + args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')} + # args.push(').to_s"') + # appsend(interp, async, 'ruby "(', *args) + args.push('}.call)"') + appsend(interp, async, 'ruby "TkComm._get_eval_string(proc{', *args) + end + + def appsend_displayof(interp, win, async, *args) + if $SAFE >= 4 + fail SecurityError, "cannot send Tk commands at level 4" + elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} + fail SecurityError, "cannot send tainted Tk commands at level #{$SAFE}" + end + win = '.' if win == nil + if async != true && async != false && async != nil + args.unshift(async) + async = false + end + if async + tk_call('send', '-async', '-displayof', win, '--', interp, *args) + else + tk_call('send', '-displayor', win, '--', interp, *args) + end + end + + def rb_appsend_displayof(interp, win, async, *args) + if $SAFE >= 4 + fail SecurityError, "cannot send Ruby commands at level 4" + elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} + fail SecurityError, "cannot send tainted Ruby commands at level #{$SAFE}" + end + win = '.' if win == nil + if async != true && async != false && async != nil + args.unshift(async) + async = false + end + #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} + args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')} + # args.push(').to_s"') + # appsend_displayof(interp, win, async, 'ruby "(', *args) + args.push('}.call)"') + appsend(interp, win, async, 'ruby "TkComm._get_eval_string(proc{', *args) + end + + def info(*args) + tk_call('info', *args) + end + + def mainloop(check_root = true) + TclTkLib.mainloop(check_root) + end + + def mainloop_thread? + # true : current thread is mainloop + # nil : there is no mainloop + # false : mainloop is running on the other thread + # ( At then, it is dangerous to call Tk interpreter directly. ) + TclTkLib.mainloop_thread? + end + + def mainloop_exist? + TclTkLib.mainloop_thread? != nil + end + + def is_mainloop? + TclTkLib.mainloop_thread? == true + end + + def mainloop_watchdog(check_root = true) + # watchdog restarts mainloop when mainloop is dead + TclTkLib.mainloop_watchdog(check_root) + end + + def do_one_event(flag = TclTkLib::EventFlag::ALL) + TclTkLib.do_one_event(flag) + end + + def set_eventloop_tick(timer_tick) + TclTkLib.set_eventloop_tick(timer_tick) + end + + def get_eventloop_tick() + TclTkLib.get_eventloop_tick + end + + def set_no_event_wait(wait) + TclTkLib.set_no_even_wait(wait) + end + + def get_no_event_wait() + TclTkLib.get_no_eventloop_wait + end + + def set_eventloop_weight(loop_max, no_event_tick) + TclTkLib.set_eventloop_weight(loop_max, no_event_tick) + end + + def get_eventloop_weight() + TclTkLib.get_eventloop_weight + end + + def restart(app_name = nil, keys = {}) + TkCore::INTERP.init_ip_internal + + tk_call('set', 'argv0', app_name) if app_name + if keys.kind_of?(Hash) + # tk_call('set', 'argc', keys.size * 2) + tk_call('set', 'argv', hash_kv(keys).join(' ')) + end + + INTERP.restart + nil + end + + def event_generate(win, context, keys=nil) + #win = win.path if win.kind_of?(TkObject) + if context.kind_of?(TkEvent::Event) + context.generate(win, ((keys)? keys: {})) + elsif keys + tk_call_without_enc('event', 'generate', win, + "<#{tk_event_sequence(context)}>", + *hash_kv(keys, true)) + else + tk_call_without_enc('event', 'generate', win, + "<#{tk_event_sequence(context)}>") + end + nil + end + + def messageBox(keys) + tk_call('tk_messageBox', *hash_kv(keys)) + end + + def getOpenFile(keys = nil) + tk_call('tk_getOpenFile', *hash_kv(keys)) + end + def getMultipleOpenFile(keys = nil) + simplelist(tk_call('tk_getOpenFile', '-multiple', '1', *hash_kv(keys))) + end + + def getSaveFile(keys = nil) + tk_call('tk_getSaveFile', *hash_kv(keys)) + end + def getMultipleSaveFile(keys = nil) + simplelist(tk_call('tk_getSaveFile', '-multiple', '1', *hash_kv(keys))) + end + + def chooseColor(keys = nil) + tk_call('tk_chooseColor', *hash_kv(keys)) + end + + def chooseDirectory(keys = nil) + 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) + _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) + _ip_invoke_core(nil, *args) + end + + 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(enc_mode, *args) + res = _ip_invoke_core(enc_mode, *args) + # >>>>> _invoke returns a TAINTED string <<<<< + rescue NameError => err + # err = $! + begin + args.unshift "unknown" + #res = INTERP._invoke(*args).taint + #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.message + fail err + end + end + if INTERP._return_value() != 0 + fail RuntimeError, res, error_at + end + ### print "==> ", res.inspect, "\n" if $DEBUG + return res + end + private :_tk_call_core + + def tk_call(*args) + _tk_call_core(nil, *args) + end + + def tk_call_without_enc(*args) + _tk_call_core(false, *args) + end + + def tk_call_with_enc(*args) + _tk_call_core(true, *args) + end + + def _tk_call_to_list_core(depth, arg_enc, val_enc, *args) + args = _conv_args([], arg_enc, *args) + val = _tk_call_core(false, *args) + if !depth.kind_of?(Integer) || depth == 0 + tk_split_simplelist(val, false, val_enc) + else + tk_split_list(val, depth, false, val_enc) + end + end + #private :_tk_call_to_list_core + + def tk_call_to_list(*args) + _tk_call_to_list_core(-1, nil, true, *args) + end + + def tk_call_to_list_without_enc(*args) + _tk_call_to_list_core(-1, false, false, *args) + end + + def tk_call_to_list_with_enc(*args) + _tk_call_to_list_core(-1, true, true, *args) + end + + def tk_call_to_simplelist(*args) + _tk_call_to_list_core(0, nil, true, *args) + end + + def tk_call_to_simplelist_without_enc(*args) + _tk_call_to_list_core(0, false, false, *args) + end + + def tk_call_to_simplelist_with_enc(*args) + _tk_call_to_list_core(0, true, true, *args) + end +end + + +module Tk + include TkCore + extend Tk + + TCL_VERSION = INTERP._invoke_without_enc("info", "tclversion").freeze + TCL_PATCHLEVEL = INTERP._invoke_without_enc("info", "patchlevel").freeze + + major, minor = TCL_VERSION.split('.') + TCL_MAJOR_VERSION = major.to_i + TCL_MINOR_VERSION = minor.to_i + + TK_VERSION = INTERP._invoke_without_enc("set", "tk_version").freeze + TK_PATCHLEVEL = INTERP._invoke_without_enc("set", "tk_patchLevel").freeze + + major, minor = TK_VERSION.split('.') + TK_MAJOR_VERSION = major.to_i + TK_MINOR_VERSION = minor.to_i + + JAPANIZED_TK = (INTERP._invoke_without_enc("info", "commands", + "kanji") != "").freeze + + def Tk.const_missing(sym) + case(sym) + when :TCL_LIBRARY + INTERP._invoke_without_enc('global', 'tcl_library') + INTERP._invoke("set", "tcl_library").freeze + + when :TK_LIBRARY + INTERP._invoke_without_enc('global', 'tk_library') + INTERP._invoke("set", "tk_library").freeze + + when :LIBRARY + INTERP._invoke("info", "library").freeze + + #when :PKG_PATH, :PACKAGE_PATH, :TCL_PACKAGE_PATH + # INTERP._invoke_without_enc('global', 'tcl_pkgPath') + # tk_split_simplelist(INTERP._invoke('set', 'tcl_pkgPath')) + + #when :LIB_PATH, :LIBRARY_PATH, :TCL_LIBRARY_PATH + # INTERP._invoke_without_enc('global', 'tcl_libPath') + # tk_split_simplelist(INTERP._invoke('set', 'tcl_libPath')) + + when :PLATFORM, :TCL_PLATFORM + if $SAFE >= 4 + fail SecurityError, "can't get #{sym} when $SAFE >= 4" + end + INTERP._invoke_without_enc('global', 'tcl_platform') + Hash[*tk_split_simplelist(INTERP._invoke_without_enc('array', 'get', + 'tcl_platform'))] + + when :ENV + INTERP._invoke_without_enc('global', 'env') + Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'env'))] + + #when :AUTO_PATH #<=== + # tk_split_simplelist(INTERP._invoke('set', 'auto_path')) + + #when :AUTO_OLDPATH + # tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath')) + + when :AUTO_INDEX + INTERP._invoke_without_enc('global', 'auto_index') + Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'auto_index'))] + + when :PRIV, :PRIVATE, :TK_PRIV + priv = {} + if INTERP._invoke_without_enc('info', 'vars', 'tk::Priv') != "" + var_nam = 'tk::Priv' + else + var_nam = 'tkPriv' + end + INTERP._invoke_without_enc('global', var_nam) + Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', + var_nam))].each{|k,v| + k.freeze + case v + when /^-?\d+$/ + priv[k] = v.to_i + when /^-?\d+\.?\d*(e[-+]?\d+)?$/ + priv[k] = v.to_f + else + priv[k] = v.freeze + end + } + priv + + else + raise NameError, 'uninitialized constant Tk::' + sym.id2name + end + end + + def Tk.errorInfo + INTERP._invoke_without_enc('global', 'errorInfo') + INTERP._invoke_without_enc('set', 'errorInfo') + end + + def Tk.errorCode + INTERP._invoke_without_enc('global', 'errorCode') + code = tk_split_simplelist(INTERP._invoke_without_enc('set', 'errorCode')) + case code[0] + when 'CHILDKILLED', 'CHILDSTATUS', 'CHILDSUSP' + begin + pid = Integer(code[1]) + code[1] = pid + rescue + end + end + code + end + + def Tk.has_mainwindow? + INTERP.has_mainwindow? + end + + def root + 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.pkgconfig_list(mod) + # Tk8.5 feature + if mod.kind_of?(Module) + if mod.respond_to?(:package_name) + pkgname = mod.package_name + elsif mod.const_defined?(:PACKAGE_NAME) + pkgname = mod::PACKAGE_NAME + else + fail NotImplementedError, 'may not be a module for a Tcl extension' + end + else + pkgname = mod.to_s + end + + pkgname = '::' << pkgname unless pkgname =~ /^::/ + + tk_split_list(tk_call(pkgname + '::pkgconfig', 'list')) + end + + def Tk.pkgconfig_get(mod, key) + # Tk8.5 feature + if mod.kind_of?(Module) + if mod.respond_to?(:package_name) + pkgname = mod.package_name + else + fail NotImplementedError, 'may not be a module for a Tcl extension' + end + else + pkgname = mod.to_s + end + + pkgname = '::' << pkgname unless pkgname =~ /^::/ + + tk_call(pkgname + '::pkgconfig', 'get', key) + end + + def Tk.tcl_pkgconfig_list + # Tk8.5 feature + Tk.pkgconfig_list('::tcl') + end + + def Tk.tcl_pkgconfig_get(key) + # Tk8.5 feature + Tk.pkgconfig_get('::tcl', key) + end + + def Tk.tk_pkgconfig_list + # Tk8.5 feature + Tk.pkgconfig_list('::tk') + end + + def Tk.tk_pkgconfig_get(key) + # Tk8.5 feature + Tk.pkgconfig_get('::tk', key) + end + + def Tk.bell(nice = false) + if nice + tk_call_without_enc('bell', '-nice') + else + tk_call_without_enc('bell') + end + nil + end + + def Tk.bell_on_display(win, nice = false) + if nice + tk_call_without_enc('bell', '-displayof', win, '-nice') + else + tk_call_without_enc('bell', '-displayof', win) + end + nil + end + + def Tk.destroy(*wins) + #tk_call_without_enc('destroy', *wins) + tk_call_without_enc('destroy', *(wins.collect{|win| + if win.kind_of?(TkWindow) + win.epath + else + win + end + })) + end + + def Tk.exit + tk_call_without_enc('destroy', '.') + end + + def Tk.pack(*args) + TkPack.configure(*args) + end + def Tk.pack_forget(*args) + TkPack.forget(*args) + end + def Tk.unpack(*args) + TkPack.forget(*args) + end + + def Tk.grid(*args) + TkGrid.configure(*args) + end + def Tk.grid_forget(*args) + TkGrid.forget(*args) + end + def Tk.ungrid(*args) + TkGrid.forget(*args) + end + + def Tk.place(*args) + TkPlace.configure(*args) + end + def Tk.place_forget(*args) + TkPlace.forget(*args) + end + def Tk.unplace(*args) + TkPlace.forget(*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 + def update(idle=nil) + # only for backward compatibility (This never be recommended to use) + Tk.update(idle) + self + end + + # NOTE:: + # If no eventloop-thread is running, "thread_update" method is same + # to "update" method. Else, "thread_update" method waits to complete + # idletask operation on the eventloop-thread. + 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 + + def Tk.lower_window(win, below=None) + tk_call('lower', _epath(win), _epath(below)) + nil + end + def Tk.raise_window(win, above=None) + tk_call('raise', _epath(win), _epath(above)) + nil + 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_without_enc('focus')) + else + 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_without_enc('focus', '-lastfor', win)) + end + + def Tk.focus_next(win) + TkManageFocus.next(win) + end + + def Tk.focus_prev(win) + TkManageFocus.prev(win) + end + + def Tk.strictMotif(mode=None) + bool(tk_call_without_enc('set', 'tk_strictMotif', mode)) + end + + def Tk.show_kinsoku(mode='both') + begin + if /^8\.*/ === TK_VERSION && JAPANIZED_TK + tk_split_simplelist(tk_call('kinsoku', 'show', mode)) + end + rescue + end + end + def Tk.add_kinsoku(chars, mode='both') + begin + if /^8\.*/ === TK_VERSION && JAPANIZED_TK + tk_split_simplelist(tk_call('kinsoku', 'add', mode, + *(chars.split('')))) + else + [] + end + rescue + [] + end + end + def Tk.delete_kinsoku(chars, mode='both') + begin + if /^8\.*/ === TK_VERSION && JAPANIZED_TK + tk_split_simplelist(tk_call('kinsoku', 'delete', mode, + *(chars.split('')))) + end + rescue + end + end + + def Tk.toUTF8(str, encoding = nil) + _toUTF8(str, encoding) + end + + def Tk.fromUTF8(str, encoding = nil) + _fromUTF8(str, encoding) + end +end + +########################################### +# string with Tcl's encoding +########################################### +module Tk + def Tk.subst_utf_backslash(str) + Tk::EncodedString.subst_utf_backslash(str) + end + def Tk.subst_tk_backslash(str) + Tk::EncodedString.subst_tk_backslash(str) + end + def Tk.utf_to_backslash_sequence(str) + Tk::EncodedString.utf_to_backslash_sequence(str) + end + 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 + + +########################################### +# convert kanji string to/from utf-8 +########################################### +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 + + 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 + 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) + end + end + + def _invoke(*cmds) + if defined?(@encoding) && @encoding != 'utf-8' + cmds = cmds.collect{|cmd| + if cmd.kind_of?(Tk::EncodedString) + 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 + } + 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 TclTkLib + class << self + alias _encoding encoding + alias _encoding= encoding= + def encoding=(name) + TkCore::INTERP.encoding = name + end + def encoding + TkCore::INTERP.encoding + end + end + end + + module Tk + module Encoding + extend Encoding + + TkCommandNames = ['encoding'.freeze].freeze + + def encoding=(name) + TkCore::INTERP.encoding = name + end + + def encoding + TkCore::INTERP.encoding + end + + def encoding_names + TkComm.simplelist(Tk.tk_call('encoding', 'names')) + end + + def encoding_system + Tk.tk_call('encoding', 'system') + end + + def encoding_system=(enc) + Tk.tk_call('encoding', 'system', enc) + end + + def encoding_convertfrom(str, enc=nil) + # str is an usual enc string or a Tcl's internal string expression + # in enc (which is returned from 'encoding_convertto' method). + # the return value is a UTF-8 string. + enc = encoding_system unless enc + ret = TkCore::INTERP.__invoke('encoding', 'convertfrom', enc, str) + ret.instance_variable_set('@encoding', 'utf-8') + ret + end + alias encoding_convert_from encoding_convertfrom + + def encoding_convertto(str, enc=nil) + # str must be a UTF-8 string. + # The return value is a Tcl's internal string expression in enc. + # To get an usual enc string, use Tk.fromUTF8(ret_val, enc). + enc = encoding_system unless enc + ret = TkCore::INTERP.__invoke('encoding', 'convertto', enc, str) + ret.instance_variable_set('@encoding', 'binary') + ret + end + alias encoding_convert_to encoding_convertto + + def encoding_dirs + # Tcl8.5 feature + TkComm.simplelist(Tk.tk_call_without_enc('encoding', 'dirs')) + end + + def encoding_dirs=(dir_list) # an array or a Tcl's list string + # Tcl8.5 feature + Tk.tk_call_without_enc('encoding', 'dirs', dir_list) + end + end + + extend Encoding + end + + # estimate encoding + case $KCODE + when /^e/i # EUC + Tk.encoding = 'euc-jp' + Tk.encoding_system = 'euc-jp' + when /^s/i # SJIS + begin + if Tk.encoding_system == 'cp932' + Tk.encoding = 'cp932' + else + Tk.encoding = 'shiftjis' + Tk.encoding_system = 'shiftjis' + end + rescue StandardError, NameError + Tk.encoding = 'shiftjis' + Tk.encoding_system = 'shiftjis' + end + when /^u/i # UTF8 + Tk.encoding = 'utf-8' + Tk.encoding_system = 'utf-8' + else # NONE + if defined? DEFAULT_TK_ENCODING + Tk.encoding_system = DEFAULT_TK_ENCODING + end + begin + Tk.encoding = Tk.encoding_system + rescue StandardError, NameError + Tk.encoding = 'utf-8' + Tk.encoding_system = 'utf-8' + end + end + +else + # dummy methods + class TclTkIp + attr_accessor :encoding + + alias __eval _eval + alias __invoke _invoke + + alias _eval_with_enc _eval + alias _invoke_with_enc _invoke + end + + module Tk + module Encoding + extend Encoding + + def encoding=(name) + nil + end + def encoding + nil + end + def encoding_names + nil + end + def encoding_system + nil + end + def encoding_system=(enc) + nil + end + + def encoding_convertfrom(str, enc=None) + str + end + alias encoding_convert_from encoding_convertfrom + + def encoding_convertto(str, enc=None) + str + end + alias encoding_convert_to encoding_convertto + def encoding_dirs + nil + end + def encoding_dirs=(dir_array) + nil + end + end + + extend Encoding + end +end + + +module TkBindCore + #def bind(context, cmd=Proc.new, *args) + # Tk.bind(self, context, cmd, *args) + #end + def bind(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + Tk.bind(self, context, cmd, *args) + end + + #def bind_append(context, cmd=Proc.new, *args) + # Tk.bind_append(self, context, cmd, *args) + #end + def bind_append(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + 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 + + +module TkTreatFont + def __font_optkeys + ['font'] + end + private :__font_optkeys + + def __pathname + self.path + end + private :__pathname + + ################################ + + def font_configinfo(key = nil) + optkeys = __font_optkeys + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __pathname.split(':') + + if key + pathname = [win, tag, key].join(';') + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, *__confinfo_cmd) + elsif optkeys.size == 1 + pathname = [win, tag, optkeys[0]].join(';') + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, *__confinfo_cmd) + else + fonts = {} + optkeys.each{|key| + key = key.to_s + pathname = [win, tag, key].join(';') + fonts[key] = + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, *__confinfo_cmd) + } + fonts + end + end + alias fontobj font_configinfo + + def font_configure(slot) + pathname = __pathname + + slot = _symbolkey2str(slot) + + __font_optkeys.each{|optkey| + optkey = optkey.to_s + l_optkey = 'latin' << optkey + a_optkey = 'ascii' << optkey + k_optkey = 'kanji' << optkey + + if slot.key?(optkey) + fnt = slot.delete(optkey) + if fnt.kind_of?(TkFont) + slot.delete(l_optkey) + slot.delete(a_optkey) + slot.delete(k_optkey) + + fnt.call_font_configure([pathname, optkey], *(__config_cmd << {})) + next + else + if fnt + if (slot.key?(l_optkey) || + slot.key?(a_optkey) || + slot.key?(k_optkey)) + fnt = TkFont.new(fnt) + + lfnt = slot.delete(l_optkey) + lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) + kfnt = slot.delete(k_optkey) + + fnt.latin_replace(lfnt) if lfnt + fnt.kanji_replace(kfnt) if kfnt + + fnt.call_font_configure([pathname, optkey], + *(__config_cmd << {})) + next + else + fnt = hash_kv(fnt) if fnt.kind_of?(Hash) + tk_call(*(__config_cmd << "-#{optkey}" << fnt)) + end + end + next + end + end + + lfnt = slot.delete(l_optkey) + lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) + kfnt = slot.delete(k_optkey) + + if lfnt && kfnt + TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], + *(__config_cmd << {})) + elsif lfnt + latinfont_configure([lfnt, optkey]) + elsif kfnt + kanjifont_configure([kfnt, optkey]) + end + } + + # configure other (without font) options + tk_call(*(__config_cmd.concat(hash_kv(slot)))) if slot != {} + self + end + + def latinfont_configure(ltn, keys=nil) + if ltn.kind_of?(Array) + key = ltn[1] + ltn = ltn[0] + else + key = nil + end + + optkeys = __font_optkeys + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __pathname.split(':') + + optkeys = [key] if key + + optkeys.each{|optkey| + optkey = optkey.to_s + + pathname = [win, tag, optkey].join(';') + + if (fobj = TkFont.used_on(pathname)) + fobj = TkFont.new(fobj) # create a new TkFont object + elsif Tk::JAPANIZED_TK + fobj = fontobj # create a new TkFont object + else + ltn = hash_kv(ltn) if ltn.kind_of?(Hash) + tk_call(*(__config_cmd << "-#{optkey}" << ltn)) + next + 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 + + fobj.call_font_configure([pathname, optkey], *(__config_cmd << {})) + } + self + end + alias asciifont_configure latinfont_configure + + def kanjifont_configure(knj, keys=nil) + if knj.kind_of?(Array) + key = knj[1] + knj = knj[0] + else + key = nil + end + + optkeys = __font_optkeys + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __pathname.split(':') + + optkeys = [key] if key + + optkeys.each{|optkey| + optkey = optkey.to_s + + pathname = [win, tag, optkey].join(';') + + if (fobj = TkFont.used_on(pathname)) + fobj = TkFont.new(fobj) # create a new TkFont object + elsif Tk::JAPANIZED_TK + fobj = fontobj # create a new TkFont object + else + knj = hash_kv(knj) if knj.kind_of?(Hash) + tk_call(*(__config_cmd << "-#{optkey}" << knj)) + next + 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 + + fobj.call_font_configure([pathname, optkey], *(__config_cmd << {})) + } + self + end + + def font_copy(win, wintag=nil, winkey=nil, targetkey=nil) + if wintag + if winkey + fnt = win.tagfontobj(wintag, winkey).dup + else + fnt = win.tagfontobj(wintag).dup + end + else + if winkey + fnt = win.fontobj(winkey).dup + else + fnt = win.fontobj.dup + end + end + + if targetkey + fnt.call_font_configure([__pathname, targetkey], *(__config_cmd << {})) + else + fnt.call_font_configure(__pathname, *(__config_cmd << {})) + end + self + end + + def latinfont_copy(win, wintag=nil, winkey=nil, targetkey=nil) + if targetkey + fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], + *(__config_cmd << {})) + else + fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {})) + end + + if wintag + if winkey + fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id) + else + fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id) + end + else + if winkey + fontobj.latin_replace(win.fontobj(winkey).latin_font_id) + else + fontobj.latin_replace(win.fontobj.latin_font_id) + end + end + self + end + alias asciifont_copy latinfont_copy + + def kanjifont_copy(win, wintag=nil, winkey=nil, targetkey=nil) + if targetkey + fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], + *(__config_cmd << {})) + else + fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {})) + end + + if wintag + if winkey + fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id) + else + fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id) + end + else + if winkey + fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id) + else + fontobj.kanji_replace(win.fontobj.kanji_font_id) + end + end + self + end +end + + +module TkConfigMethod + include TkUtil + include TkTreatFont + + def __cget_cmd + [self.path, 'cget'] + end + private :__cget_cmd + + def __config_cmd + [self.path, 'configure'] + end + private :__config_cmd + + def __confinfo_cmd + __config_cmd + end + private :__confinfo_cmd + + def __configinfo_struct + {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, + :default_value=>3, :current_value=>4} + end + private :__configinfo_struct + + def __numval_optkeys + [] + end + private :__numval_optkeys + + def __numstrval_optkeys + [] + end + private :__numstrval_optkeys + + def __boolval_optkeys + ['exportselection', 'jump', 'setgrid', 'takefocus'] + end + private :__boolval_optkeys + + def __strval_optkeys + [ + 'text', 'label', 'show', 'data', 'file', + 'activebackground', 'activeforeground', 'background', + 'disabledforeground', 'disabledbackground', 'foreground', + 'highlightbackground', 'highlightcolor', 'insertbackground', + 'selectbackground', 'selectforeground', 'troughcolor' + ] + end + private :__strval_optkeys + + def __listval_optkeys + [] + end + private :__listval_optkeys + + def __numlistval_optkeys + [] + end + private :__numlistval_optkeys + + def __tkvariable_optkeys + ['variable', 'textvariable'] + end + private :__tkvariable_optkeys + + def __val2ruby_optkeys # { key=>proc, ... } + # The method is used to convert a opt-value to a ruby's object. + # When get the value of the option "key", "proc.call(value)" is called. + {} + end + private :__val2ruby_optkeys + + def __ruby2val_optkeys # { key=>proc, ... } + # The method is used to convert a ruby's object to a opt-value. + # When set the value of the option "key", "proc.call(value)" is called. + # That is, "-#{key} #{proc.call(value)}". + {} + end + private :__ruby2val_optkeys + + def __methodcall_optkeys # { key=>method, ... } + # The method is used to both of get and set. + # Usually, the 'key' will not be a widget option. + {} + end + private :__methodcall_optkeys + + def __keyonly_optkeys # { def_key=>undef_key or nil, ... } + {} + end + private :__keyonly_optkeys + + def __conv_keyonly_opts(keys) + return keys unless keys.kind_of?(Hash) + keyonly = __keyonly_optkeys + keys2 = {} + keys.each{|k, v| + optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s} + if optkey + defkey, undefkey = optkey + if v + keys2[defkey.to_s] = None + elsif undefkey + keys2[undefkey.to_s] = None + else + # remove key + end + else + keys2[k.to_s] = v + end + } + keys2 + end + private :__conv_keyonly_opts + + def config_hash_kv(keys, enc_mode = nil, conf = nil) + hash_kv(__conv_keyonly_opts(keys), enc_mode, conf) + end + + ################################ + + def [](id) + cget(id) + end + + def []=(id, val) + configure(id, val) + val + end + + def cget(slot) + orig_slot = slot + slot = slot.to_s + + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end + + if ( method = _symbolkey2str(__val2ruby_optkeys())[slot] ) + optval = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) + begin + return method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + return optval + end + end + + if ( method = _symbolkey2str(__methodcall_optkeys)[slot] ) + return self.__send__(method) + end + + case slot + when /^(#{__numval_optkeys.join('|')})$/ + begin + number(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) + rescue + nil + end + + when /^(#{__numstrval_optkeys.join('|')})$/ + num_or_str(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) + + when /^(#{__boolval_optkeys.join('|')})$/ + begin + bool(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) + rescue + nil + end + + when /^(#{__listval_optkeys.join('|')})$/ + simplelist(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) + + when /^(#{__numlistval_optkeys.join('|')})$/ + conf = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) + if conf =~ /^[0-9+-]/ + list(conf) + else + conf + end + + when /^(#{__strval_optkeys.join('|')})$/ + _fromUTF8(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) + + when /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/ + fontcode = $1 + fontkey = $2 + fnt = tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << "-#{fontkey}")), true) + unless fnt.kind_of?(TkFont) + fnt = fontobj(fontkey) + end + if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + + when /^(#{__tkvariable_optkeys.join('|')})$/ + v = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) + (v.empty?)? nil: TkVarAccess.new(v) + + else + tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << "-#{slot}")), true) + end + end + + def configure(slot, value=None) + if slot.kind_of? Hash + slot = _symbolkey2str(slot) + + __methodcall_optkeys.each{|key, method| + value = slot.delete(key.to_s) + self.__send__(method, value) if value + } + + __ruby2val_optkeys.each{|key, method| + key = key.to_s + slot[key] = method.call(slot[key]) if slot.has_key?(key) + } + + __keyonly_optkeys.each{|defkey, undefkey| + conf = slot.find{|kk, vv| kk == defkey.to_s} + if conf + k, v = conf + if v + slot[k] = None + else + slot[undefkey.to_s] = None if undefkey + slot.delete(k) + end + end + } + + if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/}) + font_configure(slot) + elsif slot.size > 0 + tk_call(*(__config_cmd.concat(hash_kv(slot)))) + end + + else + orig_slot = slot + slot = slot.to_s + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end + + if ( conf = __keyonly_optkeys.find{|k, v| k.to_s == slot} ) + defkey, undefkey = conf + if value + tk_call(*(__config_cmd << "-#{defkey}")) + elsif undefkey + tk_call(*(__config_cmd << "-#{undefkey}")) + end + elsif ( method = _symbolkey2str(__ruby2val_optkeys)[slot] ) + tk_call(*(__config_cmd << "-#{slot}" << method.call(value))) + elsif ( method = _symbolkey2str(__methodcall_optkeys)[slot] ) + self.__send__(method, value) + elsif (slot =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) + if value == None + fontobj($2) + else + font_configure({slot=>value}) + end + else + tk_call(*(__config_cmd << "-#{slot}" << value)) + end + end + self + end + + def configure_cmd(slot, value) + configure(slot, install_cmd(value)) + end + + def configinfo(slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && + slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) + fontkey = $2 + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")), false, true) + conf[__configinfo_struct[:key]] = + conf[__configinfo_struct[:key]][1..-1] + if ( ! __configinfo_struct[:alias] \ + || conf.size > __configinfo_struct[:alias] + 1 ) + conf[__configinfo_struct[:current_value]] = fontobj(fontkey) + elsif ( __configinfo_struct[:alias] \ + && conf.size == __configinfo_struct[:alias] + 1 \ + && conf[__configinfo_struct[:alias]][0] == ?- ) + conf[__configinfo_struct[:alias]] = + conf[__configinfo_struct[:alias]][1..-1] + end + conf + else + if slot + slot = slot.to_s + case slot + when /^(#{__val2ruby_optkeys().keys.join('|')})$/ + method = _symbolkey2str(__val2ruby_optkeys())[slot] + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd() << "-#{slot}")), false, true) + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + optval = conf[__configinfo_struct[:default_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:default_value]] = val + end + if ( conf[__configinfo_struct[:current_value]] ) + optval = conf[__configinfo_struct[:current_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:current_value]] = val + end + + when /^(#{__methodcall_optkeys.keys.join('|')})$/ + method = _symbolkey2str(__methodcall_optkeys)[slot] + return [slot, '', '', '', self.__send__(method)] + + when /^(#{__numval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]]) + begin + conf[__configinfo_struct[:default_value]] = + number(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + number(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__numstrval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]]) + conf[__configinfo_struct[:default_value]] = + num_or_str(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + num_or_str(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__boolval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]]) + begin + conf[__configinfo_struct[:default_value]] = + bool(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + bool(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__listval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]]) + conf[__configinfo_struct[:default_value]] = + simplelist(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + simplelist(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__numlistval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] \ + && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:default_value]] = + list(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] \ + && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:current_value]] = + list(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__strval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + when /^(#{__tkvariable_optkeys.join('|')})$/ + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]]) + v = conf[__configinfo_struct[:default_value]] + if v.empty? + conf[__configinfo_struct[:default_value]] = nil + else + conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__configinfo_struct[:current_value]] ) + v = conf[__configinfo_struct[:current_value]] + if v.empty? + conf[__configinfo_struct[:current_value]] = nil + else + conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v) + end + end + + else + # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true) + end + conf[__configinfo_struct[:key]] = + conf[__configinfo_struct[:key]][1..-1] + + if ( __configinfo_struct[:alias] \ + && conf.size == __configinfo_struct[:alias] + 1 \ + && conf[__configinfo_struct[:alias]][0] == ?- ) + conf[__configinfo_struct[:alias]] = + conf[__configinfo_struct[:alias]][1..-1] + end + + conf + + else + # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + ret = tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[__configinfo_struct[:key]] = + conf[__configinfo_struct[:key]][1..-1] + + optkey = conf[__configinfo_struct[:key]] + case optkey + when /^(#{__val2ruby_optkeys().keys.join('|')})$/ + method = _symbolkey2str(__val2ruby_optkeys())[optkey] + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + optval = conf[__configinfo_struct[:default_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:default_value]] = val + end + if ( conf[__configinfo_struct[:current_value]] ) + optval = conf[__configinfo_struct[:current_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:current_value]] = val + end + + when /^(#{__strval_optkeys.join('|')})$/ + # do nothing + + when /^(#{__numval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + begin + conf[__configinfo_struct[:default_value]] = + number(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + number(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__numstrval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + conf[__configinfo_struct[:default_value]] = + num_or_str(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + num_or_str(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__boolval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + begin + conf[__configinfo_struct[:default_value]] = + bool(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + bool(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__listval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + conf[__configinfo_struct[:default_value]] = + simplelist(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + simplelist(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__numlistval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] \ + && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:default_value]] = + list(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] \ + && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:current_value]] = + list(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__tkvariable_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + v = conf[__configinfo_struct[:default_value]] + if v.empty? + conf[__configinfo_struct[:default_value]] = nil + else + conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__configinfo_struct[:current_value]] ) + v = conf[__configinfo_struct[:current_value]] + if v.empty? + conf[__configinfo_struct[:current_value]] = nil + else + conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v) + end + end + + else + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + if conf[__configinfo_struct[:default_value]].index('{') + conf[__configinfo_struct[:default_value]] = + tk_split_list(conf[__configinfo_struct[:default_value]]) + else + conf[__configinfo_struct[:default_value]] = + tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) + end + end + if conf[__configinfo_struct[:current_value]] + if conf[__configinfo_struct[:current_value]].index('{') + conf[__configinfo_struct[:current_value]] = + tk_split_list(conf[__configinfo_struct[:current_value]]) + else + conf[__configinfo_struct[:current_value]] = + tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) + end + end + end + + if ( __configinfo_struct[:alias] \ + && conf.size == __configinfo_struct[:alias] + 1 \ + && conf[__configinfo_struct[:alias]][0] == ?- ) + conf[__configinfo_struct[:alias]] = + conf[__configinfo_struct[:alias]][1..-1] + end + + conf + } + + __font_optkeys.each{|optkey| + optkey = optkey.to_s + fontconf = ret.assoc(optkey) + if fontconf && fontconf.size > 2 + ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} + fontconf[__configinfo_struct[:current_value]] = fontobj(optkey) + ret.push(fontconf) + end + } + + __methodcall_optkeys.each{|optkey, method| + ret << [optkey.to_s, '', '', '', self.__send__(method)] + } + + ret + end + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && + slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) + fontkey = $2 + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")), false, true) + conf[__configinfo_struct[:key]] = + conf[__configinfo_struct[:key]][1..-1] + + if ( ! __configinfo_struct[:alias] \ + || conf.size > __configinfo_struct[:alias] + 1 ) + conf[__configinfo_struct[:current_value]] = fontobj(fontkey) + { conf.shift => conf } + elsif ( __configinfo_struct[:alias] \ + && conf.size == __configinfo_struct[:alias] + 1 ) + if conf[__configinfo_struct[:alias]][0] == ?- + conf[__configinfo_struct[:alias]] = + conf[__configinfo_struct[:alias]][1..-1] + end + { conf[0] => conf[1] } + else + { conf.shift => conf } + end + else + if slot + slot = slot.to_s + case slot + when /^(#{__val2ruby_optkeys().keys.join('|')})$/ + method = _symbolkey2str(__val2ruby_optkeys())[slot] + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + optval = conf[__configinfo_struct[:default_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:default_value]] = val + end + if ( conf[__configinfo_struct[:current_value]] ) + optval = conf[__configinfo_struct[:current_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:current_value]] = val + end + + when /^(#{__methodcall_optkeys.keys.join('|')})$/ + method = _symbolkey2str(__methodcall_optkeys)[slot] + return {slot => ['', '', '', self.__send__(method)]} + + when /^(#{__numval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + begin + conf[__configinfo_struct[:default_value]] = + number(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + number(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__numstrval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + conf[__configinfo_struct[:default_value]] = + num_or_str(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + num_or_str(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__boolval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + begin + conf[__configinfo_struct[:default_value]] = + bool(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + bool(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__listval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + conf[__configinfo_struct[:default_value]] = + simplelist(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + simplelist(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__numlistval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] \ + && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:default_value]] = + list(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] \ + && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:current_value]] = + list(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__tkvariable_optkeys.join('|')})$/ + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + v = conf[__configinfo_struct[:default_value]] + if v.empty? + conf[__configinfo_struct[:default_value]] = nil + else + conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__configinfo_struct[:current_value]] ) + v = conf[__configinfo_struct[:current_value]] + if v.empty? + conf[__configinfo_struct[:current_value]] = nil + else + conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v) + end + end + + when /^(#{__strval_optkeys.join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) + else + # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) + conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true) + end + conf[__configinfo_struct[:key]] = + conf[__configinfo_struct[:key]][1..-1] + + if ( __configinfo_struct[:alias] \ + && conf.size == __configinfo_struct[:alias] + 1 ) + if conf[__configinfo_struct[:alias]][0] == ?- + conf[__configinfo_struct[:alias]] = + conf[__configinfo_struct[:alias]][1..-1] + end + { conf[0] => conf[1] } + else + { conf.shift => conf } + end + + else + ret = {} + # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[__configinfo_struct[:key]] = + conf[__configinfo_struct[:key]][1..-1] + + optkey = conf[__configinfo_struct[:key]] + case optkey + when /^(#{__val2ruby_optkeys().keys.join('|')})$/ + method = _symbolkey2str(__val2ruby_optkeys())[optkey] + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + optval = conf[__configinfo_struct[:default_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:default_value]] = val + end + if ( conf[__configinfo_struct[:current_value]] ) + optval = conf[__configinfo_struct[:current_value]] + begin + val = method.call(optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG + val = optval + end + conf[__configinfo_struct[:current_value]] = val + end + + when /^(#{__strval_optkeys.join('|')})$/ + # do nothing + + when /^(#{__numval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + begin + conf[__configinfo_struct[:default_value]] = + number(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + number(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__numstrval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + conf[__configinfo_struct[:default_value]] = + num_or_str(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + num_or_str(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__boolval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + begin + conf[__configinfo_struct[:default_value]] = + bool(conf[__configinfo_struct[:default_value]]) + rescue + conf[__configinfo_struct[:default_value]] = nil + end + end + if ( conf[__configinfo_struct[:current_value]] ) + begin + conf[__configinfo_struct[:current_value]] = + bool(conf[__configinfo_struct[:current_value]]) + rescue + conf[__configinfo_struct[:current_value]] = nil + end + end + + when /^(#{__listval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + conf[__configinfo_struct[:default_value]] = + simplelist(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] ) + conf[__configinfo_struct[:current_value]] = + simplelist(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__numlistval_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] \ + && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:default_value]] = + list(conf[__configinfo_struct[:default_value]]) + end + if ( conf[__configinfo_struct[:current_value]] \ + && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) + conf[__configinfo_struct[:current_value]] = + list(conf[__configinfo_struct[:current_value]]) + end + + when /^(#{__tkvariable_optkeys.join('|')})$/ + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + v = conf[__configinfo_struct[:default_value]] + if v.empty? + conf[__configinfo_struct[:default_value]] = nil + else + conf[__configinfo_struct[:default_value]] = TkVarAccess.new + end + end + if ( conf[__configinfo_struct[:current_value]] ) + v = conf[__configinfo_struct[:current_value]] + if v.empty? + conf[__configinfo_struct[:current_value]] = nil + else + conf[__configinfo_struct[:current_value]] = TkVarAccess.new + end + end + + else + if ( __configinfo_struct[:default_value] \ + && conf[__configinfo_struct[:default_value]] ) + if conf[__configinfo_struct[:default_value]].index('{') + conf[__configinfo_struct[:default_value]] = + tk_split_list(conf[__configinfo_struct[:default_value]]) + else + conf[__configinfo_struct[:default_value]] = + tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) + end + end + if conf[__configinfo_struct[:current_value]] + if conf[__configinfo_struct[:current_value]].index('{') + conf[__configinfo_struct[:current_value]] = + tk_split_list(conf[__configinfo_struct[:current_value]]) + else + conf[__configinfo_struct[:current_value]] = + tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) + end + end + end + + if ( __configinfo_struct[:alias] \ + && conf.size == __configinfo_struct[:alias] + 1 ) + if conf[__configinfo_struct[:alias]][0] == ?- + conf[__configinfo_struct[:alias]] = + conf[__configinfo_struct[:alias]][1..-1] + end + ret[conf[0]] = conf[1] + else + ret[conf.shift] = conf + end + } + + __font_optkeys.each{|optkey| + optkey = optkey.to_s + fontconf = ret[optkey] + if fontconf.kind_of?(Array) + ret.delete(optkey) + ret.delete('latin' << optkey) + ret.delete('ascii' << optkey) + ret.delete('kanji' << optkey) + fontconf[__configinfo_struct[:current_value]] = fontobj(optkey) + ret[optkey] = fontconf + end + } + + __methodcall_optkeys.each{|optkey, method| + ret[optkey.to_s] = ['', '', '', self.__send__(method)] + } + + ret + end + end + end + end + + def current_configinfo(slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + org_slot = slot + begin + conf = configinfo(slot) + if ( ! __configinfo_struct[:alias] \ + || conf.size > __configinfo_struct[:alias] + 1 ) + return {conf[0] => conf[-1]} + end + slot = conf[__configinfo_struct[:alias]] + end while(org_slot != slot) + fail RuntimeError, + "there is a configure alias loop about '#{org_slot}'" + else + ret = {} + configinfo().each{|conf| + if ( ! __configinfo_struct[:alias] \ + || conf.size > __configinfo_struct[:alias] + 1 ) + ret[conf[0]] = conf[-1] + end + } + 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 +end + +class TkObject<TkKernel + extend TkCore + include Tk + include TkConfigMethod + include TkBindCore + +### --> definition is moved to TkUtil module +# def path +# @path +# end + + def epath + @path + end + + def to_eval + @path + end + + def tk_send(cmd, *rest) + tk_call(path, cmd, *rest) + end + def tk_send_without_enc(cmd, *rest) + tk_call_without_enc(path, cmd, *rest) + end + def tk_send_with_enc(cmd, *rest) + tk_call_with_enc(path, cmd, *rest) + end + # private :tk_send, :tk_send_without_enc, :tk_send_with_enc + + def tk_send_to_list(cmd, *rest) + tk_call_to_list(path, cmd, *rest) + end + def tk_send_to_list_without_enc(cmd, *rest) + tk_call_to_list_without_enc(path, cmd, *rest) + end + def tk_send_to_list_with_enc(cmd, *rest) + tk_call_to_list_with_enc(path, cmd, *rest) + end + def tk_send_to_simplelist(cmd, *rest) + tk_call_to_simplelist(path, cmd, *rest) + end + def tk_send_to_simplelist_without_enc(cmd, *rest) + tk_call_to_simplelist_without_enc(path, cmd, *rest) + end + def tk_send_to_simplelist_with_enc(cmd, *rest) + tk_call_to_simplelist_with_enc(path, cmd, *rest) + end + + def method_missing(id, *args) + name = id.id2name + case args.length + when 1 + if name[-1] == ?= + configure name[0..-2], args[0] + args[0] + else + configure name, args[0] + self + end + when 0 + begin + cget(name) + rescue + super(id, *args) +# fail NameError, +# "undefined local variable or method `#{name}' for #{self.to_s}", +# error_at + end + else + super(id, *args) +# fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + end + end + +=begin + def [](id) + cget(id) + end + + def []=(id, val) + configure(id, val) + val + end +=end + + def event_generate(context, keys=nil) + if context.kind_of?(TkEvent::Event) + context.generate(self, ((keys)? keys: {})) + elsif 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_without_enc('event', 'generate', path, + "<#{tk_event_sequence(context)}>") + end + end + + def tk_trace_variable(v) + #unless v.kind_of?(TkVariable) + # 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 + end +end + + +class TkWindow<TkObject + include TkWinfo + extend TkBindCore + + TkCommandNames = [].freeze + ## ==> If TkCommandNames[0] is a string (not a null string), + ## assume the string is a Tcl/Tk's create command of the widget class. + WidgetClassName = ''.freeze + # WidgetClassNames[WidgetClassName] = self + ## ==> If self is a widget class, entry to the WidgetClassNames table. + def self.to_eval + self::WidgetClassName + end + + def initialize(parent=nil, keys=nil) + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + widgetname = keys.delete('widgetname') + install_win(if parent then parent.path end, widgetname) + without_creating = keys.delete('without_creating') + # if without_creating && !widgetname + # fail ArgumentError, + # "if set 'without_creating' to true, need to define 'widgetname'" + # end + elsif keys + keys = _symbolkey2str(keys) + widgetname = keys.delete('widgetname') + install_win(if parent then parent.path end, widgetname) + without_creating = keys.delete('without_creating') + # if without_creating && !widgetname + # fail ArgumentError, + # "if set 'without_creating' to true, need to define 'widgetname'" + # end + else + install_win(if parent then parent.path end) + end + if self.method(:create_self).arity == 0 + p 'create_self has no arg' if $DEBUG + create_self unless without_creating + if keys + # tk_call @path, 'configure', *hash_kv(keys) + configure(keys) + end + else + p 'create_self has args' if $DEBUG + fontkeys = {} + methodkeys = {} + if keys + #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key| + # fontkeys[key] = keys.delete(key) if keys.key?(key) + #} + __font_optkeys.each{|key| + fkey = key.to_s + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "kanji#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "latin#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "ascii#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + } + + __methodcall_optkeys.each{|key| + key = key.to_s + methodkeys[key] = keys.delete(key) if keys.key?(key) + } + + __ruby2val_optkeys.each{|key, method| + key = key.to_s + keys[key] = method.call(keys[key]) if keys.has_key?(key) + } + end + if without_creating && keys + #configure(keys) + configure(__conv_keyonly_opts(keys)) + else + #create_self(keys) + create_self(__conv_keyonly_opts(keys)) + end + font_configure(fontkeys) unless fontkeys.empty? + configure(methodkeys) unless methodkeys.empty? + end + end + + def create_self(keys) + # may need to override + begin + cmd = self.class::TkCommandNames[0] + fail unless (cmd.kind_of?(String) && cmd.length > 0) + rescue + fail RuntimeError, "class #{self.class} may be an abstract class" + end + + if keys and keys != None + tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) + else + tk_call_without_enc(cmd, @path) + end + end + private :create_self + + def exist? + TkWinfo.exist?(self) + end + + def bind_class + @db_class || self.class() + end + + def database_classname + TkWinfo.classname(self) + end + def database_class + name = database_classname() + if WidgetClassNames[name] + WidgetClassNames[name] + else + TkDatabaseClass.new(name) + end + end + def self.database_classname + self::WidgetClassName + end + def self.database_class + WidgetClassNames[self::WidgetClassName] + end + + def pack(keys = nil) + #tk_call_without_enc('pack', epath, *hash_kv(keys, true)) + if keys + TkPack.configure(self, keys) + else + TkPack.configure(self) + end + self + end + + def pack_in(target, keys = nil) + if keys + keys = keys.dup + keys['in'] = target + else + keys = {'in'=>target} + end + #tk_call 'pack', epath, *hash_kv(keys) + TkPack.configure(self, keys) + self + end + + def pack_forget + #tk_call_without_enc('pack', 'forget', epath) + TkPack.forget(self) + self + end + 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 + TkPack.configure(self, slot) + else + TkPack.configure(self, slot=>value) + end + end + alias pack_configure pack_config + + def pack_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 + TkPack.propagate(self) + else + TkPack.propagate(self, mode) + self + end + end + + def pack_slaves() + #list(tk_call('pack', 'slaves', epath)) + TkPack.slaves(self) + end + + def grid(keys = nil) + #tk_call 'grid', epath, *hash_kv(keys) + if keys + TkGrid.configure(self, keys) + else + TkGrid.configure(self) + end + self + end + + def grid_in(target, keys = nil) + if keys + keys = keys.dup + keys['in'] = target + else + keys = {'in'=>target} + end + #tk_call 'grid', epath, *hash_kv(keys) + TkGrid.configure(self, keys) + self + end + + def grid_forget + #tk_call('grid', 'forget', epath) + TkGrid.forget(self) + self + end + alias ungrid grid_forget + + def grid_bbox(*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 + TkGrid.configure(self, slot) + else + TkGrid.configure(self, slot=>value) + end + end + alias grid_configure grid_config + + def grid_columnconfig(index, 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)) + 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 + 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 + TkGrid.rowconfiginfo(self, index, slot) + end + + def grid_info() + #list(tk_call('grid', 'info', epath)) + TkGrid.info(self) + end + + def grid_location(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 + TkGrid.propagate(self) + else + TkGrid.propagate(self, mode) + self + end + end + + def grid_remove() + #tk_call 'grid', 'remove', epath + TkGrid.remove(self) + self + end + + def grid_size() + #list(tk_call('grid', 'size', epath)) + TkGrid.size(self) + end + + def grid_slaves(args) + #list(tk_call('grid', 'slaves', epath, *hash_kv(args))) + TkGrid.slaves(self, args) + end + + def place(keys) + #tk_call 'place', epath, *hash_kv(keys) + TkPlace.configure(self, keys) + self + end + + def place_in(target, keys = nil) + if keys + keys = keys.dup + keys['in'] = target + else + keys = {'in'=>target} + end + #tk_call 'place', epath, *hash_kv(keys) + TkPlace.configure(self, keys) + self + end + + def place_forget + #tk_call 'place', 'forget', epath + TkPlace.forget(self) + self + end + 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 + TkPlace.configure(self, slot, value) + end + alias place_configure place_config + + 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 + TkPlace.configinfo(self, 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 + TkPlace.info(self) + end + + def place_slaves() + #list(tk_call('place', 'slaves', epath)) + TkPlace.slaves(self) + end + + def set_focus(force=false) + if force + tk_call_without_enc('focus', '-force', path) + else + tk_call_without_enc('focus', path) + end + self + end + alias focus set_focus + + def grab(opt = nil) + unless opt + tk_call_without_enc('grab', 'set', path) + return self + end + + case opt + when 'set', :set + tk_call_without_enc('grab', 'set', path) + return self + 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 + return tk_call_without_enc('grab', opt, path) + end + end + + def grab_current + grab('current') + end + alias current_grab grab_current + def grab_release + grab('release') + end + alias release_grab grab_release + def grab_set + grab('set') + end + alias set_grab grab_set + def grab_set_global + grab('global') + end + alias set_global_grab grab_set_global + def grab_status + grab('status') + end + + def lower(below=None) + # below = below.epath if below.kind_of?(TkObject) + below = _epath(below) + tk_call 'lower', epath, below + self + end + alias lower_window lower + def raise(above=None) + #above = above.epath if above.kind_of?(TkObject) + above = _epath(above) + tk_call 'raise', epath, above + self + end + alias raise_window raise + + def command(cmd=nil, &b) + if cmd + configure_cmd('command', cmd) + elsif b + configure_cmd('command', Proc.new(&b)) + else + cget('command') + end + end + + def colormodel(model=None) + tk_call('tk', 'colormodel', path, model) + self + end + + def caret(keys=nil) + TkXIM.caret(path, keys) + end + + def destroy + super + children = [] + rexp = /^#{self.path}\.[^.]+$/ + TkCore::INTERP.tk_windows.each{|path, obj| + children << [path, obj] if path =~ rexp + } + if defined?(@cmdtbl) + for id in @cmdtbl + uninstall_cmd id + end + end + + children.each{|path, obj| + if defined?(@cmdtbl) + for id in @cmdtbl + uninstall_cmd id + end + end + TkCore::INTERP.tk_windows.delete(path) + } + + begin + tk_call_without_enc('destroy', epath) + rescue + end + uninstall_win + end + + def wait_visibility(on_thread = true) + if $SAFE >= 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 + INTERP._invoke('tkwait', 'visibility', path) + end + end + def eventloop_wait_visibility + wait_visibility(false) + end + def thread_wait_visibility + wait_visibility(true) + end + alias wait wait_visibility + alias tkwait wait_visibility + alias eventloop_wait eventloop_wait_visibility + alias eventloop_tkwait eventloop_wait_visibility + alias eventloop_tkwait_visibility eventloop_wait_visibility + alias thread_wait thread_wait_visibility + alias thread_tkwait thread_wait_visibility + alias thread_tkwait_visibility thread_wait_visibility + + def wait_destroy(on_thread = true) + if $SAFE >= 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 + INTERP._invoke('tkwait', 'window', epath) + end + end + alias wait_window wait_destroy + def eventloop_wait_destroy + wait_destroy(false) + end + alias eventloop_wait_window eventloop_wait_destroy + def thread_wait_destroy + wait_destroy(true) + end + alias thread_wait_window thread_wait_destroy + + alias tkwait_destroy wait_destroy + alias tkwait_window wait_destroy + + alias eventloop_tkwait_destroy eventloop_wait_destroy + alias eventloop_tkwait_window eventloop_wait_destroy + + alias thread_tkwait_destroy thread_wait_destroy + alias thread_tkwait_window thread_wait_destroy + + def bindtags(taglist=nil) + if taglist + fail ArgumentError, "taglist must be Array" unless taglist.kind_of? Array + tk_call('bindtags', path, taglist) + taglist + else + list(tk_call('bindtags', path)).collect{|tag| + if tag.kind_of?(String) + if cls = WidgetClassNames[tag] + cls + elsif btag = TkBindTag.id2obj(tag) + btag + else + tag + end + else + tag + end + } + end + end + + def bindtags=(taglist) + bindtags(taglist) + taglist + end + + def bindtags_shift + taglist = bindtags + tag = taglist.shift + bindtags(taglist) + tag + end + + def bindtags_unshift(tag) + bindtags(bindtags().unshift(tag)) + end +end + + +# freeze core modules +#TclTkLib.freeze +#TclTkIp.freeze +#TkUtil.freeze +#TkKernel.freeze +#TkComm.freeze +#TkComm::Event.freeze +#TkCore.freeze +#Tk.freeze + +module Tk + RELEASE_DATE = '2007-01-26'.freeze + + 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 + +# call setup script for Tk extension libraries (base configuration) +begin + require 'tkextlib/version.rb' + require 'tkextlib/setup.rb' +rescue LoadError + # ignore +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/after.rb b/ruby_1_8_6/ext/tk/lib/tk/after.rb new file mode 100644 index 0000000000..8c58210331 --- /dev/null +++ b/ruby_1_8_6/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/ruby_1_8_6/ext/tk/lib/tk/autoload.rb b/ruby_1_8_6/ext/tk/lib/tk/autoload.rb new file mode 100644 index 0000000000..6b3773f4ea --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/autoload.rb @@ -0,0 +1,196 @@ +# +# 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 :TkDialogObj, 'tk/dialog' +autoload :TkWarning, 'tk/dialog' +autoload :TkWarning2, 'tk/dialog' +autoload :TkWarningObj, '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 :TkItemConfigMethod, 'tk/itemconfig' + +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 :TkMenuSpec, 'tk/menuspec' + +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 :TkRTTimer, '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 :TkNamedVirtualEvent,'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 :OptionObj, 'tk/optionobj' + autoload :X_Scrollable, 'tk/scrollable' + autoload :Y_Scrollable, 'tk/scrollable' + autoload :Scrollable, 'tk/scrollable' + autoload :Wm, 'tk/wm' + + autoload :ValidateConfigure, 'tk/validation' + autoload :ItemValidateConfigure, 'tk/validation' + + autoload :EncodedString, 'tk/encodedstr' + def Tk.EncodedString(str, enc = nil); Tk::EncodedString.new(str, enc); end + + autoload :BinaryString, 'tk/encodedstr' + def Tk.BinaryString(str); Tk::BinaryString.new(str); end + + autoload :UTF8_String, 'tk/encodedstr' + def Tk.UTF8_String(str); Tk::UTF8_String.new(str); end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/bgerror.rb b/ruby_1_8_6/ext/tk/lib/tk/bgerror.rb new file mode 100644 index 0000000000..c82a8e046b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/bgerror.rb @@ -0,0 +1,29 @@ +# +# tkbgerror -- bgerror ( tkerror ) module +# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +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/ruby_1_8_6/ext/tk/lib/tk/bindtag.rb b/ruby_1_8_6/ext/tk/lib/tk/bindtag.rb new file mode 100644 index 0000000000..9023a08e06 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/bindtag.rb @@ -0,0 +1,81 @@ +# +# 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.instance_eval{ + BTagID_TBL.delete @id + @id = name + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + self + } + end + + def initialize(*args, &b) + # @id = Tk_BINDTAG_ID.join('') + @id = Tk_BINDTAG_ID.join(TkCore::INTERP._ip_id_) + 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 "#<TkBindTag: %s>", @id + '#<TkBindTag: ' + @id + '>' + end +end + + +class TkBindTagAll<TkBindTag + def TkBindTagAll.new(*args, &b) + $stderr.puts "Warning: TkBindTagALL is obsolete. Use TkBindTag::ALL\n" + + TkBindTag::ALL.bind(*args, &b) if args != [] + TkBindTag::ALL + end +end + + +class TkDatabaseClass<TkBindTag + def self.new(name, *args, &b) + return BTagID_TBL[name] if BTagID_TBL[name] + super(name, *args, &b) + end + + def initialize(name, *args, &b) + @id = name + BTagID_TBL[@id] = self + bind(*args, &b) if args != [] + end + + def inspect + #Kernel.format "#<TkDatabaseClass: %s>", @id + '#<TkDatabaseClass: ' + @id + '>' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/button.rb b/ruby_1_8_6/ext/tk/lib/tk/button.rb new file mode 100644 index 0000000000..407a47c400 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/button.rb @@ -0,0 +1,27 @@ +# +# tk/button.rb : treat button widget +# +require 'tk' +require 'tk/label' + +class TkButton<TkLabel + TkCommandNames = ['button'.freeze].freeze + WidgetClassName = 'Button'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('button', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('button', @path) + # end + #end + #private :create_self + + def invoke + _fromUTF8(tk_send_without_enc('invoke')) + end + def flash + tk_send_without_enc('flash') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/canvas.rb b/ruby_1_8_6/ext/tk/lib/tk/canvas.rb new file mode 100644 index 0000000000..c30fd79bb9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/canvas.rb @@ -0,0 +1,759 @@ +# +# tk/canvas.rb - Tk canvas classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +# +require 'tk' +require 'tk/canvastag' +require 'tk/itemconfig' +require 'tk/scrollable' + +module TkCanvasItemConfig + include TkItemConfigMethod + + def __item_strval_optkeys(id) + # maybe need to override + super(id) + [ + 'fill', 'activefill', 'disabledfill', + 'outline', 'activeoutline', 'disabledoutline' + ] + end + private :__item_strval_optkeys + + def __item_methodcall_optkeys(id) + {'coords'=>'coords'} + end + private :__item_methodcall_optkeys + + def __item_val2ruby_optkeys(id) # { key=>proc, ... } + super(id).update('window'=>proc{|i, v| window(v)}) + end + private :__item_val2ruby_optkeys + + 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 :__item_pathname +end + +class TkCanvas<TkWindow + include TkCanvasItemConfig + include Tk::Scrollable + + TkCommandNames = ['canvas'.freeze].freeze + WidgetClassName = 'Canvas'.freeze + WidgetClassNames[WidgetClassName] = self + + def __destroy_hook__ + TkcItem::CItemID_TBL.delete(@path) + end + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('canvas', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('canvas', @path) + # end + #end + #private :create_self + + def __numval_optkeys + super() + ['closeenough'] + end + private :__numval_optkeys + + def __boolval_optkeys + super() + ['confine'] + end + private :__boolval_optkeys + + def tagid(tag) + if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag) + tag.id + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + + # create a canvas item without creating a TkcItem object + def create(type, *args) + type.create(self, *args) + end + + + def addtag(tag, mode, *args) + mode = mode.to_s + if args[0] && mode =~ /^(above|below|with(tag)?)$/ + args[0] = tagid(args[0]) + end + tk_send_without_enc('addtag', tagid(tag), mode, *args) + self + end + def addtag_above(tagOrId, target) + addtag(tagOrId, 'above', tagid(target)) + end + def addtag_all(tagOrId) + addtag(tagOrId, 'all') + end + def addtag_below(tagOrId, target) + addtag(tagOrId, 'below', tagid(target)) + end + def addtag_closest(tagOrId, x, y, halo=None, start=None) + addtag(tagOrId, 'closest', x, y, halo, start) + end + def addtag_enclosed(tagOrId, x1, y1, x2, y2) + addtag(tagOrId, 'enclosed', x1, y1, x2, y2) + end + def addtag_overlapping(tagOrId, x1, y1, x2, y2) + addtag(tagOrId, 'overlapping', x1, y1, x2, y2) + end + def addtag_withtag(tagOrId, tag) + addtag(tagOrId, 'withtag', tagid(tag)) + end + + def bbox(tagOrId, *tags) + list(tk_send_without_enc('bbox', tagid(tagOrId), + *tags.collect{|t| tagid(t)})) + end + + #def itembind(tag, context, cmd=Proc.new, *args) + # _bind([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def itembind(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, "bind", tagid(tag)], context, cmd, *args) + self + end + + #def itembind_append(tag, context, cmd=Proc.new, *args) + # _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def itembind_append(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + self + end + + def itembind_remove(tag, context) + _bind_remove([path, "bind", tagid(tag)], context) + self + end + + def itembindinfo(tag, context=nil) + _bindinfo([path, "bind", tagid(tag)], context) + end + + def canvasx(screen_x, *args) + #tk_tcl2ruby(tk_send_without_enc('canvasx', screen_x, *args)) + number(tk_send_without_enc('canvasx', screen_x, *args)) + end + def canvasy(screen_y, *args) + #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args)) + number(tk_send_without_enc('canvasy', screen_y, *args)) + end + + def coords(tag, *args) + if args == [] + tk_split_list(tk_send_without_enc('coords', tagid(tag))) + else + tk_send_without_enc('coords', tagid(tag), *(args.flatten)) + self + end + end + + def dchars(tag, first, last=None) + tk_send_without_enc('dchars', tagid(tag), + _get_eval_enc_str(first), _get_eval_enc_str(last)) + self + end + + def delete(*args) + if TkcItem::CItemID_TBL[self.path] + args.each{|tag| + find('withtag', tag).each{|item| + if item.kind_of?(TkcItem) + TkcItem::CItemID_TBL[self.path].delete(item.id) + end + } + } + end + tk_send_without_enc('delete', *args.collect{|t| tagid(t)}) + self + end + alias remove delete + + def dtag(tag, tag_to_del=None) + tk_send_without_enc('dtag', tagid(tag), tagid(tag_to_del)) + self + end + alias deltag dtag + + def find(mode, *args) + list(tk_send_without_enc('find', mode, *args)).collect!{|id| + TkcItem.id2obj(self, id) + } + end + def find_above(target) + find('above', tagid(target)) + end + def find_all + find('all') + end + def find_below(target) + find('below', tagid(target)) + end + def find_closest(x, y, halo=None, start=None) + find('closest', x, y, halo, start) + end + def find_enclosed(x1, y1, x2, y2) + find('enclosed', x1, y1, x2, y2) + end + def find_overlapping(x1, y1, x2, y2) + find('overlapping', x1, y1, x2, y2) + end + def find_withtag(tag) + find('withtag', tag) + end + + def itemfocus(tagOrId=nil) + if tagOrId + tk_send_without_enc('focus', tagid(tagOrId)) + self + else + ret = tk_send_without_enc('focus') + if ret == "" + nil + else + TkcItem.id2obj(self, ret) + end + end + end + + def gettags(tagOrId) + list(tk_send_without_enc('gettags', tagid(tagOrId))).collect{|tag| + TkcTag.id2obj(self, tag) + } + end + + def icursor(tagOrId, index) + tk_send_without_enc('icursor', tagid(tagOrId), index) + self + end + + def index(tagOrId, idx) + number(tk_send_without_enc('index', tagid(tagOrId), idx)) + end + + def insert(tagOrId, index, string) + tk_send_without_enc('insert', tagid(tagOrId), index, + _get_eval_enc_str(string)) + self + end + +=begin + def itemcget(tagOrId, option) + case option.to_s + when 'dash', 'activedash', 'disableddash' + conf = tk_send_without_enc('itemcget', tagid(tagOrId), "-#{option}") + if conf =~ /^[0-9]/ + list(conf) + else + conf + end + when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile' + _fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId), "-#{option}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('itemcget', tagid(tagOrId), "-#{option}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_with_enc('itemcget', tagid(tagOrId), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tagid(tagOrId), fnt) + end + if option.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('itemcget', tagid(tagOrId), + "-#{option}"))) + end + end + + def itemconfigure(tagOrId, key, value=None) + if key.kind_of? Hash + key = _symbolkey2str(key) + coords = key.delete('coords') + self.coords(tagOrId, coords) if coords + + if ( key['font'] || key['kanjifont'] \ + || key['latinfont'] || key['asciifont'] ) + tagfont_configure(tagid(tagOrId), key.dup) + else + _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), + *hash_kv(key, true))) + end + + else + if ( key == 'coords' || key == :coords ) + self.coords(tagOrId, value) + elsif ( key == 'font' || key == :font || + key == 'kanjifont' || key == :kanjifont || + key == 'latinfont' || key == :latinfont || + key == 'asciifont' || key == :asciifont ) + if value == None + tagfontobj(tagid(tagOrId)) + else + tagfont_configure(tagid(tagOrId), {key=>value}) + 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 'coords' + return ['coords', '', '', '', self.coords(tagOrId)] + 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) + end + + ret << ['coords', '', '', '', self.coords(tagOrId)] + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if key + case key.to_s + when 'coords' + {'coords' => ['', '', '', self.coords(tagOrId)]} + 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['coords'] = ['', '', '', self.coords(tagOrId)] + + 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 +=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, gain=None) + tk_send_without_enc('scan', 'dragto', x, y, gain) + 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<TkObject + extend Tk + include TkcTagAccess + extend TkItemFontOptkeys + extend TkItemConfigOptkeys + + CItemTypeName = nil + CItemTypeToClass = {} + CItemID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ CItemID_TBL.clear } + + def TkcItem.type2class(type) + CItemTypeToClass[type] + end + + def TkcItem.id2obj(canvas, id) + cpath = canvas.path + return id unless CItemID_TBL[cpath] + CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id + end + + ######################################## + def self._parse_create_args(args) + fontkeys = {} + methodkeys = {} + if args[-1].kind_of? Hash + keys = _symbolkey2str(args.pop) + if args.size == 0 + args = keys.delete('coords') + unless args.kind_of?(Array) + fail "coords parameter must be given by an Array" + end + end + + #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key| + # fontkeys[key] = keys.delete(key) if keys.key?(key) + #} + __item_font_optkeys(nil).each{|key| + fkey = key.to_s + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "kanji#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "latin#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "ascii#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + } + + __item_methodcall_optkeys(nil).each{|key| + key = key.to_s + methodkeys[key] = keys.delete(key) if keys.key?(key) + } + + __item_ruby2val_optkeys(nil).each{|key, method| + key = key.to_s + keys[key] = method.call(keys[key]) if keys.has_key?(key) + } + + #args = args.flatten.concat(hash_kv(keys)) + args = args.flatten.concat(itemconfig_hash_kv(nil, keys)) + else + args = args.flatten + end + + [args, fontkeys] + end + private_class_method :_parse_create_args + + def self.create(canvas, *args) + unless self::CItemTypeName + fail RuntimeError, "#{self} is an abstract class" + end + args, fontkeys = _parse_create_args(args) + idnum = tk_call_without_enc(canvas.path, 'create', + self::CItemTypeName, *args) + canvas.itemconfigure(idnum, fontkeys) unless fontkeys.empty? + idnum.to_i # 'canvas item id' is an integer number + end + ######################################## + + def initialize(parent, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @parent = @c = parent + @path = parent.path + + @id = create_self(*args) # an integer number as 'canvas item id' + CItemID_TBL[@path] = {} unless CItemID_TBL[@path] + CItemID_TBL[@path][@id] = self + end + def create_self(*args) + self.class.create(@c, *args) # return an integer number as 'canvas item id' + end + private :create_self + + def id + @id + end + + def exist? + if @c.find_withtag(@id) + true + else + false + end + end + + def delete + @c.delete @id + CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + self + end + alias remove delete + alias destroy delete +end + +class TkcArc<TkcItem + CItemTypeName = 'arc'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcBitmap<TkcItem + CItemTypeName = 'bitmap'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcImage<TkcItem + CItemTypeName = 'image'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcLine<TkcItem + CItemTypeName = 'line'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcOval<TkcItem + CItemTypeName = 'oval'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcPolygon<TkcItem + CItemTypeName = 'polygon'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcRectangle<TkcItem + CItemTypeName = 'rectangle'.freeze + CItemTypeToClass[CItemTypeName] = self +end + +class TkcText<TkcItem + CItemTypeName = 'text'.freeze + CItemTypeToClass[CItemTypeName] = self + def self.create(canvas, *args) + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + txt = keys['text'] + keys['text'] = _get_eval_enc_str(txt) if txt + args.push(keys) + end + super(canvas, *args) + end +end + +class TkcWindow<TkcItem + CItemTypeName = 'window'.freeze + CItemTypeToClass[CItemTypeName] = self + def self.create(canvas, *args) + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + win = keys['window'] + # keys['window'] = win.epath if win.kind_of?(TkWindow) + keys['window'] = _epath(win) if win + args.push(keys) + end + super(canvas, *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/canvastag.rb b/ruby_1_8_6/ext/tk/lib/tk/canvastag.rb new file mode 100644 index 0000000000..a5650ee68b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/canvastag.rb @@ -0,0 +1,375 @@ +# +# tk/canvastag.rb - methods for treating canvas tags +# +require 'tk' +require 'tk/tagfont' + +module TkcTagAccess + include TkComm + include TkTreatTagFont +end + +require 'tk/canvas' + +module TkcTagAccess + def addtag(tag) + @c.addtag(tag, 'withtag', @id) + self + end + + def bbox + @c.bbox(@id) + end + + #def bind(seq, cmd=Proc.new, *args) + # @c.itembind(@id, seq, cmd, *args) + # self + #end + def bind(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @c.itembind(@id, seq, cmd, *args) + self + end + + #def bind_append(seq, cmd=Proc.new, *args) + # @c.itembind_append(@id, seq, cmd, *args) + # self + #end + def bind_append(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @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 current_configinfo(key=nil) + @c.current_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 + alias deltag dtag + + 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(idx) + @c.index(@id, idx) + 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 TkcTag<TkObject + include TkcTagAccess + + CTagID_TBL = TkCore::INTERP.create_table + Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ CTagID_TBL.clear } + + def TkcTag.id2obj(canvas, id) + cpath = canvas.path + return id unless CTagID_TBL[cpath] + CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id + end + + def initialize(parent, mode=nil, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + # @path = @id = Tk_CanvasTag_ID.join('') + @path = @id = Tk_CanvasTag_ID.join(TkCore::INTERP._ip_id_) + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + Tk_CanvasTag_ID[1].succ! + if mode + tk_call_without_enc(@c.path, "addtag", @id, mode, *args) + end + end + def id + @id + end + + def exist? + if @c.find_withtag(@id) + true + else + false + end + end + + def delete + @c.delete @id + CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath] + self + end + alias remove delete + alias destroy delete + + def set_to_above(target) + @c.addtag_above(@id, target) + self + end + alias above set_to_above + + def set_to_all + @c.addtag_all(@id) + self + end + alias all set_to_all + + def set_to_below(target) + @c.addtag_below(@id, target) + self + end + alias below set_to_below + + def set_to_closest(x, y, halo=None, start=None) + @c.addtag_closest(@id, x, y, halo, start) + self + end + alias closest set_to_closest + + def set_to_enclosed(x1, y1, x2, y2) + @c.addtag_enclosed(@id, x1, y1, x2, y2) + self + end + alias enclosed set_to_enclosed + + def set_to_overlapping(x1, y1, x2, y2) + @c.addtag_overlapping(@id, x1, y1, x2, y2) + self + end + alias overlapping set_to_overlapping + + def set_to_withtag(target) + @c.addtag_withtag(@id, target) + self + end + alias withtag set_to_withtag +end + +class TkcTagString<TkcTag + def self.new(parent, name, *args) + if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name] + return CTagID_TBL[parent.path][name] + else + super(parent, name, *args) + end + end + + def initialize(parent, name, mode=nil, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + @path = @id = name + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + if mode + tk_call_without_enc(@c.path, "addtag", @id, mode, *args) + end + end +end +TkcNamedTag = TkcTagString + +class TkcTagAll<TkcTag + def initialize(parent) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + @path = @id = 'all' + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + end +end + +class TkcTagCurrent<TkcTag + def initialize(parent) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + @path = @id = 'current' + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + end +end + +class TkcGroup<TkcTag + Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint].freeze + #def create_self(parent, *args) + def initialize(parent, *args) + #unless parent.kind_of?(TkCanvas) + # fail ArgumentError, "expect TkCanvas for 1st argument" + #end + @c = parent + @cpath = parent.path + # @path = @id = Tk_cGroup_ID.join('') + @path = @id = Tk_cGroup_ID.join(TkCore::INTERP._ip_id_) + CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath] + CTagID_TBL[@cpath][@id] = self + Tk_cGroup_ID[1].succ! + include(*args) if args != [] + end + #private :create_self + + def include(*tags) + for i in tags + #i.addtag(@id) + @c.addtag_withtag(@id, i) + end + self + end + alias add include + + def exclude(*tags) + for i in tags + #i.dtag(@id) + @c.dtag(i, @id) + end + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/checkbutton.rb b/ruby_1_8_6/ext/tk/lib/tk/checkbutton.rb new file mode 100644 index 0000000000..d76d99c0f2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/checkbutton.rb @@ -0,0 +1,25 @@ +# +# tk/checkbutton.rb : treat checkbutton widget +# +require 'tk' +require 'tk/radiobutton' + +class TkCheckButton<TkRadioButton + TkCommandNames = ['checkbutton'.freeze].freeze + WidgetClassName = 'Checkbutton'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('checkbutton', @path) + # end + #end + #private :create_self + + def toggle + tk_send_without_enc('toggle') + self + end +end +TkCheckbutton = TkCheckButton diff --git a/ruby_1_8_6/ext/tk/lib/tk/clipboard.rb b/ruby_1_8_6/ext/tk/lib/tk/clipboard.rb new file mode 100644 index 0000000000..d4205a5c28 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/clipboard.rb @@ -0,0 +1,75 @@ +# +# tk/clipboard.rb : methods to treat clipboard +# +require 'tk' + +module TkClipboard + include Tk + extend Tk + + TkCommandNames = ['clipboard'.freeze].freeze + + def self.clear(win=nil) + if win + tk_call_without_enc('clipboard', 'clear', '-displayof', win) + else + tk_call_without_enc('clipboard', 'clear') + end + end + def self.clear_on_display(win) + tk_call_without_enc('clipboard', 'clear', '-displayof', win) + end + + def self.get(type=nil) + if type + tk_call_without_enc('clipboard', 'get', '-type', type) + else + tk_call_without_enc('clipboard', 'get') + end + end + def self.get_on_display(win, type=nil) + if type + tk_call_without_enc('clipboard', 'get', '-displayof', win, '-type', type) + else + tk_call_without_enc('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.concat(hash_kv(keys)) + args.concat(['--', data]) + tk_call(*args) + end + def self.append_on_display(win, data, keys=nil) + args = ['clipboard', 'append', '-displayof', win] + args.concat(hash_kv(keys)) + args.concat(['--', 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 diff --git a/ruby_1_8_6/ext/tk/lib/tk/clock.rb b/ruby_1_8_6/ext/tk/lib/tk/clock.rb new file mode 100644 index 0000000000..4e9438f5ab --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/clock.rb @@ -0,0 +1,71 @@ +# +# tk/clock.rb : methods for clock command +# +require 'tk' + +module Tk + module Clock + include Tk + extend TkCore + + def self.add(clk, *args) + tk_call_without_enc('clock','add', clk, *args).to_i + end + + def self.clicks(ms=nil) + ms = ms.to_s if ms.kind_of?(Symbol) + case ms + when nil, '' + tk_call_without_enc('clock','clicks').to_i + when /^mic/ + tk_call_without_enc('clock','clicks','-microseconds').to_i + when /^mil/ + tk_call_without_enc('clock','clicks','-milliseconds').to_i + else + tk_call_without_enc('clock','clicks','-milliseconds').to_i + end + end + + def self.format(clk, form=nil) + if form + tk_call('clock','format',clk,'-format',form) + else + tk_call('clock','format',clk) + end + end + + def self.formatGMT(clk, form=nil) + if form + tk_call('clock','format',clk,'-format',form,'-gmt','1') + else + tk_call('clock','format',clk,'-gmt','1') + end + end + + def self.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 self.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 self.seconds + tk_call_without_enc('clock','seconds').to_i + end + def self.milliseconds + tk_call_without_enc('clock','milliseconds').to_i + end + def self.microseconds + tk_call_without_enc('clock','microseconds').to_i + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/composite.rb b/ruby_1_8_6/ext/tk/lib/tk/composite.rb new file mode 100644 index 0000000000..eaed8ed363 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/composite.rb @@ -0,0 +1,394 @@ +# +# tk/composite.rb : +# +require 'tk' + +module TkComposite + include Tk + extend Tk + +=begin + def initialize(parent=nil, *args) + @delegates = {} + @option_methods = {} + @option_setting = {} + + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + @frame = TkFrame.new(parent) + @path = @epath = @frame.path + initialize_composite(keys) + else + @frame = TkFrame.new(parent) + @path = @epath = @frame.path + initialize_composite(*args) + end + end +=end + + def _choice_classname_of_baseframe + base_class_name = nil + + klass = WidgetClassNames[self.class::WidgetClassName] + + if klass + # WidgetClassName is a known class + if klass <= TkFrame || klass < TkComposite + # klass is valid for the base frame + if self.class <= klass + # use my classname + base_class_name = self.class.name + if base_class_name == '' + # anonymous class -> use ancestor's name + base_class_name = klass.name + end + else + # not subclass -> use WidgetClassName + base_class_name = klass.name + end + + else + # klass is invalid for the base frame + if self.class < TkFrame || self.class.superclass < TkComposite + # my class name is valid for the base frame -> use my classname + base_class_name = self.class.name + if base_class_name == '' + # anonymous class -> use TkFrame + base_class_name = nil + end + else + # no idea for the base frame -> use TkFrame + base_class_name = nil + end + end + + elsif self.class::WidgetClassName && ! self.class::WidgetClassName.empty? + # unknown WidgetClassName is defined -> use it for the base frame + base_class_name = self.class::WidgetClassName + + else + # no valid WidgetClassName + if self.class < TkFrame || self.class.superclass < TkComposite + # my class name is valid for the base frame -> use my classname + base_class_name = self.class.name + if base_class_name == '' + # anonymous class -> use TkFrame + base_class_name = nil + end + else + # no idea for the base frame -> use TkFrame + base_class_name = nil + end + end + + base_class_name + end + private :_choice_classname_of_baseframe + + # def initialize(parent=nil, *args) + def initialize(*args) + @delegates = {} + @option_methods = {} + @option_setting = {} + + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = {} + end + parent = args.shift + parent = keys.delete('parent') if keys.has_key?('parent') + + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + if (base_class_name = (keys.delete('class')).to_s).empty? + base_class_name = _choice_classname_of_baseframe + end + + if base_class_name + @frame = TkFrame.new(parent, :class=>base_class_name) + else + @frame = TkFrame.new(parent) + end + @path = @epath = @frame.path + + args.push(keys) unless keys.empty? + initialize_composite(*args) + end + + def database_classname + @frame.database_classname + end + + def database_class + @frame.database_class + end + + def epath + @epath + end + + def initialize_composite(*args) end + private :initialize_composite + + def option_methods(*opts) + opts.each{|m_set, m_cget, m_info| + m_set = m_set.to_s + m_cget = m_set if !m_cget && self.method(m_set).arity == -1 + m_cget = m_cget.to_s if m_cget + m_info = m_info.to_s if m_info + @option_methods[m_set] = { + :set => m_set, :cget => m_cget, :info => m_info + } + } + end + + def delegate_alias(alias_opt, option, *wins) + if wins.length == 0 + fail ArgumentError, "target widgets are not given" + end + if alias_opt != option && (alias_opt == 'DEFAULT' || option == 'DEFAULT') + fail ArgumentError, "cannot alias 'DEFAULT' option" + end + alias_opt = alias_opt.to_s + option = option.to_s + if @delegates[alias_opt].kind_of?(Array) + if (elem = @delegates[alias_opt].assoc(option)) + wins.each{|w| elem[1].push(w)} + else + @delegates[alias_opt] << [option, wins] + end + else + @delegates[alias_opt] = [ [option, wins] ] + end + end + + def delegate(option, *wins) + delegate_alias(option, option, *wins) + end + + def cget(slot) + slot = slot.to_s + + if @option_methods.include?(slot) + if @option_methods[slot][:cget] + return self.__send__(@option_methods[slot][:cget]) + else + if @option_setting[slot] + return @option_setting[slot] + else + return '' + end + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + opt, wins = tbl[-1] + opt = slot if opt == 'DEFAULT' + if wins && wins[-1] + return wins[-1].cget(opt) + end + end + rescue + end + + super(slot) + end + + def configure(slot, value=None) + if slot.kind_of? Hash + slot.each{|slot,value| configure slot, value} + return self + end + + slot = slot.to_s + + if @option_methods.include?(slot) + unless @option_methods[slot][:cget] + if value.kind_of?(Symbol) + @option_setting[slot] = value.to_s + else + @option_setting[slot] = value + end + end + return self.__send__(@option_methods[slot][:set], value) + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + last = nil + tbl.each{|opt, wins| + opt = slot if opt == 'DEFAULT' + wins.each{|w| last = w.configure(opt, value)} + } + return last + end + rescue + end + + super(slot, value) + end + + def configinfo(slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + slot = slot.to_s + if @option_methods.include?(slot) + if @option_methods[slot][:info] + return self.__send__(@option_methods[slot][:info]) + else + return [slot, '', '', '', self.cget(slot)] + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + if tbl.length == 1 + opt, wins = tbl[0] + if slot == opt || opt == 'DEFAULT' + return wins[-1].configinfo(slot) + else + info = wins[-1].configinfo(opt) + info[0] = slot + return info + end + else + opt, wins = tbl[-1] + return [slot, '', '', '', wins[-1].cget(opt)] + end + end + rescue + end + + super(slot) + + else # slot == nil + info_list = super(slot) + + tbl = @delegates['DEFAULT'] + if tbl + wins = tbl[0][1] + if wins && wins[-1] + wins[-1].configinfo.each{|info| + slot = info[0] + info_list.delete_if{|i| i[0] == slot} << info + } + end + end + + @delegates.each{|slot, tbl| + next if slot == 'DEFAULT' + if tbl.length == 1 + opt, wins = tbl[0] + next unless wins && wins[-1] + if slot == opt + info_list.delete_if{|i| i[0] == slot} << + wins[-1].configinfo(slot) + else + info = wins[-1].configinfo(opt) + info[0] = slot + info_list.delete_if{|i| i[0] == slot} << info + end + else + opt, wins = tbl[-1] + info_list.delete_if{|i| i[0] == slot} << + [slot, '', '', '', wins[-1].cget(opt)] + end + } + + @option_methods.each{|slot, m| + if m[:info] + info = self.__send__(m[:info]) + else + info = [slot, '', '', '', self.cget(slot)] + end + info_list.delete_if{|i| i[0] == slot} << info + } + + info_list + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + slot = slot.to_s + if @option_methods.include?(slot) + if @option_methods[slot][:info] + return self.__send__(@option_methods[slot][:info]) + else + return {slot => ['', '', '', self.cget(slot)]} + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + if tbl.length == 1 + opt, wins = tbl[0] + if slot == opt || opt == 'DEFAULT' + return wins[-1].configinfo(slot) + else + return {slot => wins[-1].configinfo(opt)[opt]} + end + else + opt, wins = tbl[-1] + return {slot => ['', '', '', wins[-1].cget(opt)]} + end + end + rescue + end + + super(slot) + + else # slot == nil + info_list = super(slot) + + tbl = @delegates['DEFAULT'] + if tbl + wins = tbl[0][1] + info_list.update(wins[-1].configinfo) if wins && wins[-1] + end + + @delegates.each{|slot, tbl| + next if slot == 'DEFAULT' + if tbl.length == 1 + opt, wins = tbl[0] + next unless wins && wins[-1] + if slot == opt + info_list.update(wins[-1].configinfo(slot)) + else + info_list.update({slot => wins[-1].configinfo(opt)[opt]}) + end + else + opt, wins = tbl[-1] + info_list.update({slot => ['', '', '', wins[-1].cget(opt)]}) + end + } + + @option_methods.each{|slot, m| + if m[:info] + info = self.__send__(m[:info]) + else + info = {slot => ['', '', '', self.cget(slot)]} + end + info_list.update(info) + } + + info_list + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/console.rb b/ruby_1_8_6/ext/tk/lib/tk/console.rb new file mode 100644 index 0000000000..26ce262caa --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/console.rb @@ -0,0 +1,52 @@ +# +# tk/console.rb : control the console on system without a real console +# +require 'tk' + +module TkConsole + include Tk + extend Tk + + TkCommandNames = ['console'.freeze, 'consoleinterp'.freeze].freeze + + def self.create + TkCore::INTERP._create_console + end + self.create # initialize console + + def self.title(str=None) + tk_call 'console', str + end + def self.hide + tk_call_without_enc('console', 'hide') + end + def self.show + tk_call_without_enc('console', 'show') + end + def self.eval(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + _fromUTF8(tk_call_without_enc('console', 'eval', + _get_eval_enc_str(tcl_script))) + end + def self.maininterp_eval(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + _fromUTF8(tk_call_without_enc('consoleinterp', 'eval', + _get_eval_enc_str(tcl_script))) + + end + def self.maininterp_record(tcl_script) + # + # supports a Tcl script only + # I have no idea to support a Ruby script seamlessly. + # + _fromUTF8(tk_call_without_enc('consoleinterp', 'record', + _get_eval_enc_str(tcl_script))) + + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/dialog.rb b/ruby_1_8_6/ext/tk/lib/tk/dialog.rb new file mode 100644 index 0000000000..180da101e3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/dialog.rb @@ -0,0 +1,326 @@ +# +# tk/dialog.rb : create dialog boxes +# +require 'tk' +require 'tk/variable.rb' + +class TkDialogObj < TkWindow + extend Tk + + TkCommandNames = ['tk_dialog'.freeze].freeze + + def self.show(*args) + dlog = self.new(*args) + dlog.show + dlog + end + + def _set_button_config(configs) + set_config = proc{|c,i| + if $VERBOSE && (c.has_key?('command') || c.has_key?(:command)) + STDERR.print("Warning: cannot give a command option " + + "to the dialog button#{i}. It was removed.\n") + end + c.delete('command'); c.delete(:command) + # @config << Kernel.format("%s.button%s configure %s; ", + # @path, i, hash_kv(c).join(' ')) + # @config << @path+'.button'+i.to_s+' configure '+hash_kv(c).join(' ')+'; ' + @config << @path+'.button'+i.to_s+' configure '+ + array2tk_list(hash_kv(c))+'; ' + } + case configs + when Proc + @buttons.each_index{|i| + if (c = configs.call(i)).kind_of?(Hash) + set_config.call(c,i) + end + } + + when Array + @buttons.each_index{|i| + if (c = configs[i]).kind_of?(Hash) + set_config.call(c,i) + end + } + + when Hash + @buttons.each_with_index{|s,i| + if (c = configs[s]).kind_of?(Hash) + set_config.call(c,i) + end + } + end + # @config = 'after idle {' + @config + '};' if @config != "" + @config = array2tk_list(['after', 'idle', @config]) << ';' if @config != "" + end + private :_set_button_config + + # initialize tk_dialog + def create_self(keys) + # @var = TkVariable.new + @val = nil + + @title = title + + @message = message + @message_config = message_config + @msgframe_config = msgframe_config + + @bitmap = bitmap + @bitmap_config = message_config + + @default_button = default_button + + @buttons = buttons + @button_configs = proc{|num| button_configs(num)} + @btnframe_config = btnframe_config + + #@config = "puts [winfo children .w0000];" + @config = "" + + @command = prev_command + + if keys.kind_of?(Hash) + @title = keys['title'] if keys.key? 'title' + @message = keys['message'] if keys.key? 'message' + @bitmap = keys['bitmap'] if keys.key? 'bitmap' + # @bitmap = '{}' if @bitmap == nil || @bitmap == "" + @bitmap = '' unless @bitmap + @default_button = keys['default'] if keys.key? 'default' + @buttons = keys['buttons'] if keys.key? 'buttons' + + @command = keys['prev_command'] if keys.key? 'prev_command' + + @message_config = keys['message_config'] if keys.key? 'message_config' + @msgframe_config = keys['msgframe_config'] if keys.key? 'msgframe_config' + @bitmap_config = keys['bitmap_config'] if keys.key? 'bitmap_config' + @button_configs = keys['button_configs'] if keys.key? 'button_configs' + @btnframe_config = keys['btnframe_config'] if keys.key? 'btnframe_config' + end + + #if @title.include? ?\s + # @title = '{' + @title + '}' + #end + + if @buttons.kind_of?(Array) + _set_button_config(@buttons.collect{|cfg| + (cfg.kind_of? Array)? cfg[1]: nil}) + @buttons = @buttons.collect{|cfg| (cfg.kind_of? Array)? cfg[0]: cfg} + end + if @buttons.kind_of?(Hash) + _set_button_config(@buttons) + @buttons = @buttons.keys + end + @buttons = tk_split_simplelist(@buttons) if @buttons.kind_of?(String) + @buttons = [] unless @buttons +=begin + @buttons = @buttons.collect{|s| + if s.kind_of?(Array) + s = s.join(' ') + end + if s.include? ?\s + '{' + s + '}' + else + s + end + } +=end + + if @message_config.kind_of?(Hash) + # @config << Kernel.format("%s.msg configure %s;", + # @path, hash_kv(@message_config).join(' ')) + # @config << @path+'.msg configure '+hash_kv(@message_config).join(' ')+';' + @config << @path+'.msg configure '+ + array2tk_list(hash_kv(@message_config))+';' + end + + if @msgframe_config.kind_of?(Hash) + # @config << Kernel.format("%s.top configure %s;", + # @path, hash_kv(@msgframe_config).join(' ')) + # @config << @path+'.top configure '+hash_kv(@msgframe_config).join(' ')+';' + @config << @path+'.top configure '+ + array2tk_list(hash_kv(@msgframe_config))+';' + end + + if @btnframe_config.kind_of?(Hash) + # @config << Kernel.format("%s.bot configure %s;", + # @path, hash_kv(@btnframe_config).join(' ')) + # @config << @path+'.bot configure '+hash_kv(@btnframe_config).join(' ')+';' + @config << @path+'.bot configure '+ + array2tk_list(hash_kv(@btnframe_config))+';' + end + + if @bitmap_config.kind_of?(Hash) + # @config << Kernel.format("%s.bitmap configure %s;", + # @path, hash_kv(@bitmap_config).join(' ')) + # @config << @path+'.bitmap configure '+hash_kv(@bitmap_config).join(' ')+';' + @config << @path+'.bitmap configure '+ + array2tk_list(hash_kv(@bitmap_config))+';' + end + + _set_button_config(@button_configs) if @button_configs + end + private :create_self + + def show + # if @command.kind_of?(Proc) + if TkComm._callback_entry?(@command) + @command.call(self) + end + + if @default_button.kind_of?(String) + default_button = @buttons.index(@default_button) + else + default_button = @default_button + end + # default_button = '{}' if default_button == nil + default_button = '' if default_button == nil + #Tk.ip_eval('eval {global '+@var.id+';'+@config+ + # 'set '+@var.id+' [tk_dialog '+ + # @path+" "+@title+" {#{@message}} "+@bitmap+" "+ + # String(default_button)+" "+@buttons.join(' ')+']}') + Tk.ip_eval(@config) + # @val = Tk.ip_eval('tk_dialog ' + @path + ' ' + @title + + # ' {' + @message + '} ' + @bitmap + ' ' + + # String(default_button) + ' ' + @buttons.join(' ')).to_i + # @val = Tk.ip_eval(self.class::TkCommandNames[0] + ' ' + @path + ' ' + + # @title + ' {' + @message + '} ' + @bitmap + ' ' + + # String(default_button) + ' ' + @buttons.join(' ')).to_i + @val = Tk.ip_eval(array2tk_list([ + self.class::TkCommandNames[0], + @path, @title, @message, @bitmap, + String(default_button) + ].concat(@buttons))).to_i + end + + def value + # @var.value.to_i + @val + end + + def name + (@val)? @buttons[@val]: nil + end + + ############################################################ + # # + # following methods should be overridden for each dialog # + # # + ############################################################ + private + + def title + # returns a title string of the dialog window + return "DIALOG" + end + def message + # returns a message text to display on the dialog + return "MESSAGE" + end + def message_config + # returns a Hash {option=>value, ...} 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 + def prev_command + # returns nil or a Proc + return nil + end +end +TkDialog2 = TkDialogObj + +# +# TkDialog : with showing at initialize +# +class TkDialog < TkDialogObj + def self.show(*args) + self.new(*args) + end + + def initialize(*args) + super(*args) + show + end +end + + +# +# dialog for warning +# +class TkWarningObj < TkDialogObj + 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 +TkWarning2 = TkWarningObj + +class TkWarning < TkWarningObj + def self.show(*args) + self.new(*args) + end + def initialize(*args) + super(*args) + show + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/encodedstr.rb b/ruby_1_8_6/ext/tk/lib/tk/encodedstr.rb new file mode 100644 index 0000000000..797e514a4c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/encodedstr.rb @@ -0,0 +1,111 @@ +# +# 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) ) + @encoding = ( enc || + ((self.class::Encoding)? + self.class::Encoding : + ((Tk.encoding)? Tk.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/ruby_1_8_6/ext/tk/lib/tk/entry.rb b/ruby_1_8_6/ext/tk/lib/tk/entry.rb new file mode 100644 index 0000000000..4ac3f28229 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/entry.rb @@ -0,0 +1,117 @@ +# +# tk/entry.rb - Tk entry classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> + +require 'tk' +require 'tk/label' +require 'tk/scrollable' +require 'tk/validation' + +class TkEntry<TkLabel + include X_Scrollable + include TkValidation + + TkCommandNames = ['entry'.freeze].freeze + WidgetClassName = 'Entry'.freeze + WidgetClassNames[WidgetClassName] = self + + #def create_self(keys) + # super(__conv_vcmd_on_hash_kv(keys)) + #end + #private :create_self + + def __strval_optkeys + super() + ['show', 'disabledbackground', 'readonlybackground'] + end + private :__strval_optkeys + + def bbox(index) + list(tk_send_without_enc('bbox', index)) + end + def cursor + number(tk_send_without_enc('index', 'insert')) + end + alias icursor cursor + def cursor=(index) + tk_send_without_enc('icursor', index) + #self + index + end + alias icursor= cursor= + def index(idx) + number(tk_send_without_enc('index', idx)) + end + def insert(pos,text) + tk_send_without_enc('insert', pos, _get_eval_enc_str(text)) + self + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def mark(pos) + tk_send_without_enc('scan', 'mark', pos) + self + end + def dragto(pos) + tk_send_without_enc('scan', 'dragto', pos) + self + end + def selection_adjust(index) + tk_send_without_enc('selection', 'adjust', index) + self + end + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + def selection_from(index) + tk_send_without_enc('selection', 'from', index) + self + end + def selection_present() + bool(tk_send_without_enc('selection', 'present')) + end + def selection_range(s, e) + tk_send_without_enc('selection', 'range', s, e) + self + end + def selection_to(index) + tk_send_without_enc('selection', 'to', index) + self + end + + def invoke_validate + bool(tk_send_without_enc('validate')) + end + def validate(mode = nil) + if mode + configure 'validate', mode + else + invoke_validate + end + end + + def value + _fromUTF8(tk_send_without_enc('get')) + end + def value= (val) + tk_send_without_enc('delete', 0, 'end') + tk_send_without_enc('insert', 0, _get_eval_enc_str(val)) + val + end + alias get value + alias set value= + + def [](*args) + self.value[*args] + end + def []=(*args) + val = args.pop + str = self.value + str[*args] = val + self.value = str + val + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/event.rb b/ruby_1_8_6/ext/tk/lib/tk/event.rb new file mode 100644 index 0000000000..70a1e38bbe --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/event.rb @@ -0,0 +1,488 @@ +# +# tk/event.rb - module for event +# + +module TkEvent +end + +######################## + +require 'tkutil' +require 'tk' + +######################## + +module TkEvent + class Event < TkUtil::CallbackSubst + module Grp + KEY = 0x1 + BUTTON = 0x2 + MOTION = 0x4 + CROSSING = 0x8 + FOCUS = 0x10 + EXPOSE = 0x20 + VISIBILITY = 0x40 + CREATE = 0x80 + DESTROY = 0x100 + UNMAP = 0x200 + MAP = 0x400 + REPARENT = 0x800 + CONFIG = 0x1000 + GRAVITY = 0x2000 + CIRC = 0x4000 + PROP = 0x8000 + COLORMAP = 0x10000 + VIRTUAL = 0x20000 + ACTIVATE = 0x40000 + MAPREQ = 0x80000 + CONFIGREQ = 0x100000 + RESIZEREQ = 0x200000 + CIRCREQ = 0x400000 + + MWHEEL = 0x10000000 + + ALL = 0xFFFFFFFF + + KEY_BUTTON_MOTION_VIRTUAL = (KEY|MWHEEL|BUTTON|MOTION|VIRTUAL) + KEY_BUTTON_MOTION_CROSSING = (KEY|MWHEEL|BUTTON|MOTION|CROSSING|VIRTUAL) + end + + type_data = [ + #-----+-------------------+------------------+-----------------------# + # ID | const | group_flag | context_name # + #-----+-------------------+------------------+-----------------------# + [ 2, :KeyPress, Grp::KEY, 'KeyPress', 'Key' ], + [ 3, :KeyRelease, Grp::KEY, 'KeyRelease' ], + [ 4, :ButtonPress, Grp::BUTTON, 'ButtonPress', 'Button' ], + [ 5, :ButtonRelease, Grp::BUTTON, 'ButtonRelease' ], + [ 6, :MotionNotify, Grp::MOTION, 'Motion' ], + [ 7, :EnterNotify, Grp::CROSSING, 'Enter' ], + [ 8, :LeaveNotify, Grp::CROSSING, 'Leave' ], + [ 9, :FocusIn, Grp::FOCUS, 'FocusIn' ], + [ 10, :FocusOut, Grp::FOCUS, 'FocusOut' ], + [ 11, :KeymapNotify, 0, ], + [ 12, :Expose, Grp::EXPOSE, 'Expose' ], + [ 13, :GraphicsExpose, Grp::EXPOSE, ], + [ 14, :NoExpose, 0, ], + [ 15, :VisibilityNotify, Grp::VISIBILITY, 'Visibility' ], + [ 16, :CreateNotify, Grp::CREATE, 'Create' ], + [ 17, :DestroyNotify, Grp::DESTROY, 'Destroy' ], + [ 18, :UnmapNotify, Grp::UNMAP, 'Unmap' ], + [ 19, :MapNotify, Grp::MAP, 'Map' ], + [ 20, :MapRequest, Grp::MAPREQ, 'MapRequest' ], + [ 21, :ReparentNotify, Grp::REPARENT, 'Reparent' ], + [ 22, :ConfigureNotify, Grp::CONFIG, 'Configure' ], + [ 23, :ConfigureRequest, Grp::CONFIGREQ, 'ConfigureRequest' ], + [ 24, :GravityNotify, Grp::GRAVITY, 'Gravity' ], + [ 25, :ResizeRequest, Grp::RESIZEREQ, 'ResizeRequest' ], + [ 26, :CirculateNotify, Grp::CIRC, 'Circulate' ], + [ 27, :CirculateRequest, 0, 'CirculateRequest' ], + [ 28, :PropertyNotify, Grp::PROP, 'Property' ], + [ 29, :SelectionClear, 0, ], + [ 30, :SelectionRequest, 0, ], + [ 31, :SelectionNotify, 0, ], + [ 32, :ColormapNotify, Grp::COLORMAP, 'Colormap' ], + [ 33, :ClientMessage, 0, ], + [ 34, :MappingNotify, 0, ], + [ 35, :VirtualEvent, Grp::VIRTUAL, ], + [ 36, :ActivateNotify, Grp::ACTIVATE, 'Activate' ], + [ 37, :DeactivateNotify, Grp::ACTIVATE, 'Deactivate' ], + [ 38, :MouseWheelEvent, Grp::MWHEEL, 'MouseWheel' ], + [ 39, :TK_LASTEVENT, 0, ] + ] + + module TypeNum + end + + TYPE_NAME_TBL = Hash.new + TYPE_ID_TBL = Hash.new + TYPE_GROUP_TBL = Hash.new + + type_data.each{|id, c_name, g_flag, *t_names| + TypeNum.const_set(c_name, id) + t_names.each{|t_name| t_name.freeze; TYPE_NAME_TBL[t_name] = id } + TYPE_ID_TBL[id] = t_names + TYPE_GROUP_TBL[id] = g_flag + } + + TYPE_NAME_TBL.freeze + TYPE_ID_TBL.freeze + + def self.type_id(name) + TYPE_NAME_TBL[name.to_s] + end + + def self.type_name(id) + TYPE_ID_TBL[id] && TYPE_ID_TBL[id][0] + end + + def self.group_flag(id) + TYPE_GROUP_TBL[id] || 0 + end + + ############################################# + + module StateMask + ShiftMask = (1<<0) + LockMask = (1<<1) + ControlMask = (1<<2) + Mod1Mask = (1<<3) + Mod2Mask = (1<<4) + Mod3Mask = (1<<5) + Mod4Mask = (1<<6) + Mod5Mask = (1<<7) + Button1Mask = (1<<8) + Button2Mask = (1<<9) + Button3Mask = (1<<10) + Button4Mask = (1<<11) + Button5Mask = (1<<12) + + AnyModifier = (1<<15) + + META_MASK = (AnyModifier<<1) + ALT_MASK = (AnyModifier<<2) + EXTENDED_MASK = (AnyModifier<<3) + + CommandMask = Mod1Mask + OptionMask = Mod2Mask + end + + ############################################# + + FIELD_FLAG = { + # key => flag + 'above' => Grp::CONFIG, + 'borderwidth' => (Grp::CREATE|Grp::CONFIG), + 'button' => Grp::BUTTON, + 'count' => Grp::EXPOSE, + 'data' => Grp::VIRTUAL, + 'delta' => Grp::MWHEEL, + 'detail' => (Grp::FOCUS|Grp::CROSSING), + 'focus' => Grp::CROSSING, + 'height' => (Grp::EXPOSE|Grp::CONFIG), + 'keycode' => Grp::KEY, + 'keysym' => Grp::KEY, + 'mode' => (Grp::CROSSING|Grp::FOCUS), + 'override' => (Grp::CREATE|Grp::MAP|Grp::REPARENT|Grp::CONFIG), + 'place' => Grp::CIRC, + 'root' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'rootx' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'rooty' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'sendevent' => Grp::ALL, + 'serial' => Grp::ALL, + 'state' => (Grp::KEY_BUTTON_MOTION_VIRTUAL| + Grp::CROSSING|Grp::VISIBILITY), + 'subwindow' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING), + 'time' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| + Grp::PROP), + 'warp' => Grp::KEY_BUTTON_MOTION_VIRTUAL, + 'width' => (Grp::EXPOSE|Grp::CREATE|Grp::CONFIG), + 'window' => (Grp::CREATE|Grp::UNMAP|Grp::MAP|Grp::REPARENT| + Grp::CONFIG|Grp::GRAVITY|Grp::CIRC), + 'when' => Grp::ALL, + 'x' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| + Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY| + Grp::REPARENT), + 'y' => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING| + Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY| + Grp::REPARENT), + } + + FIELD_OPERATION = { + 'root' => proc{|val| + begin + Tk.tk_call_without_enc('winfo', 'pathname', val) + val + rescue + nil + end + }, + + 'subwindow' => proc{|val| + begin + Tk.tk_call_without_enc('winfo', 'pathname', val) + val + rescue + nil + end + }, + + 'window' => proc{|val| nil} + } + + #------------------------------------------- + + def valid_fields(group_flag=nil) + group_flag = self.class.group_flag(self.type) unless group_flag + + fields = {} + FIELD_FLAG.each{|key, flag| + next if (flag & group_flag) == 0 + begin + val = self.__send__(key) + rescue + next + end + next if !val || val == '??' + fields[key] = val + } + + fields + end + + def valid_for_generate(group_flag=nil) + fields = valid_fields(group_flag) + + FIELD_OPERATION.each{|key, cmd| + next unless fields.has_key?(key) + val = FIELD_OPERATION[key].call(fields[key]) + if val + fields[key] = val + else + fields.delete(key) + end + } + + fields + end + + def generate(win, modkeys={}) + klass = self.class + + if modkeys.has_key?(:type) || modkeys.has_key?('type') + modkeys = TkComm._symbolkey2str(modkeys) + type_id = modkeys.delete('type') + else + type_id = self.type + end + + type_name = klass.type_name(type_id) + unless type_name + fail RuntimeError, "type_id #{type_id} is invalid" + end + + group_flag = klass.group_flag(type_id) + + opts = valid_for_generate(group_flag) + + modkeys.each{|key, val| + if val + opts[key.to_s] = val + else + opts.delete(key.to_s) + end + } + + if group_flag != Grp::KEY + Tk.event_generate(win, type_name, opts) + else + # If type is KEY event, focus should be set to target widget. + # If not set, original widget will get the same event. + # That will make infinite loop. + w = Tk.tk_call_without_enc('focus') + begin + Tk.tk_call_without_enc('focus', win) + Tk.event_generate(win, type_name, opts) + ensure + Tk.tk_call_without_enc('focus', w) + end + end + end + + ############################################# + + # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>] + 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 ], + [ ?P, ?s, :property ], + [ ?R, ?s, :rootwin_id ], + [ ?S, ?s, :subwindow ], + [ ?T, ?n, :type ], + [ ?W, ?w, :widget ], + [ ?X, ?n, :x_root ], + [ ?Y, ?n, :y_root ], + nil + ] + + # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>] + 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); + + # + # NOTE: The order of parameters which passed to callback procedure is + # <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ... + # + + # If you need support extra arguments given by Tcl/Tk, + # please override _get_extra_args_tbl + # + #def self._get_extra_args_tbl + # # return an array of convert procs + # [] + #end + +=begin + alias button num + alias delta wheel_delta + alias root rootwin_id + alias rootx x_root + alias root_x x_root + alias rooty y_root + alias root_y y_root + alias sendevent send_event +=end + ALIAS_TBL = { + :button => :num, + :data => :detail, + :delta => :wheel_delta, + :root => :rootwin_id, + :rootx => :x_root, + :root_x => :x_root, + :rooty => :y_root, + :root_y => :y_root, + :sendevent => :send_event, + :window => :widget + } + + _define_attribute_aliases(ALIAS_TBL) + + end + + ############################################### + + def install_bind_for_event_class(klass, cmd, *args) + extra_args_tbl = klass._get_extra_args_tbl + + if args.compact.size > 0 + args = args.join(' ') + keys = klass._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| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + begin + TkUtil.eval_cmd(cmd, *(ex_args.concat(klass.scan_args(keys, arg)))) + rescue Exception=>e + if TkCore::INTERP.kind_of?(TclTkIp) + fail e + else + # MultiTkIp + fail Exception, "#{e.class}: #{e.message.dup}" + end + end + }) + end + else + keys, args = klass._get_all_subst_keys + + if cmd.kind_of?(String) + id = cmd + elsif cmd.kind_of?(TkCallbackEntry) + id = install_cmd(cmd) + else + id = install_cmd(proc{|*arg| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + begin + TkUtil.eval_cmd(cmd, *(ex_args << klass.new(*klass.scan_args(keys, arg)))) + rescue Exception=>e + if TkCore::INTERP.kind_of?(TclTkIp) + fail e + else + # MultiTkIp + fail Exception, "#{e.class}: #{e.message.dup}" + end + end + }) + end + end + + if TkCore::INTERP.kind_of?(TclTkIp) + id + ' ' + args + else + # MultiTkIp + "if {[set st [catch {#{id} #{args}} ret]] != 0} { + if {$st == 4} { + return -code continue $ret + } elseif {$st == 3} { + return -code break $ret + } elseif {$st == 2} { + return -code return $ret + } elseif {[regexp {^Exception: (TkCallbackContinue: .*)$} \ + $ret m msg]} { + return -code continue $msg + } elseif {[regexp {^Exception: (TkCallbackBreak: .*)$} $ret m msg]} { + return -code break $msg + } elseif {[regexp {^Exception: (TkCallbackReturn: .*)$} $ret m msg]} { + return -code return $msg + } elseif {[regexp {^Exception: (\\S+: .*)$} $ret m msg]} { + return -code return $msg + } else { + return -code error $ret + } + } else { + set ret + }" + end + end + + def install_bind(cmd, *args) + install_bind_for_event_class(TkEvent::Event, cmd, *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/font.rb b/ruby_1_8_6/ext/tk/lib/tk/font.rb new file mode 100644 index 0000000000..ab58ac5762 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/font.rb @@ -0,0 +1,1762 @@ +# +# 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 + } + + # option_type : default => string + OptionType = Hash.new(?s) + OptionType['size'] = ?n + OptionType['pointadjust'] = ?n + OptionType['underline'] = ?b + OptionType['overstrike'] = ?b + + # metric_type : default => num_or_str + MetricType = Hash.new(?n) + MetricType['fixed'] = ?b + + # 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)') + platform = Tk::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)') + platform = Tk::PLATFORM['platform'] + case platform + when 'unix' + ltn = {'family'=>'Helvetica'.freeze, + 'size'=>-12, 'weight'=>'bold'.freeze} + when 'windows' + ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} + when 'macintosh' + ltn = 'system' + else # unknown + ltn = 'Helvetica' + end + rescue + ltn = 'Helvetica' + end + + knj = ltn.dup + 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 + when :kanji, :latin, :ascii + @type = type.to_s + 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.actual(fnt, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.actual(option) + else + actual_core(fnt, nil, option) + end + end + + def TkFont.actual_displayof(fnt, win, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.actual_displayof(win, option) + else + win = '.' unless win + actual_core(fnt, win, option) + end + end + + def TkFont.configure(fnt, slot, value=None) + if fnt.kind_of?(TkFont) + fnt.configure(fnt, slot, value) + else + configure_core(fnt, slot, value) + end + fnt + end + + def TkFont.configinfo(fnt, slot=nil) + if fnt.kind_of?(TkFont) + fnt.configinfo(fnt, slot) + else + configinfo_core(fnt, slot) + end + end + + def TkFont.current_configinfo(fnt, slot=nil) + if fnt.kind_of?(TkFont) + fnt.current_configinfo(fnt, slot) + else + current_configinfo_core(fnt, slot) + end + end + + def TkFont.measure(fnt, text) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.measure(text) + else + measure_core(fnt, nil, text) + end + end + + def TkFont.measure_displayof(fnt, win, text) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.measure_displayof(win, text) + else + win = '.' unless win + measure_core(fnt, win, text) + end + end + + def TkFont.metrics(fnt, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + fnt.metrics(option) + else + metrics_core(fnt, nil, option) + end + end + + def TkFont.metrics_displayof(fnt, win, option=nil) + fnt = '{}' if fnt == '' + if fnt.kind_of?(TkFont) + font.metrics_displayof(win, option=nil) + else + win = '.' unless win + metrics_core(fnt, win, option) + end + end + + def TkFont.families(win=nil) + case (Tk::TK_VERSION) + when /^4\.*/ + ['fixed'] + + when /^8\.*/ + if win + tk_split_simplelist(tk_call('font', 'families', '-displayof', win)) + 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(pathname, *args) + win, tag, key = pathname.split(';') + key = 'font' if key == nil || key == '' + path = [win, tag, key].join(';') + + case (Tk::TK_VERSION) + when /^4\.*/ + regexp = /^-(|kanji)#{key} / + + conf_list = tk_split_simplelist(tk_call(*args)). + find_all{|prop| prop =~ regexp}. + collect{|prop| tk_split_simplelist(prop)} + + if conf_list.size == 0 + raise RuntimeError, "the widget may not support 'font' option" + end + + args << {} + + ltn_key = "-#{key}" + knj_key = "-kanji#{key}" + + ltn_info = conf_list.find{|conf| conf[0] == ltn_key} + ltn = ltn_info[-1] + ltn = nil if ltn == [] || ltn == "" + + knj_info = conf_list.find{|conf| conf[0] == knj_key} + knj = knj_info[-1] + knj = nil if knj == [] || knj == "" + + TkFont.new(ltn, knj).call_font_configure([path, key], *args) + + when /^8\.*/ + regexp = /^-#{key} / + + conf_list = tk_split_simplelist(tk_call(*args)). + find_all{|prop| prop =~ regexp}. + collect{|prop| tk_split_simplelist(prop)} + + if conf_list.size == 0 + raise RuntimeError, "the widget may not support 'font' option" + end + + args << {} + + optkey = "-#{key}" + + info = conf_list.find{|conf| conf[0] == optkey} + fnt = info[-1] + fnt = nil if fnt == [] || fnt == "" + + unless fnt + # create dummy + # TkFont.new(nil, nil).call_font_configure([path, key], *args) + dummy_fnt = TkFont.allocate + dummy_fnt.instance_eval{ init_dummy_fontobj() } + dummy_fnt + else + begin + compound = tk_split_simplelist( + Hash[*tk_split_simplelist(tk_call('font', 'configure', + fnt))].collect{|k,v| + [k[1..-1], v] + }.assoc('compound')[1]) + rescue + compound = [] + end + if compound == [] + TkFont.new(fnt).call_font_configure([path, key], *args) + else + TkFont.new(compound[0], + compound[1]).call_font_configure([path, key], *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 init_dummy_fontobj + @id = Tk_FontID.join(TkCore::INTERP._ip_id_) + Tk_FontID[1].succ! + Tk_FontNameTBL[@id] = self + + @latin_desscendant = nil + @kanji_desscendant = nil + + case (Tk::TK_VERSION) + when /^4\.*/ + @latinfont = "" + @kanjifont = "" + if JAPANIZED_TK + @compoundfont = [[@latinfont], [@kanjifont]] + @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} + else + @compoundfont = @latinfont + @fontslot = {'font'=>@latinfont} + end + else + @latinfont = @id + 'l' + @kanjifont = @id + 'k' + @compoundfont = @id + 'c' + + if JAPANIZED_TK + tk_call('font', 'create', @latinfont, '-charset', 'iso8859') + tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont]) + else + tk_call('font', 'create', @latinfont) + tk_call('font', 'create', @kanjifont) + tk_call('font', 'create', @compoundfont) + end + + @fontslot = {'font'=>@compoundfont} + end + + self + end + + def initialize(ltn=nil, knj=nil, keys=nil) + ltn = '{}' if ltn == '' + knj = '{}' if knj == '' + + # @id = Tk_FontID.join('') + @id = Tk_FontID.join(TkCore::INTERP._ip_id_) + 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 initialize_copy(font) + unless font.kind_of?(TkFont) + fail TypeError, '"initialize_copy should take same class object' + end + if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + keys = {} + font.configinfo.each{|key,value| keys[key] = value } + initialize(font.latin_font_id, font.kanji_font_id, keys) + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + initialize(font.latin_font_id, font.kanji_font_id, font.configinfo) + end + 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) + if knj + create_latinfont(ltn) + create_kanjifont(knj) + else + cfnt = ltn + create_kanjifont(cfnt) + create_latinfont(cfnt) + end + + @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 + compoundkeys = nil + 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 + + if cfnt + if cfnt.kind_of?(Hash) + compoundkeys = cfnt.dup + else + compoundkeys = {} + actual_core(cfnt).each{|key,val| compoundkeys[key] = val} + end + compoundkeys.update(_symbolkey2str(keys)) + keys = compoundkeys + end + + @fontslot = {'font'=>@compoundfont} + tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) + end + end + + ################################### + public + ################################### + def inspect + sprintf("#<%s:%0x:%s>", self.class.inspect, self.__id__, @compoundfont) + end + + def method_missing(id, *args) + name = id.id2name + case args.length + when 1 + if name[-1] == ?= + configure name[0..-2], args[0] + args[0] + else + configure name, args[0] + self + end + when 0 + begin + configinfo name + rescue + super(id, *args) +# fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at + end + else + super(id, *args) +# fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + end + end + + def call_font_configure(path, *args) + if path.kind_of?(Array) + # [path, optkey] + win, tag = path[0].split(';') + optkey = path[1].to_s + else + win, tag, optkey = path.split(';') + end + + fontslot = _symbolkey2str(@fontslot) + if optkey && optkey != "" + ltn = fontslot.delete('font') + knj = fontslot.delete('kanjifont') + fontslot[optkey] = ltn if ltn + fontslot["kanji#{optkey}"] = knj if knj + end + + keys = _symbolkey2str(args.pop).update(fontslot) + args.concat(hash_kv(keys)) + tk_call(*args) + Tk_FontUseTBL[[win, tag, optkey].join(';')] = self + self + end + + def used + ret = [] + Tk_FontUseTBL.each{|key,value| + next unless self == value + if key.include?(';') + win, tag, optkey = key.split(';') + winobj = tk_tcl2ruby(win) + if winobj.kind_of? TkText + if optkey + ret.push([winobj, winobj.tagid2obj(tag), optkey]) + else + ret.push([winobj, winobj.tagid2obj(tag)]) + end + elsif winobj.kind_of? TkCanvas + if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag + if optkey + ret.push([winobj, tagobj, optkey]) + else + ret.push([winobj, tagobj]) + end + elsif (tagobj = TkcItem.id2obj(winobj, tag)).kind_of? TkcItem + if optkey + ret.push([winobj, tagobj, optkey]) + else + ret.push([winobj, tagobj]) + end + else + if optkey + ret.push([winobj, tag, optkey]) + else + ret.push([winobj, tag]) + end + end + elsif winobj.kind_of? TkMenu + if optkey + ret.push([winobj, tag, optkey]) + else + ret.push([winobj, tag]) + end + else + if optkey + ret.push([win, tag, optkey]) + else + ret.push([win, tag]) + end + end + else + ret.push(tk_tcl2ruby(key)) + 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(win, option=nil) + win = '.' unless win + actual_core(@compoundfont, win, option) + end + + def latin_actual(option=nil) + actual_core(@latinfont, nil, option) + end + + def latin_actual_displayof(win, option=nil) + win = '.' unless win + actual_core(@latinfont, win, 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(win, option=nil) + #if JAPANIZED_TK + if @kanjifont != "" + win = '.' unless win + actual_core(@kanjifont, win, option) + else + actual_core_tk4x(nil, win, 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=None) + knj = ltn if knj == None + 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(@compoundfont, nil, text) + end + + def measure_displayof(win, text) + win = '.' unless win + measure_core(@compoundfont, win, text) + end + + def metrics(option=nil) + metrics_core(@compoundfont, nil, option) + end + + def metrics_displayof(win, option=nil) + win = '.' unless win + metrics_core(@compoundfont, win, option) + end + + def latin_metrics(option=nil) + metrics_core(@latinfont, nil, option) + end + + def latin_metrics_displayof(win, option=nil) + win = '.' unless win + metrics_core(@latinfont, win, 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(win, option=nil) + if JAPANIZED_TK + win = '.' unless win + metrics_core(@kanjifont, win, option) + else + metrics_core_tk4x(nil, win, 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 + + ################################### + # 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 + + when /^8\.[0-5]/ + alias create_latinfont create_latinfont_tk8x + alias create_kanjifont create_kanjifont_tk8x + alias create_compoundfont create_compoundfont_tk8x + + else + alias create_latinfont create_latinfont_tk8x + alias create_kanjifont create_kanjifont_tk8x + alias create_compoundfont create_compoundfont_tk8x + + 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 + + ################################### +=begin + def dup + TkFont.new(self) + end + def clone + TkFont.new(self) + end +=end +end + +module TkFont::CoreMethods + include Tk + extend TkCore + + private + + def actual_core_tk4x(font, win=nil, option=nil) + # dummy + if option == 'pointadjust' || option == :pointadjust + 1.0 + elsif option + case TkFont::OptionType[option.to_s] + when ?n + 0 + when ?b + false + else + '' + end + else + [['family',''], ['size',0], ['weight',''], ['slant',''], + ['underline',false], ['overstrike',false], ['charset',''], + ['pointadjust',0]] + end + end + + def actual_core_tk8x(font, win=nil, option=nil) + font = '{}' if font == '' + + if option == 'compound' || option == :compound + "" + elsif option + if win + val = tk_call('font', 'actual', font, + "-displayof", win, "-#{option}") + else + val = tk_call('font', 'actual', font, "-#{option}") + end + case TkFont::OptionType[option.to_s] + when ?n + num_or_str(val) + when ?b + bool(val) + else + val + end + else + l = tk_split_simplelist(if win + tk_call('font', 'actual', font, + "-displayof", win) + else + tk_call('font', 'actual', font) + end) + r = [] + while key=l.shift + if key == '-compound' + l.shift + else + key = key[1..-1] + val = l.shift + case TkFont::OptionType[key] + when ?n + r.push [key, num_or_str(val)] + when ?b + r.push [key, bool(val)] + else + r.push [key, val] + end + 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 == 'pointadjust' || option == :pointadjust + 1.0 + elsif option + case TkFont::OptionType[option.to_s] + when ?n + 0 + when ?b + false + else + '' + end + else + [['family',''], ['size',0], ['weight',''], ['slant',''], + ['underline',false], ['overstrike',false], ['charset',''], + ['pointadjust',1.0]] + 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 + case TkFont::OptionType[option.to_s] + when ?n + 0 + when ?b + false + else + '' + end + else + {'family'=>'', 'size'=>0, 'weight'=>'', 'slant'=>'', + 'underline'=>false, 'overstrike'=>false, + 'charset'=>false, 'pointadjust'=>1.0} + 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' || option == :compound + "" + elsif option + val = tk_call('font', 'configure', font, "-#{option}") + case TkFont::OptionType[option.to_s] + when ?n + num_or_str(val) + when ?b + bool(val) + else + val + end + else + l = tk_split_simplelist(tk_call('font', 'configure', font)) + r = [] + while key=l.shift + if key == '-compound' + l.shift + else + key = key[1..-1] + val = l.shift + case TkFont::OptionType[key] + when ?n + r.push [key, num_or_str(val)] + when ?b + r.push [key, bool(val)] + else + r.push [key, val] + end + 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 + val = tk_call('font', 'configure', font, "-#{option}") + case TkFont::OptionType[option.to_s] + when ?n + num_or_str(val) + when ?b + bool(val) + else + val + end + else + l = tk_split_simplelist(tk_call('font', 'configure', font)) + h = {} + while key=l.shift + if key == '-compound' + l.shift + else + key = key[1..-1] + val = l.shift + case TkFont::OptionType[key] + when ?n + h[key] = num_or_str(val) + when ?b + h[key] = bool(val) + else + h[key] = val + end + end + end + h + end + end + + def delete_core_tk4x + TkFont::Tk_FontNameTBL.delete(@id) + TkFont::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 + TkFont::Tk_FontNameTBL.delete(@id) + TkFont::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 + TkFont::Tk_FontUseTBL.dup.each{|w, fobj| + if self == fobj + begin + if w.include?(';') + win, tag, optkey = w.split(';') + optkey = 'font' if optkey == nil || optkey == '' + winobj = tk_tcl2ruby(win) +# winobj.tagfont_configure(tag, {'font'=>@latinfont}) + if winobj.kind_of? TkText + tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @latinfont) + elsif winobj.kind_of? TkCanvas + tk_call(win, 'itemconfigure', tag, "-#{optkey}", @latinfont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont) + else + raise RuntimeError, "unknown widget type" + end + else +# tk_tcl2ruby(w).font_configure('font'=>@latinfont) + tk_call(w, 'configure', '-font', @latinfont) + end + rescue + TkFont::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 + TkFont::Tk_FontUseTBL.dup.each{|w, fobj| + if self == fobj + begin + if w.include?(';') + win, tag, optkey = w.split(';') + optkey = 'kanjifont' unless optkey + winobj = tk_tcl2ruby(win) +# winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont}) + if winobj.kind_of? TkText + tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @kanjifont) + elsif winobj.kind_of? TkCanvas + tk_call(win, 'itemconfigure', tag, "-#{optkey}", @kanjifont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont) + else + raise RuntimeError, "unknown widget type" + end + else +# tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont) + tk_call(w, 'configure', '-kanjifont', @kanjifont) + end + rescue + TkFont::Tk_FontUseTBL.delete(w) + end + end + } + self + end + + def latin_replace_core_tk8x(ltn) + ltn = '{}' if 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 = TkFont::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) + knj = '{}' if 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 = TkFont::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(font, win, text) + 0 + end + + def measure_core_tk8x(font, win, text) + font = '{}' if font == '' + + if win + number(tk_call('font', 'measure', font, + '-displayof', win, text)) + else + number(tk_call('font', 'measure', font, text)) + end + end + + def metrics_core_tk4x(font, win, option=nil) + # dummy + if option + "" + else + [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]] + end + end + + def metrics_core_tk8x(font, win, option=nil) + font = '{}' if font == '' + + if option + if win + number(tk_call('font', 'metrics', font, + "-displayof", win, "-#{option}")) + else + number(tk_call('font', 'metrics', font, "-#{option}")) + end + else + l = tk_split_list(if win + tk_call('font','metrics',font,"-displayof",win) + 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 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 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 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 +end + +class TkFont + include TkFont::CoreMethods + extend TkFont::CoreMethods +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/frame.rb b/ruby_1_8_6/ext/tk/lib/tk/frame.rb new file mode 100644 index 0000000000..6636fef5b5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/frame.rb @@ -0,0 +1,128 @@ +# +# tk/frame.rb : treat frame widget +# +require 'tk' + +class TkFrame<TkWindow + TkCommandNames = ['frame'.freeze].freeze + WidgetClassName = 'Frame'.freeze + WidgetClassNames[WidgetClassName] = self + +################# old version +# def initialize(parent=nil, keys=nil) +# if keys.kind_of? Hash +# keys = keys.dup +# @classname = keys.delete('classname') if keys.key?('classname') +# @colormap = keys.delete('colormap') if keys.key?('colormap') +# @container = keys.delete('container') if keys.key?('container') +# @visual = keys.delete('visual') if keys.key?('visual') +# end +# super(parent, keys) +# end +# +# def create_self +# s = [] +# s << "-class" << @classname if @classname +# s << "-colormap" << @colormap if @colormap +# s << "-container" << @container if @container +# s << "-visual" << @visual if @visual +# tk_call 'frame', @path, *s +# end +################# + + def __boolval_optkeys + super() << 'container' + end + private :__boolval_optkeys + + def initialize(parent=nil, keys=nil) + my_class_name = nil + if self.class < WidgetClassNames[self.class::WidgetClassName] + my_class_name = self.class.name + my_class_name = nil if my_class_name == '' + end + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + else + if keys + keys = _symbolkey2str(keys) + keys['parent'] = parent + else + keys = {'parent'=>parent} + 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, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind(*args, &b) + end + end + def self.bind_append(*args, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind_append(*args, &b) + 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/ruby_1_8_6/ext/tk/lib/tk/grid.rb b/ruby_1_8_6/ext/tk/lib/tk/grid.rb new file mode 100644 index 0000000000..10fdf3569b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/grid.rb @@ -0,0 +1,220 @@ +# +# 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) + } + if Tk::TCL_MAJOR_VERSION < 8 || + (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION <= 3) + if params[0] == '-' || params[0] == 'x' || params[0] == '^' + tk_call_without_enc('grid', *params) + else + tk_call_without_enc('grid', 'configure', *params) + end + else + tk_call_without_enc('grid', 'configure', *params) + end + end + alias grid configure + + 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 + case slot + when 'uniform', :uniform + tk_call_without_enc('grid', 'columnconfigure', + master, index, "-#{slot}") + else + num_or_str(tk_call_without_enc('grid', 'columnconfigure', + master, index, "-#{slot}")) + end + else + #ilist = list(tk_call_without_enc('grid','columnconfigure',master,index)) + ilist = simplelist(tk_call_without_enc('grid', 'columnconfigure', + master, index)) + info = {} + while key = ilist.shift + case key + when 'uniform' + info[key[1..-1]] = ilist.shift + else + info[key[1..-1]] = tk_tcl2ruby(ilist.shift) + end + end + info + end + end + + def rowconfiginfo(master, index, slot=nil) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if slot + case slot + when 'uniform', :uniform + tk_call_without_enc('grid', 'rowconfigure', + master, index, "-#{slot}") + else + num_or_str(tk_call_without_enc('grid', 'rowconfigure', + master, index, "-#{slot}")) + end + else + #ilist = list(tk_call_without_enc('grid', 'rowconfigure', master, index)) + ilist = simplelist(tk_call_without_enc('grid', 'rowconfigure', + master, index)) + info = {} + while key = ilist.shift + case key + when 'uniform' + info[key[1..-1]] = ilist.shift + else + info[key[1..-1]] = tk_tcl2ruby(ilist.shift) + end + 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)) + ilist = simplelist(tk_call_without_enc('grid', 'info', slave)) + info = {} + while key = ilist.shift + #info[key[1..-1]] = ilist.shift + info[key[1..-1]] = tk_tcl2ruby(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, mode=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if mode == None + bool(tk_call_without_enc('grid', 'propagate', master)) + else + tk_call_without_enc('grid', 'propagate', master, mode) + 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 :grid, :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/ruby_1_8_6/ext/tk/lib/tk/image.rb b/ruby_1_8_6/ext/tk/lib/tk/image.rb new file mode 100644 index 0000000000..35e2c4e394 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/image.rb @@ -0,0 +1,237 @@ +# +# tk/image.rb : treat Tk image objects +# + +require 'tk' + +class TkImage<TkObject + include Tk + + TkCommandNames = ['image'.freeze].freeze + + Tk_IMGTBL = TkCore::INTERP.create_table + Tk_Image_ID = ['i'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ Tk_IMGTBL.clear } + + def self.new(keys=nil) + if keys.kind_of?(Hash) + name = nil + if keys.key?(:imagename) + name = keys[:imagename] + elsif keys.key?('imagename') + name = keys['imagename'] + end + if name + if name.kind_of?(TkImage) + obj = name + else + name = _get_eval_string(name) + obj = Tk_IMGTBL[name] + end + if obj + if !(keys[:without_creating] || keys['without_creating']) + keys = _symbolkey2str(keys) + keys.delete('imagename') + keys.delete('without_creating') + obj.instance_eval{ + tk_call_without_enc('image', 'create', + @type, @path, *hash_kv(keys, true)) + } + end + return obj + end + end + end + super(keys) + end + + def initialize(keys=nil) + @path = nil + without_creating = false + if keys.kind_of?(Hash) + keys = _symbolkey2str(keys) + @path = keys.delete('imagename') + without_creating = keys.delete('without_creating') + end + unless @path + # @path = Tk_Image_ID.join('') + @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_) + Tk_Image_ID[1].succ! + end + unless without_creating + tk_call_without_enc('image', 'create', + @type, @path, *hash_kv(keys, true)) + end + Tk_IMGTBL[@path] = self + end + + def delete + Tk_IMGTBL.delete(@id) if @id + tk_call_without_enc('image', 'delete', @path) + self + end + def height + number(tk_call_without_enc('image', 'height', @path)) + end + def inuse + bool(tk_call_without_enc('image', 'inuse', @path)) + end + def itemtype + tk_call_without_enc('image', 'type', @path) + end + def width + number(tk_call_without_enc('image', 'width', @path)) + end + + def TkImage.names + Tk.tk_call_without_enc('image', 'names').split.collect!{|id| + (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id + } + end + + def TkImage.types + Tk.tk_call_without_enc('image', 'types').split + end +end + +class TkBitmapImage<TkImage + def __strval_optkeys + super() + ['maskdata', 'maskfile'] + end + private :__strval_optkeys + + def initialize(*args) + @type = 'bitmap' + super(*args) + end +end + +class TkPhotoImage<TkImage + NullArgOptionKeys = [ "shrink", "grayscale" ] + + def _photo_hash_kv(keys) + keys = _symbolkey2str(keys) + NullArgOptionKeys.collect{|opt| + if keys[opt] + keys[opt] = None + else + keys.delete(opt) + end + } + keys.collect{|k,v| + ['-' << k, v] + }.flatten + end + private :_photo_hash_kv + + def initialize(*args) + @type = 'photo' + super(*args) + end + + def blank + tk_send_without_enc('blank') + self + end + + def cget(option) + case option.to_s + when 'data', 'file' + tk_send 'cget', '-' << option.to_s + else + tk_tcl2ruby(tk_send('cget', '-' << option.to_s)) + end + end + + def copy(src, *opts) + if opts.size == 0 + tk_send('copy', src) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('copy', src, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + args = opts.collect{|term| + if term.kind_of?(String) && term.include?(?\s) + term.split + else + term + end + }.flatten + tk_send('copy', src, *args) + end + self + end + + def data(keys={}) + #tk_send('data', *_photo_hash_kv(keys)) + tk_split_list(tk_send('data', *_photo_hash_kv(keys))) + end + + def get(x, y) + tk_send('get', x, y).split.collect{|n| n.to_i} + end + + def put(data, *opts) + if opts == [] + tk_send('put', data) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('put', data, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + tk_send('put', data, '-to', *opts) + end + self + end + + def read(file, *opts) + if opts.size == 0 + tk_send('read', file) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('read', file, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + args = opts.collect{|term| + if term.kind_of?(String) && term.include?(?\s) + term.split + else + term + end + }.flatten + tk_send('read', file, *args) + end + self + end + + def redither + tk_send 'redither' + self + end + + def get_transparency(x, y) + bool(tk_send('transparency', 'get', x, y)) + end + def set_transparency(x, y, st) + tk_send('transparency', 'set', x, y, st) + self + end + + def write(file, *opts) + if opts.size == 0 + tk_send('write', file) + elsif opts.size == 1 && opts[0].kind_of?(Hash) + tk_send('write', file, *_photo_hash_kv(opts[0])) + else + # for backward compatibility + args = opts.collect{|term| + if term.kind_of?(String) && term.include?(?\s) + term.split + else + term + end + }.flatten + tk_send('write', file, *args) + end + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/itemconfig.rb b/ruby_1_8_6/ext/tk/lib/tk/itemconfig.rb new file mode 100644 index 0000000000..a7885e74f3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/itemconfig.rb @@ -0,0 +1,1061 @@ +# +# tk/itemconfig.rb : control item/tag configuration of widget +# +require 'tk' +require 'tkutil' +require 'tk/itemfont.rb' + +module TkItemConfigOptkeys + include TkUtil + + def __item_numval_optkeys(id) + [] + end + private :__item_numval_optkeys + + def __item_numstrval_optkeys(id) + [] + end + private :__item_numstrval_optkeys + + def __item_boolval_optkeys(id) + ['exportselection', 'jump', 'setgrid', 'takefocus'] + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + # maybe need to override + [ + 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile', + 'activebackground', 'activeforeground', 'background', + 'disabledforeground', 'disabledbackground', 'foreground', + 'highlightbackground', 'highlightcolor', 'insertbackground', + 'selectbackground', 'selectforeground', 'troughcolor' + ] + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys + + def __item_numlistval_optkeys(id) + # maybe need to override + ['dash', 'activedash', 'disableddash'] + end + private :__item_numlistval_optkeys + + def __item_tkvariable_optkeys(id) + ['variable', 'textvariable'] + end + private :__item_tkvariable_optkeys + + def __item_val2ruby_optkeys(id) # { key=>method, ... } + # The method is used to convert a opt-value to a ruby's object. + # When get the value of the option "key", "method.call(id, val)" is called. + {} + end + private :__item_val2ruby_optkeys + + def __item_ruby2val_optkeys(id) # { key=>method, ... } + # The method is used to convert a ruby's object to a opt-value. + # When set the value of the option "key", "method.call(id, val)" is called. + # That is, "-#{key} #{method.call(id, value)}". + {} + end + private :__item_ruby2val_optkeys + + def __item_methodcall_optkeys(id) # { key=>method, ... } + # Use the method for both of get and set. + # Usually, the 'key' will not be a widget option. + # + # maybe need to override + # {'coords'=>'coords'} + {} + end + private :__item_methodcall_optkeys + + ################################################ + + def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... } + # maybe need to override + {} + end + private :__item_keyonly_optkeys + + + def __conv_item_keyonly_opts(id, keys) + return keys unless keys.kind_of?(Hash) + keyonly = __item_keyonly_optkeys(id) + keys2 = {} + keys.each{|k, v| + optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s} + if optkey + defkey, undefkey = optkey + if v + keys2[defkey.to_s] = None + else + keys2[undefkey.to_s] = None + end + else + keys2[k.to_s] = v + end + } + keys2 + end + + def itemconfig_hash_kv(id, keys, enc_mode = nil, conf = nil) + hash_kv(__conv_item_keyonly_opts(id, keys), enc_mode, conf) + end +end + +module TkItemConfigMethod + include TkUtil + include TkTreatItemFont + include TkItemConfigOptkeys + + def __item_cget_cmd(id) + # maybe need to override + [self.path, 'itemcget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + # maybe need to override + [self.path, 'itemconfigure', id] + end + private :__item_config_cmd + + def __item_confinfo_cmd(id) + # maybe need to override + __item_config_cmd(id) + end + private :__item_confinfo_cmd + + def __item_configinfo_struct(id) + # maybe need to override + {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, + :default_value=>3, :current_value=>4} + end + private :__item_configinfo_struct + + ################################################ + + def tagid(tagOrId) + # maybe need to override + tagOrId + end + + ################################################ + + def itemcget(tagOrId, option) + orig_opt = option + option = option.to_s + + if option.length == 0 + fail ArgumentError, "Invalid option `#{orig_opt.inspect}'" + end + + if ( method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[option] ) + optval = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) + begin + return method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + return optval + end + end + + if ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[option] ) + return self.__send__(method, tagOrId) + end + + case option + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + number(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + rescue + nil + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + num_or_str(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + bool(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + rescue + nil + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + simplelist(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + conf = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) + if conf =~ /^[0-9]/ + list(conf) + else + conf + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + v = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) + (v.empty?)? nil: TkVarAccess.new(v) + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + _fromUTF8(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}"))) + + when /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/ + fontcode = $1 + fontkey = $2 + fnt = tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{fontkey}")), true) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(tagid(tagOrId), fontkey) + end + if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ + # obsolete; just for compatibility + fnt.kanji_font + else + fnt + end + else + tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")), true) + end + end + + def itemconfigure(tagOrId, slot, value=None) + if slot.kind_of? Hash + slot = _symbolkey2str(slot) + + __item_methodcall_optkeys(tagid(tagOrId)).each{|key, method| + value = slot.delete(key.to_s) + self.__send__(method, tagOrId, value) if value + } + + __item_ruby2val_optkeys(tagid(tagOrId)).each{|key, method| + key = key.to_s + slot[key] = method.call(tagOrId, slot[key]) if slot.has_key?(key) + } + + __item_keyonly_optkeys(tagid(tagOrId)).each{|defkey, undefkey| + conf = slot.find{|kk, vv| kk == defkey.to_s} + if conf + k, v = conf + if v + slot[k] = None + else + slot[undefkey.to_s] = None if undefkey + slot.delete(k) + end + end + } + + if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/}) + tagfont_configure(tagid(tagOrId), slot) + elsif slot.size > 0 + tk_call(*(__item_config_cmd(tagid(tagOrId)).concat(hash_kv(slot)))) + end + + else + orig_slot = slot + slot = slot.to_s + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end + + if ( conf = __item_keyonly_optkeys(tagid(tagOrId)).find{|k, v| k.to_s == slot } ) + defkey, undefkey = conf + if value + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{defkey}")) + elsif undefkey + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{undefkey}")) + end + elsif ( method = _symbolkey2str(__item_ruby2val_optkeys(tagid(tagOrId)))[slot] ) + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{slot}" << method.call(tagOrId, value))) + elsif ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] ) + self.__send__(method, tagOrId, value) + elsif (slot =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + if value == None + tagfontobj(tagid(tagOrId), $2) + else + tagfont_configure(tagid(tagOrId), {slot=>value}) + end + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{slot}" << value)) + end + end + self + end + + def __itemconfiginfo_core(tagOrId, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + fontkey = $2 + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")), false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey) + elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- ) + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + conf + else + if slot + slot = slot.to_s + case slot + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] + return [slot, '', '', '', self.__send__(method, tagOrId)] + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_list(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), 0, false, true) + end + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- ) + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + + conf + + else + # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + ret = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + optkey = conf[__item_configinfo_struct(tagid(tagOrId))[:key]] + case optkey + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey] + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # do nothing + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + end + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + end + end + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- ) + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + + conf + } + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + fontconf = ret.assoc(optkey) + if fontconf && fontconf.size > 2 + ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} + fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey) + ret.push(fontconf) + end + } + + __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| + ret << [optkey.to_s, '', '', '', self.__send__(method, tagOrId)] + } + + ret + end + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + fontkey = $2 + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")), false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = fontobj(tagid(tagOrId), fontkey) + { conf.shift => conf } + elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + { conf[0] => conf[1] } + else + { conf.shift => conf } + end + else + if slot + slot = slot.to_s + case slot + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] + return {slot => ['', '', '', self.__send__(method, tagOrId)]} + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_stre(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), false, true) + + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))) + conf = tk_split_list(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")), 0, false, true) + end + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + { conf[0] => conf[1] } + else + { conf.shift => conf } + end + + else + ret = {} + # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))))).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1] + + optkey = conf[__item_configinfo_struct(tagid(tagOrId))[:key]] + case optkey + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey] + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # do nothing + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + begin + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + rescue + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + end + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ ) + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v) + end + end + if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] ) + v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if v.empty? + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v) + end + end + + else + if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \ + && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) + end + end + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] + if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]].index('{') + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + else + conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = + tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) + end + end + end + + if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \ + && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = + conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1] + end + ret[conf[0]] = conf[1] + else + ret[conf.shift] = conf + end + } + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + fontconf = ret[optkey] + if fontconf.kind_of?(Array) + ret.delete(optkey) + ret.delete('latin' << optkey) + ret.delete('ascii' << optkey) + ret.delete('kanji' << optkey) + fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey) + ret[optkey] = fontconf + end + } + + __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| + ret[optkey.to_s] = ['', '', '', self.__send__(method, tagOrId)] + } + + ret + end + end + end + end + private :__itemconfiginfo_core + + def itemconfiginfo(tagOrId, slot = nil) + __itemconfiginfo_core(tagOrId, slot) + end + + def current_itemconfiginfo(tagOrId, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + org_slot = slot + begin + conf = __itemconfiginfo_core(tagOrId, slot) + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + return {conf[0] => conf[-1]} + end + slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] + end while(org_slot != slot) + fail RuntimeError, + "there is a configure alias loop about '#{org_slot}'" + else + ret = {} + __itemconfiginfo_core(tagOrId).each{|conf| + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + ret[conf[0]] = conf[-1] + end + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + __itemconfiginfo_core(tagOrId, slot).each{|key, conf| + ret[key] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/itemfont.rb b/ruby_1_8_6/ext/tk/lib/tk/itemfont.rb new file mode 100644 index 0000000000..ab9e3ff6c9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/itemfont.rb @@ -0,0 +1,300 @@ +# +# tk/itemfont.rb : control font of widget items +# +require 'tk' + +module TkItemFontOptkeys + def __item_font_optkeys(id) + # maybe need to override + ['font'] + end + private :__item_font_optkeys +end + +module TkTreatItemFont + include TkItemFontOptkeys + + def __item_pathname(id) + # maybe need to override + [self.path, id].join(';') + end + private :__item_pathname + + ################################################ + + def tagfont_configinfo(tagOrId, key = nil) + optkeys = __item_font_optkeys(tagid(tagOrId)) + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __item_pathname(tagid(tagOrId)).split(';') + + if key + pathname = [win, tag, key].join(';') + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, + *(__item_confinfo_cmd(tagid(tagOrId)))) + elsif optkeys.size == 1 + pathname = [win, tag, optkeys[0]].join(';') + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, + *(__item_confinfo_cmd(tagid(tagOrId)))) + else + fonts = {} + optkeys.each{|key| + key = key.to_s + pathname = [win, tag, key].join(';') + fonts[key] = + TkFont.used_on(pathname) || + TkFont.init_widget_font(pathname, + *(__item_confinfo_cmd(tagid(tagOrId)))) + } + fonts + end + end + alias tagfontobj tagfont_configinfo + + def tagfont_configure(tagOrId, slot) + pathname = __item_pathname(tagid(tagOrId)) + + slot = _symbolkey2str(slot) + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + l_optkey = 'latin' << optkey + a_optkey = 'ascii' << optkey + k_optkey = 'kanji' << optkey + + if slot.key?(optkey) + fnt = slot.delete(optkey) + if fnt.kind_of?(TkFont) + slot.delete(l_optkey) + slot.delete(a_optkey) + slot.delete(k_optkey) + + fnt.call_font_configure([pathname, optkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + next + else + if fnt + if (slot.key?(l_optkey) || + slot.key?(a_optkey) || + slot.key?(k_optkey)) + fnt = TkFont.new(fnt) + + lfnt = slot.delete(l_optkey) + lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) + kfnt = slot.delete(k_optkey) + + fnt.latin_replace(lfnt) if lfnt + fnt.kanji_replace(kfnt) if kfnt + + fnt.call_font_configure([pathname, optkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + next + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << fnt)) + end + end + next + end + end + + lfnt = slot.delete(l_optkey) + lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) + kfnt = slot.delete(k_optkey) + + if lfnt && kfnt + TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + elsif lfnt + latintagfont_configure([lfnt, optkey]) + elsif kfnt + kanjitagfont_configure([kfnt, optkey]) + end + } + + # configure other (without font) options + tk_call(*(__item_config_cmd(tagid(tagOrId)).concat(hash_kv(slot)))) if slot != {} + self + end + + def latintagfont_configure(tagOrId, ltn, keys=nil) + if ltn.kind_of?(Array) + key = ltn[1] + ltn = ltn[0] + else + key = nil + end + + optkeys = __item_font_optkeys(tagid(tagOrId)) + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __item_pathname(tagid(tagOrId)).split(';') + + optkeys = [key] if key + + optkeys.each{|optkey| + optkey = optkey.to_s + + pathname = [win, tag, optkey].join(';') + + if (fobj = TkFont.used_on(pathname)) + fobj = TkFont.new(fobj) # create a new TkFont object + elsif Tk::JAPANIZED_TK + fobj = fontobj # create a new TkFont object + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << ltn)) + next + 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 + + fobj.call_font_configure([pathname, optkey], *(__item_config_cmd(tagid(tagOrId)) << {})) + } + self + end + alias asciitagfont_configure latintagfont_configure + + def kanjitagfont_configure(tagOrId, knj, keys=nil) + if knj.kind_of?(Array) + key = knj[1] + knj = knj[0] + else + key = nil + end + + optkeys = __item_font_optkeys(tagid(tagOrId)) + if key && !optkeys.find{|opt| opt.to_s == key.to_s} + fail ArgumentError, "unknown font option name `#{key}'" + end + + win, tag = __item_pathname(tagid(tagOrId)).split(';') + + optkeys = [key] if key + + optkeys.each{|optkey| + optkey = optkey.to_s + + pathname = [win, tag, optkey].join(';') + + if (fobj = TkFont.used_on(pathname)) + fobj = TkFont.new(fobj) # create a new TkFont object + elsif Tk::JAPANIZED_TK + fobj = fontobj # create a new TkFont object + else + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << knj)) + next + 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 + + fobj.call_font_configure([pathname, optkey], *(__item_config_cmd(tagid(tagOrId)) << {})) + } + self + end + + def tagfont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil) + if wintag + if winkey + fnt = win.tagfontobj(wintag, winkey).dup + else + fnt = win.tagfontobj(wintag).dup + end + else + if winkey + fnt = win.fontobj(winkey).dup + else + fnt = win.fontobj.dup + end + end + + if targetkey + fnt.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + else + fnt.call_font_configure(__item_pathname(tagid(tagOrId)), + *(__item_config_cmd(tagid(tagOrId)) << {})) + end + self + end + + + def latintagfont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil) + if targetkey + fontobj(targetkey).dup.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + else + fontobj.dup.call_font_configure(__item_pathname(tagid(tagOrId)), + *(__item_config_cmd(tagid(tagOrId)) << {})) + end + + if wintag + if winkey + fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id) + else + fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id) + end + else + if winkey + fontobj.latin_replace(win.fontobj(winkey).latin_font_id) + else + fontobj.latin_replace(win.fontobj.latin_font_id) + end + end + self + end + alias asciitagfont_copy latintagfont_copy + + def kanjifont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil) + if targetkey + fontobj(targetkey).dup.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], + *(__item_config_cmd(tagid(tagOrId)) << {})) + else + fontobj.dup.call_font_configure(__item_pathname(tagid(tagOrId)), + *(__item_config_cmd(tagid(tagOrId)) << {})) + end + + if wintag + if winkey + fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id) + else + fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id) + end + else + if winkey + fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id) + else + fontobj.kanji_replace(win.fontobj.kanji_font_id) + end + end + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/kinput.rb b/ruby_1_8_6/ext/tk/lib/tk/kinput.rb new file mode 100644 index 0000000000..a29dbcdb72 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/kinput.rb @@ -0,0 +1,71 @@ +# +# tk/kinput.rb : control kinput +# +require 'tk' + +module TkKinput + include Tk + extend Tk + + TkCommandNames = [ + 'kinput_start'.freeze, + 'kinput_send_spot'.freeze, + 'kanjiInput'.freeze + ].freeze + + def TkKinput.start(win, style=None) + tk_call('kinput_start', win, style) + end + def kinput_start(style=None) + TkKinput.start(self, style) + end + + def TkKinput.send_spot(win) + tk_call('kinput_send_spot', win) + end + def kinput_send_spot + TkKinput.send_spot(self) + end + + def TkKinput.input_start(win, keys=nil) + tk_call('kanjiInput', 'start', win, *hash_kv(keys)) + end + def kanji_input_start(keys=nil) + TkKinput.input_start(self, keys) + end + + def TkKinput.attribute_config(win, slot, value=None) + if slot.kind_of? Hash + tk_call('kanjiInput', 'attribute', win, *hash_kv(slot)) + else + tk_call('kanjiInput', 'attribute', win, "-#{slot}", value) + end + end + def kinput_attribute_config(slot, value=None) + TkKinput.attribute_config(self, slot, value) + end + + def TkKinput.attribute_info(win, slot=nil) + if slot + conf = tk_split_list(tk_call('kanjiInput', 'attribute', + win, "-#{slot}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_list(tk_call('kanjiInput', 'attribute', win)).collect{|conf| + conf[0] = conf[0][1..-1] + conf + } + end + end + def kinput_attribute_info(slot=nil) + TkKinput.attribute_info(self, slot) + end + + def TkKinput.input_end(win) + tk_call('kanjiInput', 'end', win) + end + def kanji_input_end + TkKinput.input_end(self) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/label.rb b/ruby_1_8_6/ext/tk/lib/tk/label.rb new file mode 100644 index 0000000000..8b45db9b30 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/label.rb @@ -0,0 +1,18 @@ +# +# tk/label.rb : treat label widget +# +require 'tk' + +class TkLabel<TkWindow + TkCommandNames = ['label'.freeze].freeze + WidgetClassName = 'Label'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('label', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('label', @path) + # end + #end + #private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/labelframe.rb b/ruby_1_8_6/ext/tk/lib/tk/labelframe.rb new file mode 100644 index 0000000000..73d5603200 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/labelframe.rb @@ -0,0 +1,25 @@ +# +# tk/labelframe.rb : treat labelframe widget +# +require 'tk' +require 'tk/frame' + +class TkLabelFrame<TkFrame + TkCommandNames = ['labelframe'.freeze].freeze + WidgetClassName = 'Labelframe'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('labelframe', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('labelframe', @path) + # end + #end + #private :create_self + + def __val2ruby_optkeys # { key=>proc, ... } + super().update('labelwidget'=>proc{|v| window(v)}) + end + private :__val2ruby_optkeys +end +TkLabelframe = TkLabelFrame diff --git a/ruby_1_8_6/ext/tk/lib/tk/listbox.rb b/ruby_1_8_6/ext/tk/lib/tk/listbox.rb new file mode 100644 index 0000000000..41d02d279e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/listbox.rb @@ -0,0 +1,279 @@ +# +# tk/listbox.rb : treat listbox widget +# +require 'tk' +require 'tk/itemconfig' +require 'tk/scrollable' +require 'tk/txtwin_abst' + +module TkListItemConfig + include TkItemConfigMethod + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys +end + +class TkListbox<TkTextWin + include TkListItemConfig + include Scrollable + + TkCommandNames = ['listbox'.freeze].freeze + WidgetClassName = 'Listbox'.freeze + WidgetClassNames[WidgetClassName] = self + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('listbox', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('listbox', @path) + # end + #end + #private :create_self + + def __tkvariable_optkeys + super() << 'listvariable' + end + private :__tkvariable_optkeys + + def tagid(id) + #id.to_s + _get_eval_string(id) + end + + def activate(y) + tk_send_without_enc('activate', y) + self + end + def curselection + list(tk_send_without_enc('curselection')) + end + def get(first, last=nil) + if last + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('get', first, last))) + tk_split_simplelist(tk_send_without_enc('get', first, last), false, true) + else + _fromUTF8(tk_send_without_enc('get', first)) + end + end + def nearest(y) + tk_send_without_enc('nearest', y).to_i + end + def size + tk_send_without_enc('size').to_i + end + def selection_anchor(index) + tk_send_without_enc('selection', 'anchor', index) + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', first, last) + self + end + def selection_includes(index) + bool(tk_send_without_enc('selection', 'includes', index)) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', first, last) + self + end + + def index(idx) + tk_send_without_enc('index', idx).to_i + end + + def value + get('0', 'end') + end + + def value= (vals) + unless vals.kind_of?(Array) + fail ArgumentError, 'an Array is expected' + end + tk_send_without_enc('delete', '0', 'end') + tk_send_without_enc('insert', '0', + *(vals.collect{|v| _get_eval_enc_str(v)})) + vals + end + + def clear + tk_send_without_enc('delete', '0', 'end') + self + end + alias erase clear + +=begin + def itemcget(index, key) + case key.to_s + when 'text', 'label', 'show' + _fromUTF8(tk_send_without_enc('itemcget', index, "-#{key}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('itemcget', index, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', index, + '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, 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_send_without_enc('itemcget', index, "-#{key}"))) + end + end + def itemconfigure(index, key, val=None) + if key.kind_of? Hash + if (key['font'] || key[:font] || + key['kanjifont'] || key[:kanjifont] || + key['latinfont'] || key[:latinfont] || + key['asciifont'] || key[:asciifont] ) + tagfont_configure(index, _symbolkey2str(key)) + else + tk_send_without_enc('itemconfigure', index, *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(index) + else + tagfont_configure(index, {key=>val}) + 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 +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/macpkg.rb b/ruby_1_8_6/ext/tk/lib/tk/macpkg.rb new file mode 100644 index 0000000000..1802073f46 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/macpkg.rb @@ -0,0 +1,73 @@ +# +# tk/macpkg.rb : methods for Tcl/Tk packages for Macintosh +# 2000/11/22 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +# 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 + + PACKAGE_NAME = 'resource'.freeze + def self.package_name + PACKAGE_NAME + end + + 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/ruby_1_8_6/ext/tk/lib/tk/menu.rb b/ruby_1_8_6/ext/tk/lib/tk/menu.rb new file mode 100644 index 0000000000..ddddc8e53e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/menu.rb @@ -0,0 +1,632 @@ +# +# tk/menu.rb : treat menu and menubutton +# +require 'tk' +require 'tk/itemconfig' +require 'tk/menuspec' + +module TkMenuEntryConfig + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'entrycget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'entryconfigure', id] + end + private :__item_config_cmd + + def __item_strval_optkeys(id) + super(id) << 'selectcolor' + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys + + def __item_val2ruby_optkeys(id) # { key=>proc, ... } + super(id).update('menu'=>proc{|i, v| window(v)}) + end + private :__item_val2ruby_optkeys + + alias entrycget itemcget + alias entryconfigure itemconfigure + alias entryconfiginfo itemconfiginfo + alias current_entryconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class TkMenu<TkWindow + include Wm + include TkMenuEntryConfig + extend TkMenuSpec + + TkCommandNames = ['menu'.freeze].freeze + WidgetClassName = 'Menu'.freeze + WidgetClassNames[WidgetClassName] = self + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('menu', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('menu', @path) + # end + #end + #private :create_self + + def __strval_optkeys + super() << 'selectcolor' << 'title' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'tearoff' + end + private :__boolval_optkeys + + def self.new_menuspec(menu_spec, parent = nil, tearoff = false, keys = nil) + if parent.kind_of?(Hash) + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + tearoff = keys.delete('tearoff') + elsif tearoff.kind_of?(Hash) + keys = _symbolkey2str(tearoff) + tearoff = keys.delete('tearoff') + elsif keys + keys = _symbolkey2str(keys) + else + keys = {} + end + + widgetname = keys.delete('widgetname') + _create_menu(parent, menu_spec, widgetname, tearoff, keys) + end + + def tagid(id) + #id.to_s + _get_eval_string(id) + end + + def activate(index) + tk_send_without_enc('activate', _get_eval_enc_str(index)) + self + end + def add(type, keys=nil) + tk_send_without_enc('add', type, *hash_kv(keys, true)) + self + end + def add_cascade(keys=nil) + add('cascade', keys) + end + def add_checkbutton(keys=nil) + add('checkbutton', keys) + end + def add_command(keys=nil) + add('command', keys) + end + def add_radiobutton(keys=nil) + add('radiobutton', keys) + end + def add_separator(keys=nil) + add('separator', keys) + end + + def clone_menu(*args) + if args[0].kind_of?(TkWindow) + parent = args.shift + else + parent = self + end + + if args[0].kind_of?(String) || args[0].kind_of?(Symbol) # menu type + type = args.shift + else + type = None # 'normal' + end + + if args[0].kind_of?(Hash) + keys = _symbolkey2str(args.shift) + else + keys = {} + end + + parent = keys.delete('parent') if keys.has_key?('parent') + type = keys.delete('type') if keys.has_key?('type') + + if keys.empty? + TkMenuClone.new(self, parent, type) + else + TkMenuClone.new(self, parent, type, keys) + end + end + + def index(idx) + ret = tk_send_without_enc('index', _get_eval_enc_str(idx)) + (ret == 'none')? nil: number(ret) + end + def invoke(index) + _fromUTF8(tk_send_without_enc('invoke', _get_eval_enc_str(index))) + end + def insert(index, type, keys=nil) + tk_send_without_enc('insert', _get_eval_enc_str(index), + type, *hash_kv(keys, true)) + self + end + def delete(first, last=nil) + if last + tk_send_without_enc('delete', _get_eval_enc_str(first), + _get_eval_enc_str(last)) + else + tk_send_without_enc('delete', _get_eval_enc_str(first)) + end + self + end + def popup(x, y, index=nil) + if index + tk_call_without_enc('tk_popup', path, x, y, + _get_eval_enc_str(index)) + else + tk_call_without_enc('tk_popup', path, x, y) + end + self + end + def post(x, y) + _fromUTF8(tk_send_without_enc('post', x, y)) + end + def postcascade(index) + tk_send_without_enc('postcascade', _get_eval_enc_str(index)) + self + end + def postcommand(cmd=Proc.new) + configure_cmd 'postcommand', cmd + self + end + def set_focus + tk_call_without_enc('tk_menuSetFocus', path) + self + end + def tearoffcommand(cmd=Proc.new) + configure_cmd 'tearoffcommand', cmd + self + end + def menutype(index) + tk_send_without_enc('type', _get_eval_enc_str(index)) + end + def unpost + tk_send_without_enc('unpost') + self + end + def yposition(index) + number(tk_send_without_enc('yposition', _get_eval_enc_str(index))) + end + +=begin + def entrycget(index, key) + case key.to_s + when 'text', 'label', 'show' + _fromUTF8(tk_send_without_enc('entrycget', + _get_eval_enc_str(index), "-#{key}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_send('entrycget', index, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(index, 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_send_without_enc('entrycget', _get_eval_enc_str(index), "-#{key}"))) + end + end + def entryconfigure(index, key, val=None) + if key.kind_of? Hash + if (key['font'] || key[:font] || + key['kanjifont'] || key[:kanjifont] || + key['latinfont'] || key[:latinfont] || + key['asciifont'] || key[:asciifont]) + tagfont_configure(index, _symbolkey2str(key)) + else + tk_send_without_enc('entryconfigure', _get_eval_enc_str(index), + *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(index) + else + tagfont_configure(index, {key=>val}) + 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 +end + + +class TkMenuClone<TkMenu +=begin + def initialize(parent, type=None) + widgetname = nil + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + widgetname = keys.delete('widgetname') + type = keys.delete('type'); type = None unless type + end + #unless parent.kind_of?(TkMenu) + # fail ArgumentError, "parent must be TkMenu" + #end + @parent = parent + install_win(@parent.path, widgetname) + tk_call_without_enc(@parent.path, 'clone', @path, type) + end +=end + def initialize(src_menu, *args) + widgetname = nil + + if args[0].kind_of?(TkWindow) # parent window + parent = args.shift + else + parent = src_menu + end + + if args[0].kind_of?(String) || args[0].kind_of?(Symbol) # menu type + type = args.shift + else + type = None # 'normal' + end + + if args[0].kind_of?(Hash) + keys = _symbolkey2str(args.shift) + parent = keys.delete('parent') if keys.has_key?('parent') + widgetname = keys.delete('widgetname') + type = keys.delete('type') if keys.has_key?('type') + else + keys = nil + end + + @src_menu = src_menu + @parent = parent + @type = type + install_win(@parent.path, widgetname) + tk_call_without_enc(@src_menu.path, 'clone', @path, @type) + configure(keys) if keys && !keys.empty? + end + + def source_menu + @src_menu + end +end +TkCloneMenu = TkMenuClone + +module TkSystemMenu + def initialize(parent, keys=nil) + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + end + #unless parent.kind_of? TkMenu + # fail ArgumentError, "parent must be a TkMenu object" + #end + # @path = Kernel.format("%s.%s", parent.path, self.class::SYSMENU_NAME) + @path = parent.path + '.' + self.class::SYSMENU_NAME + #TkComm::Tk_WINDOWS[@path] = self + TkCore::INTERP.tk_windows[@path] = self + if self.method(:create_self).arity == 0 + p 'create_self has no arg' if $DEBUG + create_self + configure(keys) if keys + else + p 'create_self has an arg' if $DEBUG + create_self(keys) + end + end +end + + +class TkSysMenu_Help<TkMenu + # for all platform + include TkSystemMenu + SYSMENU_NAME = 'help' +end + + +class TkSysMenu_System<TkMenu + # for Windows + include TkSystemMenu + SYSMENU_NAME = 'system' +end + + +class TkSysMenu_Apple<TkMenu + # for Machintosh + include TkSystemMenu + SYSMENU_NAME = 'apple' +end + + +class TkMenubutton<TkLabel + TkCommandNames = ['menubutton'.freeze].freeze + WidgetClassName = 'Menubutton'.freeze + WidgetClassNames[WidgetClassName] = self + def create_self(keys) + if keys and keys != None + # tk_call_without_enc('menubutton', @path, *hash_kv(keys, true)) + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + # tk_call_without_enc('menubutton', @path) + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __boolval_optkeys + super() << 'indicatoron' + end + private :__boolval_optkeys + +end +TkMenuButton = TkMenubutton + + +class TkOptionMenubutton<TkMenubutton + TkCommandNames = ['tk_optionMenu'.freeze].freeze + + class OptionMenu<TkMenu + def initialize(path) #==> return value of tk_optionMenu + @path = path + #TkComm::Tk_WINDOWS[@path] = self + TkCore::INTERP.tk_windows[@path] = self + end + end + + def initialize(*args) + # args :: [parent,] [var,] [value[, ...],] [keys] + # parent --> TkWindow or nil + # var --> TkVariable or nil + # keys --> Hash + # keys[:parent] or keys['parent'] --> parent + # keys[:variable] or keys['variable'] --> var + # keys[:values] or keys['values'] --> value, ... + # other Hash keys are menubutton options + keys = {} + keys = args.pop if args[-1].kind_of?(Hash) + keys = _symbolkey2str(keys) + + parent = nil + if args[0].kind_of?(TkWindow) || args[0] == nil + keys.delete('parent') # ignore + parent = args.shift + else + parent = keys.delete('parent') + end + + @variable = nil + if args[0].kind_of?(TkVariable) || args[0] == nil + keys.delete('variable') # ignore + @variable = args.shift + else + @variable = keys.delete('variable') + end + @variable = TkVariable.new unless @variable + + (args = keys.delete('values') || []) if args.empty? + if args.empty? + args << @variable.value + else + @variable.value = args[0] + end + + install_win(if parent then parent.path end) + @menu = OptionMenu.new(tk_call('tk_optionMenu', + @path, @variable.id, *args)) + + configure(keys) if keys + end + + def value + @variable.value + end + + def value=(val) + @variable.value = val + 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.insert(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 +TkOptionMenuButton = TkOptionMenubutton diff --git a/ruby_1_8_6/ext/tk/lib/tk/menubar.rb b/ruby_1_8_6/ext/tk/lib/tk/menubar.rb new file mode 100644 index 0000000000..392b6fbd4e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/menubar.rb @@ -0,0 +1,131 @@ +# +# tk/menubar.rb +# +# Original version: +# 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') +# +# +# OR +# +# radio_var = TkVariable.new('y') +# menu_spec = [ +# [['File', 0], +# {:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0}, +# '---', +# ['Check_A', TkVariable.new(true), 6], +# {:type=>'checkbutton', :label=>'Check_B', +# :variable=>TkVariable.new, :underline=>6}, +# '---', +# ['Radio_X', [radio_var, 'x'], 6], +# ['Radio_Y', [radio_var, 'y'], 6], +# ['Radio_Z', [radio_var, 'z'], 6], +# '---', +# ['cascade', [ +# ['sss', proc{p 'sss'}, 0], +# ['ttt', proc{p 'ttt'}, 0], +# ['uuu', proc{p 'uuu'}, 0], +# ['vvv', proc{p 'vvv'}, 0], +# ], 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'=>'Helvetia 12 bold') +# menubar.pack('side'=>'top', 'fill'=>'x') + +# See tk/menuspce.rb about the format of the menu_spec + +# 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' +require 'tk/composite' +require 'tk/menuspec' + +class TkMenubar<TkFrame + include TkComposite + include TkMenuSpec + + def initialize(parent = nil, spec = nil, options = nil) + if parent.kind_of? Hash + options = _symbolkey2str(parent) + spec = options.delete('spec') + super(options) + else + super(parent, options) + end + + @menus = [] + + spec.each{|info| add_menu(info)} if spec + + options.each{|key, value| configure(key, value)} if options + end + + def add_menu(menu_info) + mbtn, menu = _create_menubutton(@frame, menu_info) + + submenus = _get_cascade_menus(menu).flatten + + @menus.push([mbtn, menu]) + delegate('tearoff', menu, *submenus) + delegate('foreground', mbtn, menu, *submenus) + delegate('background', mbtn, menu, *submenus) + delegate('disabledforeground', mbtn, menu, *submenus) + delegate('activeforeground', mbtn, menu, *submenus) + delegate('activebackground', mbtn, menu, *submenus) + delegate('font', mbtn, menu, *submenus) + delegate('kanjifont', mbtn, menu, *submenus) + end + + def [](index) + return @menus[index] + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/menuspec.rb b/ruby_1_8_6/ext/tk/lib/tk/menuspec.rb new file mode 100644 index 0000000000..118a4f42b1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/menuspec.rb @@ -0,0 +1,269 @@ +# +# tk/menuspec.rb +# Hidethoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# based on tkmenubar.rb : +# Copyright (C) 1998 maeda shugo. All rights reserved. +# This file can be distributed under the terms of the Ruby. +# +# The format of the menu_spec is: +# [ menu_info, menu_info, ... ] +# +# And the format of the menu_info is: +# [ +# [text, underline, configs], # menu button/entry (*1) +# [label, command, underline, accelerator, configs], # command entry +# [label, TkVar_obj, underline, accelerator, configs], # checkbutton entry +# [label, [TkVar_obj, value], +# underline, accelerator, configs], # radiobutton entry +# [label, [[...menu_info...], [...menu_info...], ...], +# underline, accelerator, configs], # cascade entry (*2) +# '---', # separator +# ... +# ] +# +# underline, accelerator, and configs are optional pearameters. +# Hashes are OK instead of Arrays. Then the entry type ('command', +# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key +# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info +# is acceptable for 'menu' key (then, create sub-menu). +# +# NOTE: (*1) +# If you want to make special menus (*.help for UNIX, *.system for Win, +# and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX, +# 'system' for Win, and 'apple' for Mac) option to the configs hash of +# menu button/entry information. +# +# NOTE: (*2) +# If you want to configure a cascade menu, add :menu_config=>{...configs..} +# to the configs of the cascade entry. + +module TkMenuSpec + def _create_menu(parent, menu_info, menu_name = nil, + tearoff = false, default_opts = nil) + if tearoff.kind_of?(Hash) + default_opts = tearoff + tearoff = false + end + + if menu_name.kind_of?(Hash) + default_opts = menu_name + menu_name = nil + tearoff = false + end + + if default_opts.kind_of?(Hash) + orig_opts = _symbolkey2str(default_opts) + else + orig_opts = {} + end + + tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff') + + if menu_name + menu = TkMenu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff) + else + menu = TkMenu.new(parent, :tearoff=>tearoff) + end + + for item_info in menu_info + if item_info.kind_of?(Hash) + options = orig_opts.dup + options.update(_symbolkey2str(item_info)) + item_type = (options.delete('type') || 'command').to_s + menu_name = options.delete('menu_name') + menu_opts = orig_opts.dup + menu_opts.update(_symbolkey2str(options.delete('menu_config') || {})) + if item_type == 'cascade' && options['menu'].kind_of?(Array) + # create cascade menu + submenu = _create_menu(menu, options['menu'], menu_name, + tearoff, menu_opts) + options['menu'] = submenu + end + menu.add(item_type, options) + + elsif item_info.kind_of?(Array) + options = orig_opts.dup + + options['label'] = item_info[0] if item_info[0] + + case item_info[1] + when TkVariable + # checkbutton + item_type = 'checkbutton' + options['variable'] = item_info[1] + options['onvalue'] = true + options['offvalue'] = false + + when Array + # radiobutton or cascade + if item_info[1][0].kind_of?(TkVariable) + # radiobutton + item_type = 'radiobutton' + options['variable'] = item_info[1][0] + options['value'] = item_info[1][1] if item_info[1][1] + + else + # cascade + item_type = 'cascade' + menu_opts = orig_opts.dup + if item_info[4] && item_info[4].kind_of?(Hash) + opts = _symbolkey2str(item_info[4]) + menu_name = opts.delete('menu_name') + menu_config = opts.delete('menu_config') || {} + menu_opts.update(_symbolkey2str(menu_config)) + end + submenu = _create_menu(menu, item_info[1], menu_name, + tearoff, menu_opts) + options['menu'] = submenu + end + + else + # command + item_type = 'command' + options['command'] = item_info[1] if item_info[1] + end + + options['underline'] = item_info[2] if item_info[2] + options['accelerator'] = item_info[3] if item_info[3] + if item_info[4] && item_info[4].kind_of?(Hash) + opts = _symbolkey2str(item_info[4]) + if item_type == 'cascade' + opts.delete('menu_name') + opts.delete('menu_config') + end + options.update(opts) + end + menu.add(item_type, options) + + elsif /^-+$/ =~ item_info + menu.add('separator') + + else + menu.add('command', 'label' => item_info) + end + end + + menu + end + private :_create_menu + + def _use_menubar?(parent) + use_menubar = false + if parent.kind_of?(TkRoot) || parent.kind_of?(TkToplevel) + return true + else + begin + parent.cget('menu') + return true + rescue + end + end + false + end + private :_use_menubar? + + def _create_menu_for_menubar(parent) + unless (mbar = parent.menu).kind_of?(TkMenu) + mbar = TkMenu.new(parent, :tearoff=>false) + parent.menu(mbar) + end + mbar + end + private :_create_menu_for_menubar + + def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil) + btn_info = menu_info[0] + + if tearoff.kind_of?(Hash) + default_opts = tearoff + tearoff = false + end + + if default_opts.kind_of?(Hash) + keys = _symbolkey2str(default_opts) + else + keys = {} + end + + tearoff = keys.delete('tearoff') if keys.key?('tearoff') + + if _use_menubar?(parent) + # menubar by menu entries + + mbar = _create_menu_for_menubar(parent) + + menu_name = nil + + if btn_info.kind_of?(Hash) + keys.update(_symbolkey2str(btn_info)) + menu_name = keys.delete('menu_name') + keys['label'] = keys.delete('text') if keys.key?('text') + elsif btn_info.kind_of?(Array) + keys['label'] = btn_info[0] if btn_info[0] + keys['underline'] = btn_info[1] if btn_info[1] + if btn_info[2]&&btn_info[2].kind_of?(Hash) + keys.update(_symbolkey2str(btn_info[2])) + menu_name = keys.delete('menu_name') + end + else + keys = {:label=>btn_info} + end + + menu = _create_menu(mbar, menu_info[1..-1], menu_name, + tearoff, default_opts) + menu.tearoff(tearoff) + + keys['menu'] = menu + mbar.add('cascade', keys) + + [mbar, menu] + + else + # menubar by menubuttons + mbtn = TkMenubutton.new(parent) + + menu_name = nil + + if btn_info.kind_of?(Hash) + keys.update(_symbolkey2str(btn_info)) + menu_name = keys.delete('menu_name') + keys['text'] = keys.delete('label') if keys.key?('label') + mbtn.configure(keys) + elsif btn_info.kind_of?(Array) + mbtn.configure('text', btn_info[0]) if btn_info[0] + mbtn.configure('underline', btn_info[1]) if btn_info[1] + # mbtn.configure('accelerator', btn_info[2]) if btn_info[2] + if btn_info[2]&&btn_info[2].kind_of?(Hash) + keys.update(_symbolkey2str(btn_info[2])) + menu_name = keys.delete('menu_name') + mbtn.configure(keys) + end + else + mbtn.configure('text', btn_info) + end + + mbtn.pack('side' => 'left') + + menu = _create_menu(mbtn, menu_info[1..-1], menu_name, + tearoff, default_opts) + + mbtn.menu(menu) + + [mbtn, menu] + end + end + private :_create_menubutton + + def _get_cascade_menus(menu) + menus = [] + (0..(menu.index('last'))).each{|idx| + if menu.menutype(idx) == 'cascade' + submenu = menu.entrycget(idx, 'menu') + menus << [submenu, _get_cascade_menus(submenu)] + end + } + menus + end + private :_get_cascade_menus +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/message.rb b/ruby_1_8_6/ext/tk/lib/tk/message.rb new file mode 100644 index 0000000000..79121bebb3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/message.rb @@ -0,0 +1,19 @@ +# +# tk/message.rb : treat message widget +# +require 'tk' +require 'tk/label' + +class TkMessage<TkLabel + TkCommandNames = ['message'.freeze].freeze + WidgetClassName = 'Message'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('message', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('message', @path) + # end + #end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/mngfocus.rb b/ruby_1_8_6/ext/tk/lib/tk/mngfocus.rb new file mode 100644 index 0000000000..1a2049c8a8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/mngfocus.rb @@ -0,0 +1,33 @@ +# +# tk/mngfocus.rb : methods for Tcl/Tk standard library 'focus.tcl' +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +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(win) + tk_tcl2ruby(tk_call('tk_focusNext', win)) + end + def focusNext + TkManageFocus.next(self) + end + + def TkManageFocus.prev(win) + tk_tcl2ruby(tk_call('tk_focusPrev', win)) + end + def focusPrev + TkManageFocus.prev(self) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/msgcat.rb b/ruby_1_8_6/ext/tk/lib/tk/msgcat.rb new file mode 100644 index 0000000000..061e43fd89 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/msgcat.rb @@ -0,0 +1,292 @@ +# +# tk/msgcat.rb : methods for Tcl message catalog +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +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') + + PACKAGE_NAME = 'msgcat'.freeze + def self.package_name + PACKAGE_NAME + end + + 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, *args) + src_str = sprintf(src_str, *args) unless args.empty? + 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 SystemExit + exit(0) + rescue Interrupt + exit!(1) + 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 + super(id, *args) +# 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') + if trans_str && trans_str != None + trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) + Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true), + trans_str)) + else + Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true))) + end + end + def set_translation(locale, src_str, trans_str=None, enc='utf-8') + if trans_str && trans_str != None + trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) + Tk.UTF8_String(@namespace.eval{ + tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true), + trans_str) + }) + else + Tk.UTF8_String(@namespace.eval{ + tk_call_without_enc('::msgcat::mcset', + locale, + _get_eval_string(src_str, true))}) + end + 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/ruby_1_8_6/ext/tk/lib/tk/namespace.rb b/ruby_1_8_6/ext/tk/lib/tk/namespace.rb new file mode 100644 index 0000000000..5bf6474c5b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/namespace.rb @@ -0,0 +1,500 @@ +# +# tk/namespace.rb : methods to manipulate Tcl/Tk namespace +# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +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 + + Tk_NsCode_RetObjID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ + Tk_Namespace_ID_TBL.clear + Tk_NsCode_RetObjID_TBL.clear + } + + def TkNamespace.id2obj(id) + Tk_Namespace_ID_TBL[id]? Tk_Namespace_ID_TBL[id]: id + end + + ##################################### + + class Ensemble < TkObject + def __cget_cmd + ['namespace', 'ensemble', 'configure', self.path] + end + private :__cget_cmd + + def __config_cmd + ['namespace', 'ensemble', 'configure', self.path] + end + private :__config_cmd + + def __configinfo_struct + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>nil, :current_value=>2} + end + private :__configinfo_struct + + def __boolval_optkeys + ['prefixes'] + end + private :__boolval_optkeys + + def __listval_optkeys + ['map', 'subcommands', 'unknown'] + end + private :__listval_optkeys + + def self.exist?(ensemble) + bool(tk_call('namespace', 'ensemble', 'exists', ensemble)) + end + + def initialize(keys = {}) + @ensemble = @path = tk_call('namespace', 'ensemble', 'create', keys) + end + + def cget(slot) + if slot == :namespace || slot == 'namespace' + ns = super(slot) + if TkNamespace::Tk_Namespace_ID_TBL.key?(ns) + TkNamespace::Tk_Namespace_ID_TBL[ns] + else + ns + end + else + super(slot) + end + end + + def configinfo(slot = nil) + if slot + if slot == :namespace || slot == 'namespace' + val = super(slot) + if TkNamespace::Tk_Namespace_ID_TBL.key?(val) + val = TkNamespace::Tk_Namespace_ID_TBL[val] + end + else + val = super(slot) + end + + if TkComm::GET_CONFIGINFO_AS_ARRAY + [slot.to_s, val] + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + {slot.to_s => val} + end + + else + info = super() + + if TkComm::GET_CONFIGINFO_AS_ARRAY + info.map!{|inf| + if inf[0] == 'namespace' && + TkNamespace::Tk_Namespace_ID_TBL.key?(inf[-1]) + [inf[0], TkNamespace::Tk_Namespace_ID_TBL[inf[-1]]] + else + inf + end + } + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + val = info['namespace'] + if TkNamespace::Tk_Namespace_ID_TBL.key?(val) + info['namespace'] = TkNamespace::Tk_Namespace_ID_TBL[val] + end + end + + info + end + end + + def exists? + bool(tk_call('namespace', 'ensemble', 'exists', @path)) + end + end + + ##################################### + + 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, true))? 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, true))? 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, true))? 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, use_obj_id = false) + @scope = scope + ' ' + @use_obj_id = use_obj_id + end + def path + @scope + end + def to_eval + @scope + end + def call(*args) + ret = TkCore::INTERP._eval_without_enc(@scope + array2tk_list(args)) + if @use_obj_id + ret = TkNamespace::Tk_NsCode_RetObjID_TBL.delete(ret.to_i) + end + ret + end + end + + ##################################### + + def install_cmd(cmd) + lst = tk_split_simplelist(super(cmd), false, false) + if lst[1] =~ /^::/ + lst[1] = @fullname + else + lst.insert(1, @fullname) + end + TkCore::INTERP._merge_tklist(*lst) + 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, true))? 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, true))? 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, true))? 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('') + name = Tk_Namespace_ID.join(TkCore::INTERP._ip_id_) + 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 ::= [<namespace>] [<pattern>] + # <pattern> must be glob-style pattern + tk_split_simplelist(tk_call('namespace', 'children', *args)).collect{|ns| + # ns is fullname + if Tk_Namespace_ID_TBL.key?(ns) + Tk_Namespace_ID_TBL[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 +=begin + 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 +=end + def code(script = Proc.new) + if script.kind_of?(String) + cmd = proc{|*args| + ret = ScopeArgs.new(@fullname,*args).instance_eval(script) + id = ret.object_id + TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret + id + } + elsif script.kind_of?(Proc) + cmd = proc{|*args| + ret = ScopeArgs.new(@fullname,*args).instance_eval(&script) + id = ret.object_id + TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret + id + } + else + fail ArgumentError, "String or Proc is expected" + end + TkNamespace::NsCode.new(tk_call_without_enc('namespace', 'code', + _get_eval_string(cmd, false)), + true) + end + + def self.current_path + tk_call('namespace', 'current') + end + def current_path + @fullname + end + + def self.current + ns = self.current_path + if Tk_Namespace_ID_TBL.key?(ns) + Tk_Namespace_ID_TBL[ns] + else + ns + end + end + def current_namespace + # ns_tk_call('namespace', 'current') + # @fullname + self + end + alias current current_namespace + + def self.delete(*ns_list) + tk_call('namespace', 'delete', *ns_list) + ns_list.each{|ns| + if ns.kind_of?(TkNamespace) + Tk_Namespace_ID_TBL.delete(ns.path) + else + Tk_Namespace_ID_TBL.delete(ns.to_s) + end + } + 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 +=begin + 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]) + uninstall_cmd(_fromUTF8(TkCore::INTERP._split_tklist(_toUTF8(code_obj.path))[-1])) + tk_tcl2ruby(ret) + end +=end + def eval(cmd = Proc.new, *args) + code_obj = code(cmd) + ret = code_obj.call(*args) + uninstall_cmd(_fromUTF8(TkCore::INTERP._split_tklist(_toUTF8(code_obj.path))[-1])) + ret + end + + def self.exist?(ns) + bool(tk_call('namespace', 'exists', ns)) + end + def exist? + TkNamespece.exist?(@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.inscope(@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_Namespace_ID_TBL.key?(ns) + Tk_Namespace_ID_TBL[ns] + else + ns + end + end + def parent + tk_call('namespace', 'parent', @fullname) + end + + def self.get_path + tk_call('namespace', 'path') + end + def self.set_path(*namespace_list) + tk_call('namespace', 'path', array2tk_list(namespace_list)) + end + def set_path + tk_call('namespace', 'path', @fullname) + end + + def self.qualifiers(str) + tk_call('namespace', 'qualifiers', str) + end + + def self.tail(str) + tk_call('namespace', 'tail', str) + end + + def self.upvar(namespace, *var_pairs) + tk_call('namespace', 'upvar', namespace, *(var_pairs.flatten)) + end + def upvar(*var_pairs) + TkNamespace.inscope(@fullname, *(var_pairs.flatten)) + end + + def self.get_unknown_handler + tk_tcl2ruby(tk_call('namespace', 'unknown')) + end + def self.set_unknown_handler(cmd = Proc.new) + tk_call('namespace', 'unknown', cmd) + 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 + +TkNamespace::Global = TkNamespace.new('::') diff --git a/ruby_1_8_6/ext/tk/lib/tk/optiondb.rb b/ruby_1_8_6/ext/tk/lib/tk/optiondb.rb new file mode 100644 index 0000000000..a806f3971d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/optiondb.rb @@ -0,0 +1,371 @@ +# +# tk/optiondb.rb : treat option database +# +require 'tk' + +module TkOptionDB + include Tk + extend Tk + + TkCommandNames = ['option'.freeze].freeze + CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint].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 + alias read_file readfile + module_function :add, :clear, :get, :readfile, :read_file + + 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)? Tk.encoding : Tk.encoding_system) + + unless f_enc + f_enc = i_enc + end + + ent = [] + cline = '' + open(file, 'r') {|f| + while line = f.gets + #cline += line.chomp! + cline.concat(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 + + @@resource_proc_class.const_set(:CARRIER, '.'.freeze) + + @@resource_proc_class.instance_variable_set('@method_tbl', + TkCore::INTERP.create_table) + @@resource_proc_class.instance_variable_set('@add_method', false) + @@resource_proc_class.instance_variable_set('@safe_mode', 4) + + class << @@resource_proc_class + private :new + +=begin + CARRIER = '.'.freeze + METHOD_TBL = TkCore::INTERP.create_table + ADD_METHOD = false + SAFE_MODE = 4 +=end + +=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] + res_proc, proc_str = @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) + unless TkComm._callback_entry?(res_proc) + #if id == :new || !(self::METHOD_TBL.has_key?(id) || self::ADD_METHOD) + if id == :new || !(@method_tbl.has_key?(id) || @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) + eval("$SAFE = #{@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] + @method_tbl[id] = [res_proc, proc_source] + end + res_proc.call(*args) + end + + private :__check_proc_string__, :method_missing + end + @@resource_proc_class.freeze + +=begin + 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 +=end + def __create_new_class(klass, func, safe = 4, add = false, parent = nil) + if klass.kind_of?(TkWindow) + carrier = klass.path + klass = CmdClassID.join(TkCore::INTERP._ip_id_) + CmdClassID[1].succ! + parent = nil # ignore parent + else + klass = klass.to_s if klass.kind_of?(Symbol) + unless (?A..?Z) === klass[0] + fail ArgumentError, "bad string '#{klass}' for class name" + end + if parent == nil + install_win(nil) + elsif parent.kind_of?(TkWindow) + install_win(parent.path) + 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) + end + + unless func.kind_of?(Array) + fail ArgumentError, "method-list must be Array" + end + func_str = func.join(' ') + + if parent.kind_of?(Class) && parent <= @@resource_proc_class + cmd_klass = Class.new(parent) + else + cmd_klass = Class.new(TkOptionDB.module_eval('@@resource_proc_class')) + end + cmd_klass.const_set(:CARRIER, carrier.dup.freeze) + + cmd_klass.instance_variable_set('@method_tbl', TkCore::INTERP.create_table) + cmd_klass.instance_variable_set('@add_method', add) + cmd_klass.instance_variable_set('@safe_mode', safe) + func.each{|f| + cmd_klass.instance_variable_get('@method_tbl')[f.to_s.intern] = nil + } +=begin + cmd_klass.const_set(:METHOD_TBL, TkCore::INTERP.create_table) + cmd_klass.const_set(:ADD_METHOD, add) + cmd_klass.const_set(:SAFE_MODE, safe) + func.each{|f| cmd_klass::METHOD_TBL[f.to_s.intern] = nil } +=end + + cmd_klass + 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 + def __null_method(*args); nil; end + [ :class_eval, :name, :superclass, :clone, :dup, :autoload, :autoload?, + :ancestors, :const_defined?, :const_get, :const_set, :const_missing, + :class_variables, :constants, :included_modules, :instance_methods, + :method_defined?, :module_eval, :private_instance_methods, + :protected_instance_methods, :public_instance_methods, + :singleton_methods, :remove_const, :remove_method, :undef_method, + :to_s, :inspect, :display, :method, :methods, :respond_to?, + :instance_variable_get, :instance_variable_set, :instance_method, + :instance_eval, :instance_variables, :kind_of?, :is_a?, + :private_methods, :protected_methods, :public_methods ].each{|m| + alias_method(m, :__null_method) + } + 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/ruby_1_8_6/ext/tk/lib/tk/optionobj.rb b/ruby_1_8_6/ext/tk/lib/tk/optionobj.rb new file mode 100644 index 0000000000..8fe7e0ee5a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/optionobj.rb @@ -0,0 +1,212 @@ +# +# tk/optionobj.rb : control options for a group of widgets +# +# NOTE: If you want to use key-only option (no value), +# use Tk::None for the value of the key-only option. +# +# e.g. hash_kv({'aaa'=>1, 'bbb'=>Tk::None, 'ccc'=>3}) +# => ["-aaa", 1, "-bbb", "-ccc", 3] +# +require 'tk' + +module Tk + class OptionObj < Hash + include TkUtil + + def initialize(hash = nil) + super() + @observ = [] + update_without_notify(_symbolkey2str(hash)) if hash + end + + def observ_info + @observ.dup + end + + def observs + @observ.collect{|win| + if win.kind_of?(Array) + win[0] + else + win + end + } + end + + def _remove_win(win) + if win.kind_of?(Array) + widget, method = win + @observ.delete_if{|x| + if x.kind_of?(Array) + x[0] == widget + else + x == widget + end + } + else + @observ.delete_if{|x| + if x.kind_of?(Array) + x[0] == win + else + x == win + end + } + end + end + private :_remove_win + + def assign(*wins) + # win := + # widget #==> call widget.configure(hash) + # [widget] #==> call widget.configure(hash) + # [widget, nil, {src=>target, ... }] + # #==> call widget.configure(hash) + # with converting hash-key + # [widget, method] #==> call widget.method(hash) + # [widget, method, {src=>target, ... }] + # #==> call widget.method(hash) + # with converting hash-key + # [widget [receiver, method, arg, ... ]] + # #==> call receiver.method(arg, ... , hash) + # [widget [receiver, method, arg, ... ], {src=>target, ... }] + # #==> call receiver.method(arg, ... , hash) + # with onverting hash-key + # + # src := option_name_on_optobj + # + # target := + # nil #==> not use the src + # option_name_on_target_widget + # [ option_name_on_target_widget, ... ] + # #==> set all of them + # + wins.each{|win| + _remove_win(win) + @observ << win + notify(win) + } + self + end + + def unassign(*wins) + wins.each{|win| + _remove_win(win) + } + self + end + + def notify(target = nil) + if target + targets = [target] + elsif @observ.empty? + return self + else + targets = @observ.dup + end + + return self if empty? + + org_hash = _symbolkey2str(self) + + targets.each{|win| + widget = receiver = win + hash = org_hash + begin + if win.kind_of?(Array) + widget, method, conv_tbl = win + receiver = widget + + if conv_tbl + hash = {} + org_hash.each{|key, val| + key = conv_tbl[key] if conv_tbl.key?(key) + next unless key + if key.kind_of?(Array) + key.each{|k| hash[k] = val} + else + hash[key] = val + end + } + end + + if method.kind_of?(Array) + receiver, method, *args = method + receiver.__send__(method, *(args << hash)) + elsif method + widget.__send__(method, hash) + else + widget.configure(hash) + end + + else + widget.configure(self) + end + rescue => e + if ( ( widget.kind_of?(TkObject) \ + && widget.respond_to?('exist?') \ + && ! receiver.exist? ) \ + || ( receiver.kind_of?(TkObject) \ + && receiver.respond_to?('exist?') \ + && ! receiver.exist? ) ) + @observ.delete(win) + else + fail e + end + end + } + + self + end + alias apply notify + + def +(hash) + unless hash.kind_of?(Hash) + fail ArgumentError, "expect a Hash" + end + new_obj = self.dup + new_obj.update_without_notify(_symbolkey2str(hash)) + new_obj + end + + alias update_without_notify update + + def update(hash) + update_without_notify(_symbolkey2str(hash)) + notify + end + + def configure(key, value=nil) + if key.kind_of?(Hash) + update(key) + else + store(key,value) + end + end + + def [](key) + super(key.to_s) + end + alias cget [] + + def store(key, val) + key = key.to_s + super(key, val) + notify + end + def []=(key, val) + store(key,val) + end + + def replace(hash) + super(_symbolkey2str(hash)) + notify + end + + def default(opt) + fail RuntimeError, "unknown option `#{opt}'" + end + private :default + + undef :default= + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/pack.rb b/ruby_1_8_6/ext/tk/lib/tk/pack.rb new file mode 100644 index 0000000000..8fab363121 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/pack.rb @@ -0,0 +1,90 @@ +# +# 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 + alias pack configure + + 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, mode=None) + # master = master.epath if master.kind_of?(TkObject) + master = _epath(master) + if mode == None + bool(tk_call_without_enc('pack', 'propagate', master)) + else + tk_call_without_enc('pack', 'propagate', master, mode) + 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 :pack, :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/ruby_1_8_6/ext/tk/lib/tk/package.rb b/ruby_1_8_6/ext/tk/lib/tk/package.rb new file mode 100644 index 0000000000..d1eb27674d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/package.rb @@ -0,0 +1,139 @@ +# +# 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 if_needed(pkg, ver, *arg, &b) + size = arg.size + + if size==0 && !b + # proc info + procedure(tk_call('package', 'ifneeded', pkg, ver)) + + elsif size==0 && b + # set proc + cmd = proc(&b) + tk_call('package', 'ifneeded', pkg, ver, cmd) + cmd + + elsif size==1 && !b + # set proc + cmd = arg[0] + if cmd + tk_call('package', 'ifneeded', pkg, ver, cmd) + cmd + else + # remove proc + tk_call('package', 'ifneeded', pkg, ver, '') + nil + end + + else + fail ArgumentError, 'too many arguments' + end + end + + def names + tk_split_simplelist(tk_call('package', 'names')) + end + + def provide(package, version=nil) + if version + tk_call('package', 'provide', package, version) + end + if (ret = tk_call('package', 'provide', package)) == '' + nil + else + ret + end + end + + def present(package, version=None) + begin + tk_call('package', 'present', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def present_exact(package, version) + begin + tk_call('package', 'present', '-exact', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def require(package, version=None) + begin + tk_call('package', 'require', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def require_exact(package, version) + begin + tk_call('package', 'require', '-exact', package, version) + rescue => e + fail e.class, 'TkPackage ' << e.message + end + end + + def unknown_proc(*arg, &b) + size = arg.size + + if size==0 && !b + # proc info + procedure(tk_call('package', 'unknown')) + + elsif size==0 && b + # set proc + cmd = proc(&b) + tk_call('package', 'unknown', cmd) + cmd + + elsif size==1 && !b + # set proc + cmd = arg[0] + if cmd + tk_call('package', 'unknown', cmd) + cmd + else + # remove proc + tk_call('package', 'unknown', '') + nil + end + + else + fail ArgumentError, 'too many arguments' + end + 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/ruby_1_8_6/ext/tk/lib/tk/palette.rb b/ruby_1_8_6/ext/tk/lib/tk/palette.rb new file mode 100644 index 0000000000..2b6fdf5d90 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/palette.rb @@ -0,0 +1,55 @@ +# +# tk/palette.rb : methods for Tcl/Tk standard library 'palette.tcl' +# 1998/06/21 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +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(win, colors) + if not colors.kind_of?(Hash) + fail "2nd arg need to be Hash" + end + + tk_call('global', "tkPalette") + colors.each{|key, value| + begin + if win.cget(key) == tk_call('set', "tkPalette(#{key})") + win[key] = colors[key] + end + rescue + # ignore + end + } + + TkWinfo.children(win).each{|w| TkPalette.recolorTree(w, colors)} + end + + def recolorTree(colors) + TkPalette.recolorTree(self, colors) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/panedwindow.rb b/ruby_1_8_6/ext/tk/lib/tk/panedwindow.rb new file mode 100644 index 0000000000..c6cf3cd11f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/panedwindow.rb @@ -0,0 +1,232 @@ +# +# tk/panedwindow.rb : treat panedwindow +# +require 'tk' + +class TkPanedWindow<TkWindow + TkCommandNames = ['panedwindow'.freeze].freeze + WidgetClassName = 'Panedwindow'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('panedwindow', @path) + # end + #end + #private :create_self + + def add(*args) + keys = args.pop + fail ArgumentError, "no window in arguments" unless keys + if keys && keys.kind_of?(Hash) + fail ArgumentError, "no window in arguments" if args == [] + # args = args.collect{|w| (w.kind_of?(TkObject))? w.epath: w } + args = args.collect{|w| _epath(w) } + #args.push(hash_kv(keys)) + args.concat(hash_kv(keys)) + else + args.push(keys) if keys + # args = args.collect{|w| (w.kind_of?(TkObject))? w.epath: w } + args = args.collect{|w| _epath(w) } + end + tk_send_without_enc('add', *args) + self + end + + def forget(win, *wins) + wins.unshift(win) + # tk_send_without_enc('forget', *((w.kind_of?(TkObject))? w.epath: w)) + tk_send_without_enc('forget', *(wins.collect{|w| _epath(w)})) + self + end + alias del forget + alias delete forget + alias remove forget + + def identify(x, y) + list(tk_send_without_enc('identify', x, y)) + end + + def proxy_coord + list(tk_send_without_enc('proxy', 'coord')) + end + def proxy_forget + tk_send_without_enc('proxy', 'forget') + self + end + def proxy_place(x, y) + tk_send_without_enc('proxy', 'place', x, y) + self + end + + def sash_coord(index) + list(tk_send('sash', 'coord', index)) + end + def sash_dragto(index, x, y) + tk_send('sash', 'dragto', index, x, y) + self + end + def sash_mark(index, x, y) + tk_send('sash', 'mark', index, x, y) + self + end + def sash_place(index, x, y) + tk_send('sash', 'place', index, x, y) + self + end + + def panecget(win, key) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + tk_tcl2ruby(tk_send_without_enc('panecget', win, "-#{key}")) + end + + def paneconfigure(win, key, value=nil) + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if key.kind_of? Hash + params = [] + key.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_send_without_enc('paneconfigure', win, *params) + else + # value = value.epath if value.kind_of?(TkObject) + value = _epath(value) + tk_send_without_enc('paneconfigure', win, "-#{key}", value) + end + self + end + alias pane_config paneconfigure + + def paneconfiginfo(win, key=nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if key + #conf = tk_split_list(tk_send_without_enc('paneconfigure', + # win, "-#{key}")) + conf = tk_split_list(tk_send_without_enc('paneconfigure', + win, "-#{key}"), + false, true) + conf[0] = conf[0][1..-1] + if conf[0] == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + conf[4] = bool(conf[4]) unless conf[4].empty? + end + conf + else + #tk_split_simplelist(tk_send_without_enc('paneconfigure', + # win)).collect{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('paneconfigure', win), + false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + conf[0] = conf[0][1..-1] + if conf[3] + if conf[0] == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + elsif conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[0] == 'hide' + conf[4] = bool(conf[4]) unless conf[4].empty? + elsif conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + # win = win.epath if win.kind_of?(TkObject) + win = _epath(win) + if key + #conf = tk_split_list(tk_send_without_enc('paneconfigure', + # win, "-#{key}")) + conf = tk_split_list(tk_send_without_enc('paneconfigure', + win, "-#{key}"), + false, true) + key = conf.shift[1..-1] + if key == 'hide' + conf[2] = bool(conf[2]) unless conf[2].empty? + conf[3] = bool(conf[3]) unless conf[3].empty? + end + { key => conf } + else + ret = {} + #tk_split_simplelist(tk_send_without_enc('paneconfigure', + # win)).each{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('paneconfigure', win), + false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + key = conf.shift[1..-1] + if key + if key == 'hide' + conf[2] = bool(conf[2]) unless conf[2].empty? + elsif conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if key == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + elsif 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/ruby_1_8_6/ext/tk/lib/tk/place.rb b/ruby_1_8_6/ext/tk/lib/tk/place.rb new file mode 100644 index 0000000000..f7ebdfcbd6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/place.rb @@ -0,0 +1,128 @@ +# +# 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 + alias place configure + + 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 = tk_split_simplelist(tk_call_without_enc('place', 'configure', + win, "-#{slot}") ) + conf[0] = conf[0][1..-1] + conf[1] = tk_tcl2ruby(conf[1]) + conf[2] = tk_tcl2ruby(conf[1]) + conf[3] = tk_tcl2ruby(conf[1]) + conf[4] = tk_tcl2ruby(conf[1]) + conf + else + tk_split_simplelist(tk_call_without_enc('place', 'configure', + win)).collect{|conflist| + #conf = list(conflist) + conf = simplelist(conflist).collect!{|inf| tk_tcl2ruby(inf)} + 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 = tk_split_simplelist(tk_call_without_enc('place', 'configure', + win, "-#{slot}") ) + # { conf[0][1..-1] => conf[1] } + { conf[0][1..-1] => tk_tcl2ruby(conf[4]) } + else + ret = {} + #tk_split_list(tk_call_without_enc('place','configure',win)).each{|conf| + tk_split_simplelist(tk_call_without_enc('place', 'configure', + win)).each{|conf_list| + #ret[conf[0][1..-1]] = conf[1] + conf = simplelist(conf_list) + ret[conf[0][1..-1]] = tk_tcl2ruby(conf[4]) + } + 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)) + ilist = simplelist(tk_call_without_enc('place', 'info', win)) + info = {} + while key = ilist.shift + #info[key[1..-1]] = ilist.shift + info[key[1..-1]] = tk_tcl2ruby(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 :place, :configure, :configinfo, :current_configinfo + module_function :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/ruby_1_8_6/ext/tk/lib/tk/radiobutton.rb b/ruby_1_8_6/ext/tk/lib/tk/radiobutton.rb new file mode 100644 index 0000000000..f8f67d709a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/radiobutton.rb @@ -0,0 +1,66 @@ +# +# tk/radiobutton.rb : treat radiobutton widget +# +require 'tk' +require 'tk/button' + +class TkRadioButton<TkButton + TkCommandNames = ['radiobutton'.freeze].freeze + WidgetClassName = 'Radiobutton'.freeze + WidgetClassNames[WidgetClassName] = self + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('radiobutton', @path) + # end + #end + #private :create_self + + def __boolval_optkeys + super() << 'indicatoron' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'selectcolor' + end + private :__strval_optkeys + + def __ruby2val_optkeys # { key=>proc, ... } + { + 'variable'=>proc{|v| tk_trace_variable(v)} # for backward compatibility + } + end + private :__ruby2val_optkeys + + + def deselect + tk_send_without_enc('deselect') + self + end + def select + tk_send_without_enc('select') + self + end + + def get_value + var = tk_send_without_enc('cget', '-variable') + if TkVariable::USE_TCLs_SET_VARIABLE_FUNCTIONS + _fromUTF8(INTERP._get_global_var(var)) + else + INTERP._eval(Kernel.format('global %s; set %s', var, var)) + end + end + + def set_value(val) + var = tk_send_without_enc('cget', '-variable') + if TkVariable::USE_TCLs_SET_VARIABLE_FUNCTIONS + _fromUTF8(INTERP._set_global_var(var, _get_eval_string(val, true))) + else + s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' + INTERP._eval(Kernel.format('global %s; set %s %s', var, var, s)) + end + end +end +TkRadiobutton = TkRadioButton diff --git a/ruby_1_8_6/ext/tk/lib/tk/root.rb b/ruby_1_8_6/ext/tk/lib/tk/root.rb new file mode 100644 index 0000000000..0e5584c7c1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/root.rb @@ -0,0 +1,108 @@ +# +# tk/root.rb : treat root widget +# +require 'tk' +require 'tk/wm' +require 'tk/menuspec' + +class TkRoot<TkWindow + include Wm + include TkMenuSpec + + def __methodcall_optkeys # { key=>method, ... } + TOPLEVEL_METHODCALL_OPTKEYS + end + private :__methodcall_optkeys + +=begin + ROOT = [] + def TkRoot.new(keys=nil) + if ROOT[0] + Tk_WINDOWS["."] = ROOT[0] + return ROOT[0] + end + new = super(:without_creating=>true, :widgetname=>'.') + if keys # wm commands + keys.each{|k,v| + if v.kind_of? Array + new.send(k,*v) + else + new.send(k,v) + end + } + end + ROOT[0] = new + Tk_WINDOWS["."] = new + end +=end + def TkRoot.new(keys=nil, &b) + unless TkCore::INTERP.tk_windows['.'] + TkCore::INTERP.tk_windows['.'] = + super(:without_creating=>true, :widgetname=>'.'){} + end + root = TkCore::INTERP.tk_windows['.'] + + keys = _symbolkey2str(keys) + + # wm commands + root.instance_eval{ + __methodcall_optkeys.each{|key, method| + value = keys.delete(key.to_s) + self.__send__(method, value) if value + } + } + + if keys # wm commands ( for backward comaptibility ) + 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 self.to_eval + # self::WidgetClassName + '.' + end + + def create_self + @path = '.' + end + private :create_self + + def path + "." + end + + def add_menu(menu_info, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_info. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_info can override it. + if tearoff.kind_of?(Hash) + opts = tearoff + tearoff = false + end + _create_menubutton(self, menu_info, tearoff, opts) + end + + def add_menubar(menu_spec, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_spec. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_spec can override it. + menu_spec.each{|info| add_menu(info, tearoff, opts)} + self.menu + end + + def TkRoot.destroy + TkCore::INTERP._invoke('destroy', '.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scale.rb b/ruby_1_8_6/ext/tk/lib/tk/scale.rb new file mode 100644 index 0000000000..0b703aa055 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scale.rb @@ -0,0 +1,86 @@ +# +# tk/scale.rb : treat scale widget +# +require 'tk' + +class TkScale<TkWindow + TkCommandNames = ['scale'.freeze].freeze + WidgetClassName = 'Scale'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + if keys.key?('command') && ! keys['command'].kind_of?(String) + cmd = keys.delete('command') + keys['command'] = proc{|val| cmd.call(val.to_f)} + end + #tk_call_without_enc('scale', @path, *hash_kv(keys, true)) + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + #tk_call_without_enc('scale', @path) + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __strval_optkeys + super() << 'label' + end + private :__strval_optkeys + + def _wrap_command_arg(cmd) + proc{|val| + if val.kind_of?(String) + cmd.call(number(val)) + else + cmd.call(val) + end + } + end + private :_wrap_command_arg + + def configure_cmd(slot, value) + configure(slot=>value) + end + + def configure(slot, value=None) + if (slot == 'command' || slot == :command) + configure('command'=>value) + elsif slot.kind_of?(Hash) && + (slot.key?('command') || slot.key?(:command)) + slot = _symbolkey2str(slot) + slot['command'] = _wrap_command_arg(slot.delete('command')) + end + super(slot, value) + end + + def command(cmd=Proc.new) + configure('command'=>cmd) + end + + def get(x=None, y=None) + number(tk_send_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/ruby_1_8_6/ext/tk/lib/tk/scrollable.rb b/ruby_1_8_6/ext/tk/lib/tk/scrollable.rb new file mode 100644 index 0000000000..96959b7a4b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scrollable.rb @@ -0,0 +1,82 @@ +# +# tk/scrollable.rb : module for scrollable widget +# +require 'tk' + +module Tk + module XScrollable + def xscrollcommand(cmd=Proc.new) + configure_cmd 'xscrollcommand', cmd + # Tk.update # avoid scrollbar trouble + self + 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 xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + end + + def xscrollbar(bar=nil) + if bar + @xscrollbar = bar + @xscrollbar.orient 'horizontal' + self.xscrollcommand {|*arg| @xscrollbar.set(*arg)} + @xscrollbar.command {|*arg| self.xview(*arg)} + Tk.update # avoid scrollbar trouble + end + @xscrollbar + end + end + + module YScrollable + def yscrollcommand(cmd=Proc.new) + configure_cmd 'yscrollcommand', cmd + # Tk.update # avoid scrollbar trouble + self + 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 yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end + + def yscrollbar(bar=nil) + if bar + @yscrollbar = bar + @yscrollbar.orient 'vertical' + self.yscrollcommand {|*arg| @yscrollbar.set(*arg)} + @yscrollbar.command {|*arg| self.yview(*arg)} + Tk.update # avoid scrollbar trouble + end + @yscrollbar + end + end + + X_Scrollable = XScrollable + Y_Scrollable = YScrollable + + module Scrollable + include XScrollable + include YScrollable + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scrollbar.rb b/ruby_1_8_6/ext/tk/lib/tk/scrollbar.rb new file mode 100644 index 0000000000..70aadfdd4c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scrollbar.rb @@ -0,0 +1,124 @@ +# +# tk/scrollbar.rb : treat scrollbar widget +# +require 'tk' + +class TkScrollbar<TkWindow + TkCommandNames = ['scrollbar'.freeze].freeze + WidgetClassName = 'Scrollbar'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + @assigned = [] + @scroll_proc = proc{|*args| + if self.orient == 'horizontal' + @assigned.each{|w| w.xview(*args)} + else # 'vertical' + @assigned.each{|w| w.yview(*args)} + end + } + + if keys and keys != None + #tk_call_without_enc('scrollbar', @path, *hash_kv(keys, true)) + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + #tk_call_without_enc('scrollbar', @path) + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def propagate_set(src_win, first, last) + self.set(first, last) + if self.orient == 'horizontal' + @assigned.each{|w| w.xview('moveto', first) if w != src_win} + else # 'vertical' + @assigned.each{|w| w.yview('moveto', first) if w != src_win} + end + end + + def assign(*wins) + begin + self.command(@scroll_proc) if self.cget('command').cmd != @scroll_proc + rescue Exception + self.command(@scroll_proc) + end + orient = self.orient + wins.each{|w| + @assigned << w unless @assigned.index(w) + if orient == 'horizontal' + w.xscrollcommand proc{|first, last| self.propagate_set(w, first, last)} + else # 'vertical' + w.yscrollcommand proc{|first, last| self.propagate_set(w, first, last)} + end + } + Tk.update # avoid scrollbar trouble + self + end + + def assigned_list + begin + return @assigned.dup if self.cget('command').cmd == @scroll_proc + rescue Exception + end + fail RuntimeError, "not depend on the assigned_list" + end + + def configure(*args) + ret = super(*args) + # Tk.update # avoid scrollbar trouble + ret + end + + #def delta(deltax=None, deltay=None) + def delta(deltax, deltay) + number(tk_send_without_enc('delta', deltax, deltay)) + end + + #def fraction(x=None, y=None) + def fraction(x, y) + number(tk_send_without_enc('fraction', x, y)) + end + + def identify(x, y) + tk_send_without_enc('identify', x, y) + end + + def get + #ary1 = tk_send('get').split + #ary2 = [] + #for i in ary1 + # ary2.push number(i) + #end + #ary2 + list(tk_send_without_enc('get')) + end + + def set(first, last) + tk_send_without_enc('set', first, last) + self + end + + def activate(element=None) + tk_send_without_enc('activate', element) + end +end + +class TkXScrollbar<TkScrollbar + def create_self(keys) + keys = {} unless keys + keys['orient'] = 'horizontal' + super(keys) + end + private :create_self +end + +class TkYScrollbar<TkScrollbar + def create_self(keys) + keys = {} unless keys + keys['orient'] = 'vertical' + super(keys) + end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/scrollbox.rb b/ruby_1_8_6/ext/tk/lib/tk/scrollbox.rb new file mode 100644 index 0000000000..fd04057fb6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/scrollbox.rb @@ -0,0 +1,36 @@ +# +# tk/scrollbox.rb - Tk Listbox with Scrollbar +# as an example of Composite Widget +# $Date$ +# by Yukihiro Matsumoto <matz@netlab.co.jp> +# +require 'tk' +require 'tk/listbox' + +class TkScrollbox<TkListbox + include TkComposite + def initialize_composite(keys=nil) + list = TkListbox.new(@frame) + scroll = TkScrollbar.new(@frame) + @path = list.path + +=begin + list.configure 'yscroll', scroll.path+" set" + list.pack 'side'=>'left','fill'=>'both','expand'=>'yes' + scroll.configure 'command', list.path+" yview" + scroll.pack 'side'=>'right','fill'=>'y' +=end + list.yscrollbar(scroll) + list.pack('side'=>'left','fill'=>'both','expand'=>'yes') + 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/ruby_1_8_6/ext/tk/lib/tk/selection.rb b/ruby_1_8_6/ext/tk/lib/tk/selection.rb new file mode 100644 index 0000000000..5caa6ef8ef --- /dev/null +++ b/ruby_1_8_6/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/ruby_1_8_6/ext/tk/lib/tk/spinbox.rb b/ruby_1_8_6/ext/tk/lib/tk/spinbox.rb new file mode 100644 index 0000000000..9a10977d12 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/spinbox.rb @@ -0,0 +1,99 @@ +# +# tk/spinbox.rb - Tk spinbox classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +# +require 'tk' +require 'tk/entry' + +class TkSpinbox<TkEntry + TkCommandNames = ['spinbox'.freeze].freeze + WidgetClassName = 'Spinbox'.freeze + WidgetClassNames[WidgetClassName] = self + + class SpinCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?d, ?s, :direction ], + [ ?s, ?e, :current ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + + [ ?e, proc{|val| + #enc = Tk.encoding + enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system) + if enc + Tk.fromUTF8(TkComm::string(val), enc) + else + TkComm::string(val) + end + } + ], + + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + (val)? '1': '0' + end + end + + def self._config_keys + ['command'] + end + end + + def __validation_class_list + super() << SpinCommand + end + + Tk::ValidateConfigure.__def_validcmd(binding, SpinCommand) + + #def create_self(keys) + # tk_call_without_enc('spinbox', @path) + # if keys and keys != None + # configure(keys) + # end + #end + #private :create_self + + def __boolval_optkeys + super() << 'wrap' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'buttonbackground' << 'format' + end + private :__strval_optkeys + + def __listval_optkeys + super() << 'values' + end + private :__listval_optkeys + + def identify(x, y) + tk_send_without_enc('identify', x, y) + end + + def spinup + tk_send_without_enc('invoke', 'spinup') + self + end + + def spindown + tk_send_without_enc('invoke', 'spindown') + self + end + + def set(str) + _fromUTF8(tk_send_without_enc('set', _get_eval_enc_str(str))) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/tagfont.rb b/ruby_1_8_6/ext/tk/lib/tk/tagfont.rb new file mode 100644 index 0000000000..a1807395d2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/tagfont.rb @@ -0,0 +1,43 @@ +# +# tk/tagfont.rb : control font of tags +# +require 'tk' + +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(win, wintag=nil) + @parent.tagfont_copy(@id, win, wintag) + self + end + + def latinfont_copy(win, wintag=nil) + @parent.latintagfont_copy(@id, win, wintag) + self + end + alias asciifont_copy latinfont_copy + + def kanjifont_copy(win, wintag=nil) + @parent.kanjitagfont_copy(@id, win, wintag) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/text.rb b/ruby_1_8_6/ext/tk/lib/tk/text.rb new file mode 100644 index 0000000000..49d4b5625b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/text.rb @@ -0,0 +1,1550 @@ +# +# tk/text.rb - Tk text classes +# $Date$ +# by Yukihiro Matsumoto <matz@caelum.co.jp> +require 'tk' +require 'tk/itemfont' +require 'tk/itemconfig' +require 'tk/scrollable' +require 'tk/txtwin_abst' + +module TkTextTagConfig + include TkTreatItemFont + include TkItemConfigMethod + + def __item_cget_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'cget', id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'configure', id[1]] + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + id = tagid(id[1]) + end + [self.path, id].join(';') + end + private :__item_pathname + + def tag_cget(tagOrId, option) + itemcget(['tag', tagOrId], option) + end + def tag_configure(tagOrId, slot, value=None) + itemconfigure(['tag', tagOrId], slot, value) + end + def tag_configinfo(tagOrId, slot=nil) + itemconfigure(['tag', tagOrId], slot) + end + def current_tag_configinfo(tagOrId, slot=nil) + itemconfigure(['tag', tagOrId], slot) + end + + def window_cget(tagOrId, option) + itemcget(['window', tagOrId], option) + end + def window_configure(tagOrId, slot, value=None) + itemconfigure(['window', tagOrId], slot, value) + end + def window_configinfo(tagOrId, slot=nil) + itemconfigure(['window', tagOrId], slot) + end + def current_window_configinfo(tagOrId, slot=nil) + itemconfigure(['window', tagOrId], slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class TkText<TkTextWin + ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze + #include TkTreatTextTagFont + include TkTextTagConfig + include Scrollable + + ####################################### + + module IndexModMethods + def +(mod) + return chars(mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(String.new(id) << ' + ' << mod) + else + TkText::IndexString.new(String.new(id) << ' ' << mod) + end + end + + def -(mod) + return chars(-mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(String.new(id) << ' - ' << mod) + elsif mod =~ /^\s*[-]\s+(\d.*)$/ + TkText::IndexString.new(String.new(id) << ' - -' << $1) + else + TkText::IndexString.new(String.new(id) << ' ' << mod) + end + end + + def chars(mod) + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' chars') + end + end + alias char chars + + def display_chars(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display chars') + end + end + alias display_char display_chars + + def any_chars(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any chars') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any chars') + end + end + alias any_char any_chars + + def indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' indices') + end + end + + def display_indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display indices') + end + end + + def any_indices(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any indices') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any indices') + end + end + + def lines(mod) + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' lines') + end + end + alias line lines + + def display_lines(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display_lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display lines') + end + end + alias display_line display_lines + + def any_lines(mod) + # Tk8.5 feature + fail ArgumentError, 'expect Integer' unless mod.kind_of?(Integer) + if mod < 0 + TkText::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any_lines') + else + TkText::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any lines') + end + end + alias any_line any_lines + + def linestart + TkText::IndexString.new(String.new(id) << ' linestart') + end + def lineend + TkText::IndexString.new(String.new(id) << ' lineend') + end + + def display_linestart + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display linestart') + end + def display_lineend + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display lineend') + end + + def wordstart + TkText::IndexString.new(String.new(id) << ' wordstart') + end + def wordend + TkText::IndexString.new(String.new(id) << ' wordend') + end + + def display_wordstart + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display wordstart') + end + def display_wordend + # Tk8.5 feature + TkText::IndexString.new(String.new(id) << ' display wordend') + end + end + + class IndexString < String + include IndexModMethods + + def self.at(x,y) + self.new("@#{x},#{y}") + end + + def self.new(str) + if str.kind_of?(String) + super(str) + elsif str.kind_of?(Symbol) + super(str.to_s) + else + str + end + end + + def id + self + end + end + + ####################################### + + TkCommandNames = ['text'.freeze].freeze + WidgetClassName = 'Text'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.new(*args, &block) + obj = super(*args){} + obj.init_instance_variable + obj.instance_eval(&block) if defined? yield + obj + end + + def init_instance_variable + @cmdtbl = [] + @tags = {} + end + + def __destroy_hook__ + TkTextTag::TTagID_TBL.delete(@path) + TkTextMark::TMarkID_TBL.delete(@path) + end + + def create_self(keys) + #if keys and keys != None + # #tk_call_without_enc('text', @path, *hash_kv(keys, true)) + # tk_call_without_enc(self.class::TkCommandNames[0], @path, + # *hash_kv(keys, true)) + #else + # #tk_call_without_enc('text', @path) + # tk_call_without_enc(self.class::TkCommandNames[0], @path) + #end + super(keys) + init_instance_variable + end + private :create_self + + def __strval_optkeys + super() << 'inactiveseletcionbackground' + end + private :__strval_optkeys + + def self.at(x, y) + TkText::IndexString.at(x, y) + end + + def at(x, y) + TkText::IndexString.at(x, y) + end + + def index(idx) + TkText::IndexString.new(tk_send_without_enc('index', + _get_eval_enc_str(idx))) + end + + def get_displaychars(*index) + # Tk8.5 feature + get('-displaychars', *index) + end + + def value + _fromUTF8(tk_send_without_enc('get', "1.0", "end - 1 char")) + end + + def value= (val) + tk_send_without_enc('delete', "1.0", 'end') + tk_send_without_enc('insert', "1.0", _get_eval_enc_str(val)) + val + end + + def clear + tk_send_without_enc('delete', "1.0", 'end') + self + end + alias erase clear + + def _addcmd(cmd) + @cmdtbl.push cmd + end + + def _addtag(name, obj) + @tags[name] = obj + end + + def tagid(tag) + if tag.kind_of?(TkTextTag) \ + || tag.kind_of?(TkTextMark) \ + || tag.kind_of?(TkTextImage) \ + || tag.kind_of?(TkTextWindow) + tag.id + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + def tagid2obj(tagid) + if @tags[tagid] + @tags[tagid] + else + tagid + end + end + + def tag_names(index=None) + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_names + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('mark', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('mark', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_gravity(mark, direction=nil) + if direction + tk_send_without_enc('mark', 'gravity', + _get_eval_enc_str(mark), direction) + self + else + tk_send_without_enc('mark', 'gravity', _get_eval_enc_str(mark)) + end + end + + def mark_set(mark, index) + tk_send_without_enc('mark', 'set', _get_eval_enc_str(mark), + _get_eval_enc_str(index)) + self + end + alias set_mark mark_set + + def mark_unset(*marks) + tk_send_without_enc('mark', 'unset', + *(marks.collect{|mark| _get_eval_enc_str(mark)})) + self + end + alias unset_mark mark_unset + + def mark_next(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'next', + _get_eval_enc_str(index)))) + end + alias next_mark mark_next + + def mark_previous(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'previous', + _get_eval_enc_str(index)))) + end + alias previous_mark mark_previous + + def image_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), + "-#{slot}"))) + end + end + + def image_configure(index, slot, value=None) + if slot.kind_of?(Hash) + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true))) + else + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + "-#{slot}", + _get_eval_enc_str(value))) + end + self + end + + def image_configinfo(index, 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_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + conf[0] = conf[0][1..-1] + conf + else + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + 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_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + key = conf.shift[1..-1] + { key => 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) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + 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| + tk_split_simplelist(tk_send_without_enc('image', 'names'), false, true).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 are Tk8.5 feature + cnt = 0 + args = opts.collect{|opt| + str = opt.to_s + cnt += 1 if str != 'update' + '-' + str + } + args << _get_eval_enc_str(idx1) << _get_eval_enc_str(idx2) + if cnt <= 1 + number(tk_send_without_enc('count', *opts)) + else + list(tk_send_without_enc('count', *opts)) + end + end + + def count_info(idx1, idx2, update=true) + # Tk8.5 feature + opts = [ + :chars, :displaychars, :displayindices, :displaylines, + :indices, :lines, :xpixels, :ypixels + ] + if update + lst = count(idx1, idx2, :update, *opts) + else + lst = count(idx1, idx2, *opts) + end + info = {} + opts.each_with_index{|key, idx| info[key] = lst[idx]} + info + end + + def peer_names() + # Tk8.5 feature + list(tk_send_without_enc('peer', 'names')) + 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) + TkTextTag::TTagID_TBL[@path].delete(tag.id) + else + TkTextTag::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) + # _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + # self + #end + def tag_bind(tag, seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + + #def tag_bind_append(tag, seq, cmd=Proc.new, *args) + # _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) + # self + #end + def tag_bind_append(tag, seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _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 + +=begin + 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 +=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), + *(indices.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))) + l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges', + _get_eval_enc_str(tag)), + false, true) + r = [] + while key=l.shift + r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] + end + r + end + + def tag_nextrange(tag, first, last=None) + simplelist(tk_send_without_enc('tag', 'nextrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def tag_prevrange(tag, first, last=None) + simplelist(tk_send_without_enc('tag', 'prevrange', + _get_eval_enc_str(tag), + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + +=begin + 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 +=end + + def window_names + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('window', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('window', 'names'), false, true).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 ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + nocase = false + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| + s_opt = opt.to_s + nocase = true if s_opt == 'nocase' + '-' + s_opt + } + else + opts = [] + end + + if args[0].kind_of?(Regexp) + regexp = args.shift + if !nocase && (regexp.options & Regexp::IGNORECASE) != 0 + opts << '-nocase' + end + args.unshift(regexp.source) + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + TkText::IndexString.new(ret) + end + end + + def tksearch_with_count(*args) + # call 'search' subcommand of text widget + # args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + nocase = false + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| + s_opt = opt.to_s + nocase = true if s_opt == 'nocase' + '-' + s_opt + } + else + opts = [] + end + + opts << '-count' << args.shift + + if args[0].kind_of?(Regexp) + regexp = args.shift + if !nocase && (regexp.options & Regexp::IGNORECASE) != 0 + opts << '-nocase' + end + args.unshift(regexp.source) + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + TkText::IndexString.new(ret) + 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) + if type_info.kind_of?(Symbol) + type_info = [ type_info.to_s ] + elsif type_info.kind_of?(String) + type_info = [ type_info ] + end + 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) + when 'image' + result.push tk_tcl2ruby(val) + end + i = idx + 1 + end + + # retrieve index + idx = str.index(/ /, i) + if idx + result.push(TkText::IndexString.new(str[i..(idx-1)])) + i = idx + 1 + else + result.push(TkText::IndexString.new(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 TkText::Peer < TkText + # Tk8.5 feature + def initialize(text, parent=nil, keys={}) + unless text.kind_of?(TkText) + fail ArgumentError, "TkText is expected for 1st argument" + end + @src_text = text + super(parent, keys) + end + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(@src_text.path, 'peer', 'create', @path) + else + tk_call_without_enc(@src_text.path, 'peer', 'create', @path) + end + end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/textimage.rb b/ruby_1_8_6/ext/tk/lib/tk/textimage.rb new file mode 100644 index 0000000000..a29b23c7dd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/textimage.rb @@ -0,0 +1,82 @@ +# +# tk/textimage.rb - treat Tk text image object +# +require 'tk' +require 'tk/text' + +class TkTextImage<TkObject + include TkText::IndexModMethods + + def initialize(parent, index, keys) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @t = parent + if index == 'end' || index == :end + @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars')) + elsif index.kind_of? TkTextMark + if tk_call_without_enc(@t.path,'index',index.path) == tk_call_without_enc(@t.path,'index','end') + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + 'end - 1 chars')) + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + index.path)) + end + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + _get_eval_enc_str(index))) + end + @path.gravity = 'left' + @index = @path.path + @id = tk_call_without_enc(@t.path, 'image', 'create', @index, + *hash_kv(keys, true)).freeze + @path.gravity = 'right' + end + + def id + TkText::IndexString.new(@id) + end + def mark + @path + end + + def [](slot) + cget(slot) + end + def []=(slot, value) + configure(slot, value) + value + end + + def cget(slot) + @t.image_cget(@index, slot) + end + + def configure(slot, value=None) + @t.image_configure(@index, slot, value) + self + end +# def configure(slot, value) +# tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value +# end + + def configinfo(slot = nil) + @t.image_configinfo(@index, slot) + end + + def current_configinfo(slot = nil) + @t.current_image_configinfo(@index, slot) + end + + def image + img = tk_call_without_enc(@t.path, 'image', 'cget', @index, '-image') + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img + end + + def image=(value) + tk_call_without_enc(@t.path, 'image', 'configure', @index, '-image', + _get_eval_enc_str(value)) + #self + value + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/textmark.rb b/ruby_1_8_6/ext/tk/lib/tk/textmark.rb new file mode 100644 index 0000000000..650d95af70 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/textmark.rb @@ -0,0 +1,166 @@ +# +# tk/textmark.rb - methods for treating text marks +# +require 'tk' +require 'tk/text' + +class TkTextMark<TkObject + include TkText::IndexModMethods + + TMarkID_TBL = TkCore::INTERP.create_table + Tk_TextMark_ID = ['mark'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TMarkID_TBL.clear } + + def TkTextMark.id2obj(text, id) + tpath = text.path + return id unless TMarkID_TBL[tpath] + TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id + end + + def initialize(parent, index) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + # @path = @id = Tk_TextMark_ID.join('') + @path = @id = Tk_TextMark_ID.join(TkCore::INTERP._ip_id_).freeze + TMarkID_TBL[@id] = self + TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath] + TMarkID_TBL[@tpath][@id] = self + Tk_TextMark_ID[1].succ! + tk_call_without_enc(@t.path, 'mark', 'set', @id, + _get_eval_enc_str(index)) + @t._addtag id, self + end + + def id + TkText::IndexString.new(@id) + end + + def exist? + #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'names'))).find{|id| id == @id } ) + if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'mark', 'names'), false, true).find{|id| id == @id } ) + true + else + false + end + end + +=begin + # move to TkText::IndexModMethods module + def +(mod) + return chars(mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(@id + ' + ' + mod) + else + TkText::IndexString.new(@id + ' ' + mod) + end + end + + def -(mod) + return chars(-mod) if mod.kind_of?(Numeric) + + mod = mod.to_s + if mod =~ /^\s*[+-]?\d/ + TkText::IndexString.new(@id + ' - ' + mod) + elsif mod =~ /^\s*[-]\s+(\d.*)$/ + TkText::IndexString.new(@id + ' - -' + $1) + else + TkText::IndexString.new(@id + ' ' + mod) + end + end +=end + + def pos + @t.index(@id) + end + + def pos=(where) + set(where) + end + + def set(where) + tk_call_without_enc(@t.path, 'mark', 'set', @id, + _get_eval_enc_str(where)) + self + end + + def unset + tk_call_without_enc(@t.path, 'mark', 'unset', @id) + self + end + alias destroy unset + + def gravity + tk_call_without_enc(@t.path, 'mark', 'gravity', @id) + end + + def gravity=(direction) + tk_call_without_enc(@t.path, 'mark', 'gravity', @id, direction) + #self + direction + end + + def next(index = nil) + if index + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', _get_eval_enc_str(index)))) + else + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', @id))) + end + end + + def previous(index = nil) + if index + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', _get_eval_enc_str(index)))) + else + @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', @id))) + end + end +end + +class TkTextNamedMark<TkTextMark + def self.new(parent, name, *args) + if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name] + return TMarkID_TBL[parent.path][name] + else + super(parent, name, *args) + end + end + + def initialize(parent, name, index=nil) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + @path = @id = name + TMarkID_TBL[@id] = self + TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath] + TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id] + tk_call_without_enc(@t.path, 'mark', 'set', @id, + _get_eval_enc_str(index)) if index + @t._addtag id, self + end +end + +class TkTextMarkInsert<TkTextNamedMark + def self.new(parent,*args) + super(parent, 'insert', *args) + end +end + +class TkTextMarkCurrent<TkTextNamedMark + def self.new(parent,*args) + super(parent, 'current', *args) + end +end + +class TkTextMarkAnchor<TkTextNamedMark + def self.new(parent,*args) + super(parent, 'anchor', *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/texttag.rb b/ruby_1_8_6/ext/tk/lib/tk/texttag.rb new file mode 100644 index 0000000000..cc2c56210f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/texttag.rb @@ -0,0 +1,279 @@ +# +# tk/texttag.rb - methods for treating text tags +# +require 'tk' +require 'tk/text' +require 'tk/tagfont' + +class TkTextTag<TkObject + include TkTreatTagFont + include TkText::IndexModMethods + + TTagID_TBL = TkCore::INTERP.create_table + Tk_TextTag_ID = ['tag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TTagID_TBL.clear } + + def TkTextTag.id2obj(text, id) + tpath = text.path + return id unless TTagID_TBL[tpath] + TTagID_TBL[tpath][id]? TTagID_TBL[tpath][id]: id + end + + def initialize(parent, *args) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + # @path = @id = Tk_TextTag_ID.join('') + @path = @id = Tk_TextTag_ID.join(TkCore::INTERP._ip_id_).freeze + # TTagID_TBL[@id] = self + TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath] + TTagID_TBL[@tpath][@id] = self + Tk_TextTag_ID[1].succ! + #tk_call @t.path, "tag", "configure", @id, *hash_kv(keys) + if args != [] + keys = args.pop + if keys.kind_of?(Hash) + add(*args) if args != [] + configure(keys) + else + args.push keys + add(*args) + end + end + @t._addtag id, self + end + + def id + TkText::IndexString.new(@id) + end + + def exist? + #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'names'))).find{|id| id == @id } ) + if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'names'), false, true).find{|id| id == @id } ) + true + else + false + end + end + + def first + TkText::IndexString.new(@id + '.first') + end + + def last + TkText::IndexString.new(@id + '.last') + end + + def add(*indices) + tk_call_without_enc(@t.path, 'tag', 'add', @id, + *(indices.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def remove(*indices) + tk_call_without_enc(@t.path, 'tag', 'remove', @id, + *(indices.collect{|idx| _get_eval_enc_str(idx)})) + self + end + + def ranges + l = tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'ranges', @id)) + r = [] + while key=l.shift + r.push [TkText::IndexString.new(key), TkText::IndexString.new(l.shift)] + end + r + end + + def nextrange(first, last=None) + simplelist(tk_call_without_enc(@t.path, 'tag', 'nextrange', @id, + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def prevrange(first, last=None) + simplelist(tk_call_without_enc(@t.path, 'tag', 'prevrange', @id, + _get_eval_enc_str(first), + _get_eval_enc_str(last))).collect{|idx| + TkText::IndexString.new(idx) + } + end + + def [](key) + cget key + end + + def []=(key,val) + configure key, val + val + end + + def cget(key) + @t.tag_cget @id, key + end +=begin + def cget(key) + case key.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', @id, "-#{key}")) + when 'font', 'kanjifont' + #fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}")) + fnt = tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', + @id, '-font'))) + unless fnt.kind_of?(TkFont) + fnt = tagfontobj(@id, 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(@t.path, 'tag', 'cget', + @id, "-#{key}"))) + end + end +=end + + def configure(key, val=None) + @t.tag_configure @id, key, val + end +# def configure(key, val=None) +# if key.kind_of?(Hash) +# tk_call @t.path, 'tag', 'configure', @id, *hash_kv(key) +# else +# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", val +# end +# end +# def configure(key, value) +# if value == FALSE +# value = "0" +# elsif value.kind_of?(Proc) +# value = install_cmd(value) +# end +# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", value +# end + + def configinfo(key=nil) + @t.tag_configinfo @id, key + end + + def current_configinfo(key=nil) + @t.current_tag_configinfo @id, key + end + + #def bind(seq, cmd=Proc.new, *args) + # _bind([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + # self + #end + def bind(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + self + end + + #def bind_append(seq, cmd=Proc.new, *args) + # _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + # self + #end + def bind_append(seq, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, *args) + self + end + + def bind_remove(seq) + _bind_remove([@t.path, 'tag', 'bind', @id], seq) + self + end + + def bindinfo(context=nil) + _bindinfo([@t.path, 'tag', 'bind', @id], context) + end + + def raise(above=None) + tk_call_without_enc(@t.path, 'tag', 'raise', @id, + _get_eval_enc_str(above)) + self + end + + def lower(below=None) + tk_call_without_enc(@t.path, 'tag', 'lower', @id, + _get_eval_enc_str(below)) + self + end + + def destroy + tk_call_without_enc(@t.path, 'tag', 'delete', @id) + TTagID_TBL[@tpath].delete(@id) if TTagID_TBL[@tpath] + self + end +end + +class TkTextNamedTag<TkTextTag + def self.new(parent, name, *args) + if TTagID_TBL[parent.path] && TTagID_TBL[parent.path][name] + tagobj = TTagID_TBL[parent.path][name] + if args != [] + keys = args.pop + if keys.kind_of?(Hash) + tagobj.add(*args) if args != [] + tagobj.configure(keys) + else + args.push keys + tagobj.add(*args) + end + end + return tagobj + else + super(parent, name, *args) + end + end + + def initialize(parent, name, *args) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @parent = @t = parent + @tpath = parent.path + @path = @id = name + TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath] + TTagID_TBL[@tpath][@id] = self unless TTagID_TBL[@tpath][@id] + #if mode + # tk_call @t.path, "addtag", @id, *args + #end + if args != [] + keys = args.pop + if keys.kind_of?(Hash) + add(*args) if args != [] + configure(keys) + else + args.push keys + add(*args) + end + end + @t._addtag id, self + end +end + +class TkTextTagSel<TkTextNamedTag + def self.new(parent, *args) + super(parent, 'sel', *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/textwindow.rb b/ruby_1_8_6/ext/tk/lib/tk/textwindow.rb new file mode 100644 index 0000000000..605c40addd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/textwindow.rb @@ -0,0 +1,149 @@ +# +# tk/textwindow.rb - treat Tk text window object +# +require 'tk' +require 'tk/text' + +class TkTextWindow<TkObject + include TkText::IndexModMethods + + def initialize(parent, index, keys = {}) + #unless parent.kind_of?(TkText) + # fail ArgumentError, "expect TkText for 1st argument" + #end + @t = parent + if index == 'end' || index == :end + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + 'end - 1 chars')) + elsif index.kind_of?(TkTextMark) + if tk_call_without_enc(@t.path,'index',index.path) == tk_call_without_enc(@t.path,'index','end') + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + 'end - 1 chars')) + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', + index.path)) + end + else + @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', _get_eval_enc_str(index))) + end + @path.gravity = 'left' + @index = @path.path + keys = _symbolkey2str(keys) + @id = keys['window'] + # keys['window'] = @id.epath if @id.kind_of?(TkWindow) + keys['window'] = _epath(@id) if @id + if keys['create'] + @p_create = keys['create'] + # if @p_create.kind_of?(Proc) + if TkComm._callback_entry?(@p_create) +=begin + keys['create'] = install_cmd(proc{ + @id = @p_create.call + if @id.kind_of?(TkWindow) + @id.epath + else + @id + end + }) +=end + keys['create'] = install_cmd(proc{@id = @p_create.call; _epath(@id)}) + end + end + tk_call_without_enc(@t.path, 'window', 'create', @index, + *hash_kv(keys, true)) + @path.gravity = 'right' + end + + def id + TkText::IndexString.new(_epath(@id)) + end + def mark + @path + end + + def [](slot) + cget(slot) + end + def []=(slot, value) + configure(slot, value) + value + end + + def cget(slot) + @t.window_cget(@index, slot) + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + if slot['window'] + @id = slot['window'] + # slot['window'] = @id.epath if @id.kind_of?(TkWindow) + slot['window'] = _epath(@id) if @id + end + if slot['create'] + self.create=slot.delete('create') + end + if slot.size > 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) + if TkComm._callback_entry?(@p_create) + 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/ruby_1_8_6/ext/tk/lib/tk/timer.rb b/ruby_1_8_6/ext/tk/lib/tk/timer.rb new file mode 100644 index 0000000000..47f2b79350 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/timer.rb @@ -0,0 +1,634 @@ +# +# 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.start(*args, &b) + self.new(*args, &b).start + end + + def self.callback(obj_id) + 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 + @after_id = nil + begin + @return_value = @current_proc.call(self) + rescue SystemExit + exit(0) + rescue Interrupt + exit!(1) + rescue Exception => e + if @cancel_on_exception && + @cancel_on_exception.find{|exc| e.kind_of?(exc)} + cancel + @return_value = e + @in_callback = false + 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) + if TkCore::INTERP.deleted? + self.cancel + return self + end + @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) + if TkComm._callback_entry?(@sleep_time) + 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, &b) + # @id = Tk_CBID.join('') + @id = Tk_CBID.join(TkCore::INTERP._ip_id_) + 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). + + if b + case args.size + when 0 + add_procs(b) + when 1 + args << -1 << b + else + args << b + end + end + + 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_interval(interval) + #if interval != 'idle' && interval != :idle \ + # && !interval.kind_of?(Integer) && !interval.kind_of?(Proc) + if interval != 'idle' && interval != :idle \ + && !interval.kind_of?(Integer) && !TkComm._callback_entry?(interval) + fail ArgumentError, "expect Integer or Proc" + end + @sleep_time = interval + end + + def set_procs(interval, loop_exec, *procs) + #if interval != 'idle' && interval != :idle \ + # && !interval.kind_of?(Integer) && !interval.kind_of?(Proc) + if interval != 'idle' && interval != :idle \ + && !interval.kind_of?(Integer) && !TkComm._callback_entry?(interval) + fail ArgumentError, "expect Integer or Proc for 1st argument" + end + @sleep_time = interval + + @loop_proc = [] + procs.each{|e| + # if e.kind_of?(Proc) + if TkComm._callback_entry?(e) + @loop_proc.push([e]) + else + @loop_proc.push(e) + end + } + @proc_max = @loop_proc.size + @current_pos = 0 + + if loop_exec.kind_of?(Integer) && loop_exec < 0 + @loop_exec = -1 + elsif loop_exec == true + @loop_exec = -1 + elsif loop_exec == nil || loop_exec == false || loop_exec == 0 + @loop_exec = 0 + else + if not loop_exec.kind_of?(Integer) + fail ArgumentError, "expect Integer for 2nd argument" + end + @loop_exec = loop_exec + end + @do_loop = @loop_exec + + self + end + + def add_procs(*procs) + procs.each{|e| + # if e.kind_of?(Proc) + if TkComm._callback_entry?(e) + @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) + if TkComm._callback_entry?(e) + @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=nil, init_proc=nil, *init_args, &b) + # set parameters for 'restart' + sleep = @init_sleep unless sleep + + if sleep != 'idle' && sleep != :idle && !sleep.kind_of?(Integer) + fail ArgumentError, "expect Integer or 'idle' for 1st argument" + end + + @init_sleep = sleep + @init_proc = init_proc + @init_args = init_args + + @init_proc = b if !@init_proc && b + @init_proc = proc{|*args| } if @init_sleep > 0 && !@init_proc + + self + end + + def start(*init_args, &b) + return nil if @running + + Tk_CBTBL[@id] = self + @do_loop = @loop_exec + @current_pos = 0 + @return_value = nil + @after_id = nil + + @init_sleep = 0 + @init_proc = nil + @init_args = nil + + argc = init_args.size + if argc > 0 + sleep = init_args.shift + if sleep != 'idle' && sleep != :idle && !sleep.kind_of?(Integer) + fail ArgumentError, "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 > 2 + + @init_proc = b if !@init_proc && b + @init_proc = proc{|*args| } if @init_sleep > 0 && !@init_proc + + @current_sleep = @init_sleep + @running = true + if @init_proc + # if not @init_proc.kind_of?(Proc) + if !TkComm._callback_entry?(@init_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 + @current_script = [] + + @set_next = false if @in_callback + + self + end + + def restart(*restart_args, &b) + cancel if @running + if restart_args == [] && !b + start(@init_sleep, @init_proc, *@init_args) + else + start(*restart_args, &b) + 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 + return restart() if @current_script.empty? + sleep, cmd = @current_script + fail RuntimeError, "no procedure to continue" unless cmd + if wait + unless wait.kind_of?(Integer) + fail ArgumentError, "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 + + +class TkRTTimer < TkTimer + DEFAULT_OFFSET_LIST_SIZE = 5 + + def initialize(*args, &b) + super(*args, &b) + + @offset_list = Array.new(DEFAULT_OFFSET_LIST_SIZE){ [0, 0] } + @offset_s = 0 + @offset_u = 0 + @est_time = nil + end + + def start(*args, &b) + return nil if @running + @est_time = nil + @cb_start_time = Time.now + super(*args, &b) + end + + def cancel + super() + @est_time = nil + @cb_start_time = Time.now + self + end + alias stop cancel + + def continue(wait=nil) + fail RuntimeError, "is already running" if @running + @cb_start_time = Time.now + super(wait) + end + + def set_interval(interval) + super(interval) + @est_time = nil + end + + def _offset_ave + size = 0 + d_sec = 0; d_usec = 0 + @offset_list.each_with_index{|offset, idx| + # weight = 1 + weight = idx + 1 + size += weight + d_sec += offset[0] * weight + d_usec += offset[1] * weight + } + offset_s, mod = d_sec.divmod(size) + offset_u = ((mod * 1000000 + d_usec) / size.to_f).round + [offset_s, offset_u] + end + private :_offset_ave + + 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 + + cmd, *cmd_args = @loop_proc[@current_pos] + @current_pos += 1 + @current_proc = cmd + + @offset_s, @offset_u = _offset_ave + + if TkComm._callback_entry?(@sleep_time) + sleep = @sleep_time.call(self) + else + sleep = @sleep_time + end + + if @est_time + @est_time = Time.at(@est_time.to_i, @est_time.usec + sleep*1000) + else + @est_time = Time.at(@cb_start_time.to_i, + @cb_start_time.usec + sleep*1000) + end + + now = Time.now + real_sleep = ((@est_time.to_i - now.to_i + @offset_s)*1000.0 + + (@est_time.usec - now.usec + @offset_u)/1000.0).round + if real_sleep <= 0 + real_sleep = 0 + @offset_s = now.to_i + @offset_u = now.usec + end + @current_sleep = real_sleep + + set_callback(real_sleep, cmd_args) + end + + def cb_call + if @est_time + @offset_list.shift + + @cb_start_time = Time.now + + if @current_sleep == 0 + @offset_list.push([ + @offset_s - @cb_start_time.to_i, + @offset_u - @cb_start_time.usec + ]) + else + @offset_list.push([ + @offset_s + (@est_time.to_i - @cb_start_time.to_i), + @offset_u + (@est_time.usec - @cb_start_time.usec) + ]) + end + end + + @cb_cmd.call + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/toplevel.rb b/ruby_1_8_6/ext/tk/lib/tk/toplevel.rb new file mode 100644 index 0000000000..5e199e1330 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/toplevel.rb @@ -0,0 +1,257 @@ +# +# tk/toplevel.rb : treat toplevel widget +# +require 'tk' +require 'tk/wm' +require 'tk/menuspec' + +class TkToplevel<TkWindow + include Wm + include TkMenuSpec + + TkCommandNames = ['toplevel'.freeze].freeze + WidgetClassName = 'Toplevel'.freeze + WidgetClassNames[WidgetClassName] = self + +################# old version +# def initialize(parent=nil, screen=nil, classname=nil, keys=nil) +# if screen.kind_of? Hash +# keys = screen.dup +# else +# @screen = screen +# end +# @classname = classname +# if keys.kind_of? Hash +# keys = keys.dup +# @classname = keys.delete('classname') if keys.key?('classname') +# @colormap = keys.delete('colormap') if keys.key?('colormap') +# @container = keys.delete('container') if keys.key?('container') +# @screen = keys.delete('screen') if keys.key?('screen') +# @use = keys.delete('use') if keys.key?('use') +# @visual = keys.delete('visual') if keys.key?('visual') +# end +# super(parent, keys) +# end +# +# def create_self +# s = [] +# s << "-class" << @classname if @classname +# s << "-colormap" << @colormap if @colormap +# s << "-container" << @container if @container +# s << "-screen" << @screen if @screen +# s << "-use" << @use if @use +# s << "-visual" << @visual if @visual +# tk_call 'toplevel', @path, *s +# end +################# + + def __boolval_optkeys + super() << 'container' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'screen' + end + private :__strval_optkeys + + def __val2ruby_optkeys # { key=>proc, ... } + super().update('menu'=>proc{|v| window(v)}) + end + private :__val2ruby_optkeys + + def __methodcall_optkeys # { key=>method, ... } + TOPLEVEL_METHODCALL_OPTKEYS + end + private :__methodcall_optkeys + + def _wm_command_option_chk(keys) + keys = {} unless keys + new_keys = {} + wm_cmds = {} + + conf_methods = _symbolkey2str(__methodcall_optkeys()) + + keys.each{|k,v| + if conf_methods.key?(k) + wm_cmds[conf_methods[k]] = v + elsif Wm.method_defined?(k) + case k + when 'screen','class','colormap','container','use','visual' + new_keys[k] = v + else + case self.method(k).arity + when -1,1 + wm_cmds[k] = v + else + new_keys[k] = v + end + end + else + new_keys[k] = v + end + } + [new_keys, wm_cmds] + end + private :_wm_command_option_chk + + def initialize(parent=nil, screen=nil, classname=nil, keys=nil) + my_class_name = nil + if self.class < WidgetClassNames[WidgetClassName] + my_class_name = self.class.name + my_class_name = nil if my_class_name == '' + end + if parent.kind_of? Hash + keys = _symbolkey2str(parent) + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + @classname = keys['class'] + @colormap = keys['colormap'] + @container = keys['container'] + @screen = keys['screen'] + @use = keys['use'] + @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 + keys, cmds = _wm_command_option_chk(keys) + super(keys) + cmds.each{|k,v| + if v.kind_of? Array + self.__send__(k,*v) + else + self.__send__(k,v) + end + } + return + end + + if screen.kind_of? Hash + keys = screen + else + @screen = screen + if classname.kind_of? Hash + keys = classname + else + @classname = classname + end + end + if keys.kind_of? Hash + keys = _symbolkey2str(keys) + if keys.key?('classname') + keys['class'] = keys.delete('classname') + end + @classname = keys['class'] unless @classname + @colormap = keys['colormap'] + @container = keys['container'] + @screen = keys['screen'] unless @screen + @use = keys['use'] + @visual = keys['visual'] + else + keys = {} + end + 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 + keys, cmds = _wm_command_option_chk(keys) + super(parent, keys) + cmds.each{|k,v| + if v.kind_of? Array + self.send(k,*v) + else + self.send(k,v) + end + } + end + + #def create_self(keys) + # if keys and keys != None + # tk_call_without_enc('toplevel', @path, *hash_kv(keys, true)) + # else + # tk_call_without_enc('toplevel', @path) + # end + #end + #private :create_self + + def specific_class + @classname + end + + def add_menu(menu_info, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_info. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_info can override it. + if tearoff.kind_of?(Hash) + opts = tearoff + tearoff = false + end + _create_menubutton(self, menu_info, tearoff, opts) + end + + def add_menubar(menu_spec, tearoff=false, opts=nil) + # See tk/menuspec.rb for menu_spec. + # opts is a hash of default configs for all of cascade menus. + # Configs of menu_spec can override it. + menu_spec.each{|info| add_menu(info, tearoff, opts)} + self.menu + 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, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind(*args, &b) + end + end + def self.bind_append(*args, &b) + if self == WidgetClassNames[WidgetClassName] || self.name == '' + super(*args, &b) + else + TkDatabaseClass.new(self.name).bind_append(*args, &b) + 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/ruby_1_8_6/ext/tk/lib/tk/txtwin_abst.rb b/ruby_1_8_6/ext/tk/lib/tk/txtwin_abst.rb new file mode 100644 index 0000000000..540f806d17 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/txtwin_abst.rb @@ -0,0 +1,39 @@ +# +# tk/txtwin_abst.rb : TkTextWin abstruct class +# +require 'tk' + +class TkTextWin<TkWindow + TkCommandNames = [].freeze + #def create_self + # fail RuntimeError, "TkTextWin is an abstract class" + #end + #private :create_self + + def bbox(index) + list(tk_send_without_enc('bbox', index)) + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def get(*index) + _fromUTF8(tk_send_without_enc('get', *index)) + end + def insert(index, *args) + tk_send('insert', index, *args) + 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 see(index) + tk_send_without_enc('see', index) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/validation.rb b/ruby_1_8_6/ext/tk/lib/tk/validation.rb new file mode 100644 index 0000000000..0c5b5c61b9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/validation.rb @@ -0,0 +1,376 @@ +# +# tk/validation.rb - validation support module for entry, spinbox, and so on +# +require 'tk' + +module Tk + module ValidateConfigure + def self.__def_validcmd(scope, klass, keys=nil) + keys = klass._config_keys unless keys + keys.each{|key| + eval("def #{key}(*args, &b) + __validcmd_call(#{klass.name}, '#{key}', *args, &b) + end", scope) + } + end + + def __validcmd_call(klass, key, *args, &b) + return cget(key) if args.empty? && !b + + cmd = (b)? proc(&b) : args.shift + + if cmd.kind_of?(klass) + configure(key, cmd) + elsif !args.empty? + configure(key, [cmd, args]) + else + configure(key, cmd) + end + end + + def __validation_class_list + # maybe need to override + [] + end + + def __get_validate_key2class + k2c = {} + __validation_class_list.each{|klass| + klass._config_keys.each{|key| + k2c[key.to_s] = klass + } + } + k2c + end + + def __conv_vcmd_on_hash_kv(keys) + key2class = __get_validate_key2class + + keys = _symbolkey2str(keys) + key2class.each{|key, klass| + if keys[key].kind_of?(Array) + cmd, *args = keys[key] + keys[key] = klass.new(cmd, args.join(' ')) + # elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method) + elsif TkComm._callback_entry?(keys[key]) + keys[key] = klass.new(keys[key]) + end + } + keys + end + + def create_self(keys) + super(__conv_vcmd_on_hash_kv(keys)) + end + private :create_self + + def configure(slot, value=TkComm::None) + if slot.kind_of?(Hash) + super(__conv_vcmd_on_hash_kv(slot)) + else + super(__conv_vcmd_on_hash_kv(slot=>value)) + end + self + end +=begin + def configure(slot, value=TkComm::None) + key2class = __get_validate_key2class + + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + key2class.each{|key, klass| + if slot[key].kind_of?(Array) + cmd, *args = slot[key] + slot[key] = klass.new(cmd, args.join(' ')) + elsif slot[key].kind_of?(Proc) || slot[key].kind_of?(Method) + slot[key] = klass.new(slot[key]) + end + } + super(slot) + + else + slot = slot.to_s + if (klass = key2class[slot]) + if value.kind_of?(Array) + cmd, *args = value + value = klass.new(cmd, args.join(' ')) + elsif value.kind_of?(Proc) || value.kind_of?(Method) + value = klass.new(value) + end + end + super(slot, value) + end + + self + end +=end + end + + module ItemValidateConfigure + def self.__def_validcmd(scope, klass, keys=nil) + keys = klass._config_keys unless keys + keys.each{|key| + eval("def item_#{key}(id, *args, &b) + __item_validcmd_call(#{klass.name}, '#{key}', id, *args, &b) + end", scope) + } + end + + def __item_validcmd_call(tagOrId, klass, key, *args, &b) + return itemcget(tagid(tagOrId), key) if args.empty? && !b + + cmd = (b)? proc(&b) : args.shift + + if cmd.kind_of?(klass) + itemconfigure(tagid(tagOrId), key, cmd) + elsif !args.empty? + itemconfigure(tagid(tagOrId), key, [cmd, args]) + else + itemconfigure(tagid(tagOrId), key, cmd) + end + end + + def __item_validation_class_list(id) + # maybe need to override + [] + end + + def __get_item_validate_key2class(id) + k2c = {} + __item_validation_class_list(id).each{|klass| + klass._config_keys.each{|key| + k2c[key.to_s] = klass + } + } + end + + def __conv_item_vcmd_on_hash_kv(keys) + key2class = __get_item_validate_key2class(tagid(tagOrId)) + + keys = _symbolkey2str(keys) + key2class.each{|key, klass| + if keys[key].kind_of?(Array) + cmd, *args = keys[key] + keys[key] = klass.new(cmd, args.join(' ')) + # elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method) + elsif TkComm._callback_entry?(keys[key]) + keys[key] = klass.new(keys[key]) + end + } + keys + end + + def itemconfigure(tagOrId, slot, value=TkComm::None) + if slot.kind_of?(Hash) + super(__conv_item_vcmd_on_hash_kv(slot)) + else + super(__conv_item_vcmd_on_hash_kv(slot=>value)) + end + self + end +=begin + def itemconfigure(tagOrId, slot, value=TkComm::None) + key2class = __get_item_validate_key2class(tagid(tagOrId)) + + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + key2class.each{|key, klass| + if slot[key].kind_of?(Array) + cmd, *args = slot[key] + slot[key] = klass.new(cmd, args.join(' ')) + elsif slot[key].kind_of?(Proc) || slot[key].kind_of?(Method) + slot[key] = klass.new(slot[key]) + end + } + super(slot) + + else + slot = slot.to_s + if (klass = key2class[slot]) + if value.kind_of?(Array) + cmd, *args = value + value = klass.new(cmd, args.join(' ')) + elsif value.kind_of?(Proc) || value.kind_of?(Method) + value = klass.new(value) + end + end + super(slot, value) + end + + self + end +=end + end +end + +class TkValidateCommand + include TkComm + extend TkComm + + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?d, ?n, :action ], + [ ?i, ?x, :index ], + [ ?s, ?e, :current ], + [ ?v, ?s, :type ], + [ ?P, ?e, :value ], + [ ?S, ?e, :string ], + [ ?V, ?s, :triggered ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + + [ ?e, proc{|val| + #enc = Tk.encoding + enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system) + if enc + Tk.fromUTF8(TkComm::string(val), enc) + else + TkComm::string(val) + end + } + ], + + [ ?x, proc{|val| + idx = TkComm::number(val) + if idx < 0 + nil + else + idx + end + } + ], + + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + # + # NOTE: The order of parameters which passed to callback procedure is + # <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ... + # + + #def self._get_extra_args_tbl + # # return an array of convert procs + # [] + #end + + def self.ret_val(val) + (val)? '1': '0' + end + end + + ############################################### + + def self._config_keys + # array of config-option key (string or symbol) + ['vcmd', 'validatecommand', 'invcmd', 'invalidcommand'] + end + + def _initialize_for_cb_class(klass, cmd = Proc.new, *args) + extra_args_tbl = klass._get_extra_args_tbl + + if args.compact.size > 0 + args = args.join(' ') + keys = klass._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| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + klass.ret_val(cmd.call( + *(ex_args.concat(klass.scan_args(keys, arg))) + )) + }) + ' ' + args + end + else + keys, args = klass._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| + ex_args = [] + extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)} + klass.ret_val(cmd.call( + *(ex_args << klass.new(*klass.scan_args(keys, arg))) + )) + }) + ' ' + args + end + end + end + + def initialize(cmd = Proc.new, *args) + _initialize_for_cb_class(self.class::ValidateArgs, cmd, *args) + end + + def to_eval + @id + end +end + +module TkValidation + include Tk::ValidateConfigure + + class ValidateCmd < TkValidateCommand + module Action + Insert = 1 + Delete = 0 + Others = -1 + Focus = -1 + Forced = -1 + Textvariable = -1 + TextVariable = -1 + end + end + + ##################################### + + def __validation_class_list + super() << ValidateCmd + end + + Tk::ValidateConfigure.__def_validcmd(binding, ValidateCmd) + +=begin + 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 +=end +# def validatecommand(*args, &b) +# __validcmd_call(ValidateCmd, 'validatecommand', *args, &b) +# end +# alias vcmd validatecommand + +=begin + 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 +=end +# def invalidcommand(*args, &b) +# __validcmd_call(ValidateCmd, 'invalidcommand', *args, &b) +# end +# alias invcmd invalidcommand +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/variable.rb b/ruby_1_8_6/ext/tk/lib/tk/variable.rb new file mode 100644 index 0000000000..e5cacadc1a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/variable.rb @@ -0,0 +1,1651 @@ +# +# 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(id, name1, name2, op) + #name1,name2,op = tk_split_list(args) + #name1,name2,op = tk_split_simplelist(args) + if TkVar_CB_TBL[id] + #_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op)) + begin + _get_eval_string(TkVar_CB_TBL[id].trace_callback(name2, op)) + rescue SystemExit + exit(0) + rescue Interrupt + exit!(1) + 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 self.new_hash(val = {}) + if val.kind_of?(Hash) + self.new(val) + else + fail ArgumentError, 'Hash is expected' + end + end + + # + # default_value is available only when the variable is an assoc array. + # + def default_value(val=nil, &b) + if b + @def_default = :proc + @default_val = proc(&b) + else + @def_default = :val + @default_val = val + end + self + end + def set_default_value(val) + @def_default = :val + @default_val = val + self + end + alias default_value= set_default_value + def default_proc(cmd = Proc.new) + @def_default = :proc + @default_val = cmd + self + end + + def undef_default + @default_val = nil + @def_default = false + self + end + + def default_value_type + @type + end + def default_element_value_type(idxs) + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + @element_type[index] + end + + def _set_default_value_type_core(type, idxs) + if type.kind_of?(Class) + if type == NilClass + type = nil + elsif type == Numeric + type = :numeric + elsif type == TrueClass || type == FalseClass + type = :bool + elsif type == String + type = :string + elsif type == Symbol + type = :symbol + elsif type == Array + type = :list + elsif type <= TkVariable + type = :variable + elsif type <= TkWindow + type = :window + elsif TkComm._callback_entry_class?(type) + type = :procedure + else + type = nil + end + else + case(type) + when nil + type = nil + when :numeric, 'numeric' + type = :numeric + when true, false, :bool, 'bool' + type = :bool + when :string, 'string' + type = :string + when :symbol, 'symbol' + type = :symbol + when :list, 'list' + type = :list + when :numlist, 'numlist' + type = :numlist + when :variable, 'variable' + type = :variable + when :window, 'window' + type = :window + when :procedure, 'procedure' + type = :procedure + else + return _set_default_value_type_core(type.class, idxs) + end + end + if idxs + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + @element_type[index] = type + else + @type = type + end + type + end + private :_set_default_value_type_core + + def set_default_value_type(type) + _set_default_value_type_core(type, nil) + self + end + alias default_value_type= set_default_value_type + + def set_default_element_value_type(idxs, type) + _set_default_value_type_core(type, idxs) + self + end + + def _to_default_type(val, idxs = nil) + if idxs + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + type = @element_type[index] + else + type = @type + end + return val unless type + if val.kind_of?(Hash) + val.keys.each{|k| val[k] = _to_default_type(val[k], idxs) } + val + else + begin + case(type) + when :numeric + number(val) + when :bool + TkComm.bool(val) + when :string + val + when :symbol + val.intern + when :list + tk_split_simplelist(val) + when :numlist + tk_split_simplelist(val).collect!{|v| number(v)} + when :variable + TkVarAccess.new(val) + when :window + TkComm.window(val) + when :procedure + TkComm.procedure(val) + else + val + end + rescue + val + end + end + end + private :_to_default_type + + def _to_default_element_type(idxs, val) + _to_default_type(val, idxs) + end + private :_to_default_element_type + + def initialize(val="", type=nil) + # @id = Tk_VARIABLE_ID.join('') + begin + @id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_) + Tk_VARIABLE_ID[1].succ! + end until INTERP._invoke_without_enc('info', 'globals', @id).empty? + + TkVar_ID_TBL[@id] = self + + @var = @id + @elem = nil + + @def_default = false + @default_val = nil + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + @type = nil + var = self + @element_type = Hash.new{|k,v| var.default_value_type } + + self.default_value_type = type + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @id) + #INTERP._invoke('global', @id) + + # create and init + if val.kind_of?(Hash) + # assoc-array variable + self[''] = 0 + self.clear + end + 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 ref(*idxs) + # "#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})" + TkVarAccess.new("#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})") + end + + def is_hash? + #ITNERP._eval("global #{@id}; array exist #{@id}") == '1' + INTERP._invoke_without_enc('global', @id) + # INTERP._invoke_without_enc('array', 'exist', @id) == '1' + TkComm.bool(INTERP._invoke_without_enc('array', 'exist', @id)) + end + + def is_scalar? + ! is_hash? + end + + def exist?(*elems) + INTERP._invoke_without_enc('global', @id) + if elems.empty? + TkComm.bool(tk_call('info', 'exist', @id)) + else + # array + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + TkComm.bool(tk_call('info', 'exist', "#{@id}")) && + TkComm.bool(tk_call('info', 'exist', "#{@id}(#{index})")) + end + 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}")) + INTERP._invoke_without_enc('global', @id) + #tk_split_simplelist(INTERP._fromUTF8(INTERP._invoke_without_enc('array', 'names', @id))) + tk_split_simplelist(INTERP._invoke_without_enc('array', 'names', @id), + false, true) + end + + def size + INTERP._invoke_without_enc('global', @id) + TkComm.number(INTERP._invoke_without_enc('array', 'size', @id)) + end + + def clear + if (is_scalar?) + fail RuntimeError, 'cannot clear a scalar variable' + end + keys.each{|k| unset(k)} + self + end + + def update(hash) + if (is_scalar?) + fail RuntimeError, 'cannot update a scalar variable' + end + hash.each{|k,v| self[k] = v} + self + 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' + INTERP._invoke_without_enc('global', @id) + # if INTERP._invoke('array', 'exist', @id) == '1' + if TkComm.bool(INTERP._invoke('array', 'exist', @id)) + #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) + val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable) + if val.kind_of?(Hash) + self.clear + 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) +=begin + 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 +=end +# _fromUTF8(INTERP._set_global_var(@id, array2tk_list(val, true))) + 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 _element_value(*idxs) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + begin + _fromUTF8(INTERP._get_global_var2(@id, index)) + rescue => e + case @def_default + when :proc + @default_val.call(self, *idxs) + when :val + @default_val + else + fail e + end + end + #_fromUTF8(INTERP._get_global_var2(@id, 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 []=(*args) + val = args.pop + type = default_element_value_type(args) + val = val._value if !type && type != :variable && val.kind_of?(TkVariable) + index = args.collect{|idx| _get_eval_string(idx, true)}.join(',') + _fromUTF8(INTERP._set_global_var2(@id, index, _get_eval_string(val, true))) + #_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(*elems) + if elems.empty? + INTERP._unset_global_var(@id) + else + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + INTERP._unset_global_var2(@id, index) + 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) + val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable) + 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, true))} + #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, true)}.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 _element_value(*idxs) + index = idxs.collect{|idx| _get_eval_string(idx)}.join(',') + begin + INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index)) + rescue => e + case @def_default + when :proc + @default_val.call(self, *idxs) + when :val + @default_val + else + fail e + end + end + #INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, 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 []=(*args) + val = args.pop + type = default_element_value_type(args) + val = val._value if !type && type != :variable && val.kind_of?(TkVariable) + index = args.collect{|idx| _get_eval_string(idx)}.join(',') + INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, + index, _get_eval_string(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(*elems) + if elems.empty? + INTERP._eval(Kernel.format('global %s; unset %s', @id, @id)) + #INTERP._eval(Kernel.format('unset %s', @id)) + #INTERP._eval('unset ' + @id) + else + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + INTERP._eval(Kernel.format('global %s; unset %s(%s)', @id, @id, index)) + #INTERP._eval(Kernel.format('global %s; unset %s(%s)', + # @id, @id, _get_eval_string(elem))) + #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem))) + #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')') + end + end + alias remove unset + +end + + protected :_value, :_element_value + + def value + _to_default_type(_value) + end + + def [](*idxs) + _to_default_element_type(idxs, _element_value(*idxs)) + end + + def set_value(val) + self.value = val + self + end + + def set_element_value(idxs, val) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + + def set_value_type(val) + self.default_value_type = val.class + self.value = val + self + end + + alias value_type= set_value_type + + def set_element_value_type(idxs, val) + self.set_default_element_value_type(idxs, val.class) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + + def numeric + number(_value) + end + def numeric_element(*idxs) + number(_element_value(*idxs)) + end + def set_numeric(val) + case val + when Numeric + self.value=(val) + when TkVariable + self.value=(val.numeric) + else + raise ArgumentError, "Numeric is expected" + end + self + end + alias numeric= set_numeric + def set_numeric_element(idxs, val) + case val + when Numeric + val + when TkVariable + val = val.numeric + else + raise ArgumentError, "Numeric is expected" + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_numeric_type(val) + @type = :numeric + self.numeric=(val) + self + end + alias numeric_type= set_numeric_type + def set_numeric_element_type(idxs, val) + self.set_default_element_value_type(idxs, :numeric) + self.set_numeric_element(idxs, val) + end + + def bool + TkComm.bool(_value) +=begin + # see Tcl_GetBoolean man-page + case _value.downcase + when '0', 'false', 'no', 'off' + false + else + true + end +=end + end + def bool_element(*idxs) + TkComm.bool(_element_value(*idxs)) + end + def set_bool(val) + if ! val + self.value = '0' + else + case val.to_s.downcase + when 'false', '0', 'no', 'off' + self.value = '0' + else + self.value = '1' + end + end + self + end + alias bool= set_bool + def set_bool_element(idxs, val) + if ! val + val = '0' + else + case val.to_s.downcase + when 'false', '0', 'no', 'off' + val = '0' + else + val = '1' + end + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_bool_type(val) + @type = :bool + self.bool=(val) + self + end + alias bool_type= set_bool_type + def set_bool_element_type(idxs, val) + self.set_default_element_value_type(idxs, :bool) + self.set_bool_element(idxs, val) + end + + def variable + # keeps a Tcl's variable name + TkVarAccess.new(self._value) + end + def variable_element(*idxs) + TkVarAccess.new(_element_value(*idxs)) + end + def set_variable(var) + var = var.id if var.kind_of?(TkVariable) + self.value = var + self + end + alias variable= set_variable + def set_variable_element(idxs, var) + var = var.id if var.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=var + else + self[idxs]=var + end + self + end + def set_variable_type(var) + @type = :variable + var = var.id if var.kind_of?(TkVariable) + self.value = var + self + end + alias variable_type= set_variable_type + def set_variable_element_type(idxs, var) + self.set_default_element_value_type(idxs, :variable) + self.set_variable_element(idxs, var) + end + + def window + TkComm.window(self._value) + end + def window_element(*idxs) + TkComm.window(_element_value(*idxs)) + end + def set_window(win) + win = win._value if win.kind_of?(TkVariable) + self.value = win + self + end + alias window= set_window + def set_window_element(idxs, win) + win = win._value if win.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=win + else + self[idxs]=win + end + self + end + def set_window_type(win) + @type = :window + self.window=(win) + self + end + alias window_type= set_window_type + def set_window_element_type(idxs, win) + self.set_default_element_value_type(idxs, :window) + self.set_window_element(idxs, win) + end + + def procedure + TkComm.procedure(self._value) + end + def procedure_element(*idxs) + TkComm.procedure(_element_value(*idxs)) + end + def set_procedure(cmd) + self.value = cmd + self + end + alias procedure= set_procedure + def set_procedure_element(idxs, cmd) + cmd = cmd._value if cmd.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=cmd + else + self[idxs]=cmd + end + self + end + def set_procedure_type(cmd) + @type = :procedure + self.procedure=(cmd) + self + end + alias procedure_type= set_procedure_type + def set_procedure_element_type(idxs, cmd) + self.set_default_element_value_type(idxs, :procedure) + self.set_proceure_element(idxs, cmd) + end + + def to_i + number(_value).to_i + end + def element_to_i(*idxs) + number(_element_value(*idxs)).to_i + end + + def to_f + number(_value).to_f + end + def element_to_f(*idxs) + number(_element_value(*idxs)).to_f + end + + def to_s + #string(value).to_s + _value + end + alias string to_s + def element_to_s(*idxs) + _element_value(*idxs) + end + def string_element(*idxs) + _element_value(*idxs) + end + def set_string(val) + val = val._value if val.kind_of?(TkVariable) + self.value=val + self + end + alias string= set_string + def set_string_element(idxs, val) + val = val._value if val.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_string_type(val) + @type = :string + self.string=(val) + self + end + alias string_type= set_string_type + def set_string_element_type(idxs, val) + self.set_default_element_value_type(idxs, :string) + self.set_string_element(idxs, val) + end + + def to_sym + _value.intern + end + alias symbol to_sym + def element_to_sym(*idxs) + _element_value(*idxs).intern + end + alias symbol_element element_to_sym + def set_symbol(val) + val = val._value if val.kind_of?(TkVariable) + self.value=val + self + end + alias symbol= set_symbol + def set_symbol_element(idxs, val) + val = val._value if val.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_symbol_type(val) + @type = :symbol + self.value=(val) + self + end + alias symbol_type= set_symbol_type + def set_symbol_element_type(idxs, val) + self.set_default_element_value_type(idxs, :symbol) + self.set_symbol_element(idxs, val) + end + + def list + #tk_split_list(value) + tk_split_simplelist(_value) + end + alias to_a list + def list_element(*idxs) + tk_split_simplelist(_element_value(*idxs)) + end + alias element_to_a list_element + + def numlist + list.collect!{|val| number(val)} + end + def numlist_element(*idxs) + list_element(*idxs).collect!{|val| number(val)} + end + + def set_list(val) + case val + when Array + self.value=(val) + when TkVariable + self.value=(val.list) + else + raise ArgumentError, "Array is expected" + end + self + end + alias list= set_list + + alias set_numlist set_list + alias numlist= set_numlist + + def set_list_element(idxs, val) + case val + when Array + val + when TkVariable + val = val.list + else + raise ArgumentError, "Array is expected" + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + alias set_numlist_element set_list_element + + def set_list_type(val) + @type = :list + self.list=(val) + self + end + alias list_type= set_list_type + def set_list_element_type(idxs, val) + self.set_default_element_value_type(idxs, :list) + self.set_list_element(idxs, val) + end + def set_numlist_type(val) + @type = :numlist + self.numlist=(val) + self + end + alias numlist_type= set_numlist_type + def set_numlist_element_type(idxs, val) + self.set_default_element_value_type(idxs, :numlist) + self.set_numlist_element(idxs, val) + end + + def lappend(*elems) + tk_call('lappend', @id, *elems) + self + end + def element_lappend(idxs, *elems) + if idxs.kind_of?(Array) + idxs = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + end + tk_call('lappend', "#{@id}(#{idxs})", *elems) + self + end + + def lindex(idx) + tk_call('lindex', self._value, idx) + end + alias lget lindex + def element_lindex(elem_idxs, idx) + if elem_idxs.kind_of?(Array) + val = _element_value(*elem_idxs) + else + val = _element_value(elem_idxs) + end + tk_call('lindex', val, idx) + end + alias element_lget element_lindex + + def lget_i(idx) + number(lget(idx)).to_i + end + def element_lget_i(elem_idxs, idx) + number(element_lget(elem_idxs, idx)).to_i + end + + def lget_f(idx) + number(lget(idx)).to_f + end + def element_lget_f(elem_idxs, idx) + number(element_lget(elem_idxs, idx)).to_f + end + + def lset(idx, val) + tk_call('lset', @id, idx, val) + self + end + def element_lset(elem_idxs, idx, val) + if elem_idxs.kind_of?(Array) + idxs = elem_idxs.collect{|i| _get_eval_string(i, true)}.join(',') + end + tk_call('lset', "#{@id}(#{idxs})", idx, val) + self + end + + def inspect + #Kernel.format "#<TkVariable: %s>", @id + '#<TkVariable: ' + @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) + num_or_str(self._value) * other.to_i + #begin + # number(self._value) * other + #rescue + # self._value * other + #end + end + def /(other) + number(self._value) / other + end + def %(other) + num_or_str(self._value) % other.to_i + #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) + self._value == other._value + 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 + # false if self is not an assoc array + self._value == other + else + # false + self._value == _get_eval_string(other) + 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 + elsif other.kind_of?(Numeric) + begin + return self.numeric <=> other + rescue + return self._value <=> other.to_s + end + elsif other.kind_of?(Array) + return self.list <=> other + 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('') + opts = opts.to_s + 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 ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, 'rb_var') + end +=end + else + newopts = @trace_opts.dup + #opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} + opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, + 'rb_var ' << @id) + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @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) + if @elem + fail(RuntimeError, + "invalid for a TkVariable which denotes an element of Tcl's array") + end + @trace_elem = {} if @trace_elem == nil + @trace_elem[elem] = [] if @trace_elem[elem] == nil + opts = opts.to_s + 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 ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + else + newopts = @trace_opts.dup + # opts.each_byte{|c| newopts += c.chr unless newopts.index(c)} + opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + if newopts != @trace_opts + Tk.tk_call_without_enc('trace', 'vdelete', @id, @trace_opts, + 'rb_var ' << @id) + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'variable', @id, @trace_opts, + 'rb_var ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + @trace_opts.replace(newopts) + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @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) + if @elem + fail(RuntimeError, + "invalid for a TkVariable which denotes an element of Tcl's array") + end + 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 = opts.to_s + 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)} + e[0].each_byte{|c| newopts.concat(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)} + e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + } + } + + newopts = newopts.to_s + 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 ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @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 ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', + @id, @trace_opts, 'rb_var') + end +=end + end + end + + self + end + + def trace_vdelete_for_element(elem,opts,cmd) + if @elem + fail(RuntimeError, + "invalid for a TkVariable which denotes an element of Tcl's array") + end + return self unless @trace_elem.kind_of? Hash + return self unless @trace_elem[elem].kind_of? Array + opts = opts.to_s + 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)} + e[0].each_byte{|c| newopts.concat(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)} + e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c)} + } + } + + newopts = newopts.to_s + 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 ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'remove', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'vdelete', + @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 ' << @id) +=begin + if /^(8\.([4-9]|[1-9][0-9])|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION + # TCL_VERSION >= 8.4 + Tk.tk_call_without_enc('trace', 'add', 'variable', + @id, @trace_opts, 'rb_var') + else + # TCL_VERSION <= 8.3 + Tk.tk_call_without_enc('trace', 'variable', @id, + @trace_opts, 'rb_var') + end +=end + end + end + + self + end +end + +class TkVarAccess<TkVariable + def self.new(name, *args) + if name.kind_of?(TkVariable) + name.value = args[0] unless args.empty? + return name + end + + if v = TkVar_ID_TBL[name] + v.value = args[0] unless args.empty? + return v + end + + super(name, *args) + end + + def self.new_hash(name, *args) + if name.kind_of?(TkVariable) + unless name.is_hash? + fail ArgumentError, "already exist as a scalar variable" + end + name.value = args[0] unless args.empty? + return name + end + + if v = TkVar_ID_TBL[name] + unless v.is_hash? + fail ArgumentError, "already exist as a scalar variable" + end + v.value = args[0] unless args.empty? + return v + end + + INTERP._invoke_without_enc('global', name) + if args.empty? && INTERP._invoke_without_enc('array', 'exist', name) == '0' + self.new(name, {}) # force creating + else + self.new(name, *args) + end + end + + def initialize(varname, val=nil) + @id = varname + TkVar_ID_TBL[@id] = self + + @var = @id + @elem = nil + + @def_default = false + @default_val = nil + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + @type = nil + var = self + @element_type = Hash.new{|k,v| var.default_value_type } + + # is an element? + if @id =~ /^([^(]+)\((.+)\)$/ + # is an element --> var == $1, elem == $2 + @var = $1 + @elem = $2 + end + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @var) +=begin + begin + INTERP._invoke_without_enc('global', @id) + rescue => e + if @id =~ /^(.+)\([^()]+\)$/ + # is an element --> varname == $1 + INTERP._invoke_without_enc('global', $1) + else + fail e + end + end +=end + + if val + if val.kind_of?(Hash) + # assoc-array variable + self[''] = 0 + self.clear + end + #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._set_global_var(@id, _toUTF8(_get_eval_string(val))) + self.value = val + end + end +end + +module Tk + begin + INTERP._invoke_without_enc('global', 'auto_path') + auto_path = INTERP._invoke('set', 'auto_path') + rescue => e + begin + INTERP._invoke_without_enc('global', 'env') + auto_path = INTERP._invoke('set', 'env(TCLLIBPATH)') + rescue => e + auto_path = Tk::LIBRARY + end + end + + AUTO_PATH = TkVarAccess.new('auto_path', auto_path) + +=begin + AUTO_OLDPATH = tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath')) + AUTO_OLDPATH.each{|s| s.freeze} + AUTO_OLDPATH.freeze +=end + + TCL_PACKAGE_PATH = TkVarAccess.new('tcl_pkgPath') + PACKAGE_PATH = TCL_PACKAGE_PATH + + TCL_LIBRARY_PATH = TkVarAccess.new('tcl_libPath') + LIBRARY_PATH = TCL_LIBRARY_PATH + + TCL_PRECISION = TkVarAccess.new('tcl_precision') +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/virtevent.rb b/ruby_1_8_6/ext/tk/lib/tk/virtevent.rb new file mode 100644 index 0000000000..d47e80aecd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/virtevent.rb @@ -0,0 +1,106 @@ +# +# tk/virtevent.rb : treats virtual events +# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +require 'tk' + +class TkVirtualEvent<TkObject + extend Tk + + TkCommandNames = ['event'.freeze].freeze + + TkVirtualEventID = ["VirtEvent".freeze, "00000".taint].freeze + TkVirtualEventTBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ TkVirtualEventTBL.clear } + + class PreDefVirtEvent<self + def self.new(event, *sequences) + if event =~ /^<(<.*>)>$/ + event = $1 + elsif event !~ /^<.*>$/ + event = '<' + event + '>' + end + if TkVirtualEvent::TkVirtualEventTBL.has_key?(event) + TkVirtualEvent::TkVirtualEventTBL[event] + else + super(event, *sequences) + end + end + + def initialize(event, *sequences) + @path = @id = event + TkVirtualEvent::TkVirtualEventTBL[@id] = self + add(*sequences) + end + end + + def TkVirtualEvent.getobj(event) + obj = TkVirtualEventTBL[event] + if obj + obj + else + if tk_call_without_enc('event', 'info').index("<#{event}>") + 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('') + '>' + @path = @id = '<' + TkVirtualEventID.join(TkCore::INTERP._ip_id_) + '>' + 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 + +TkNamedVirtualEvent = TkVirtualEvent::PreDefVirtEvent diff --git a/ruby_1_8_6/ext/tk/lib/tk/winfo.rb b/ruby_1_8_6/ext/tk/lib/tk/winfo.rb new file mode 100644 index 0000000000..c649b4a0c9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/winfo.rb @@ -0,0 +1,392 @@ +# +# tk/winfo.rb : methods for winfo command +# +module TkWinfo +end + +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(win) + number(tk_call_without_enc('winfo', 'cells', win)) + end + def winfo_cells + TkWinfo.cells self + end + + def TkWinfo.children(win) + list(tk_call_without_enc('winfo', 'children', win)) + end + def winfo_children + TkWinfo.children self + end + + def TkWinfo.classname(win) + tk_call_without_enc('winfo', 'class', win) + end + def winfo_classname + TkWinfo.classname self + end + alias winfo_class winfo_classname + + def TkWinfo.colormapfull(win) + bool(tk_call_without_enc('winfo', 'colormapfull', win)) + 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(win) + number(tk_call_without_enc('winfo', 'depth', win)) + end + def winfo_depth + TkWinfo.depth self + end + + def TkWinfo.exist?(win) + bool(tk_call_without_enc('winfo', 'exists', win)) + end + def winfo_exist? + TkWinfo.exist? self + end + + def TkWinfo.fpixels(win, dist) + number(tk_call_without_enc('winfo', 'fpixels', win, dist)) + end + def winfo_fpixels(dist) + TkWinfo.fpixels self, dist + end + + def TkWinfo.geometry(win) + tk_call_without_enc('winfo', 'geometry', win) + end + def winfo_geometry + TkWinfo.geometry self + end + + def TkWinfo.height(win) + number(tk_call_without_enc('winfo', 'height', win)) + end + def winfo_height + TkWinfo.height self + end + + def TkWinfo.id(win) + tk_call_without_enc('winfo', 'id', win) + end + def winfo_id + TkWinfo.id self + end + + def TkWinfo.interps(win=nil) + if win + #tk_split_simplelist(tk_call_without_enc('winfo', 'interps', + # '-displayof', win)) + tk_split_simplelist(tk_call_without_enc('winfo', 'interps', + '-displayof', win), + false, true) + else + #tk_split_simplelist(tk_call_without_enc('winfo', 'interps')) + tk_split_simplelist(tk_call_without_enc('winfo', 'interps'), + false, true) + end + end + def winfo_interps + TkWinfo.interps self + end + + def TkWinfo.mapped?(win) + bool(tk_call_without_enc('winfo', 'ismapped', win)) + end + def winfo_mapped? + TkWinfo.mapped? self + end + + def TkWinfo.manager(win) + tk_call_without_enc('winfo', 'manager', win) + end + def winfo_manager + TkWinfo.manager self + end + + def TkWinfo.appname(win) + tk_call('winfo', 'name', win) + end + def winfo_appname + TkWinfo.appname self + end + + def TkWinfo.parent(win) + window(tk_call_without_enc('winfo', 'parent', win)) + 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(win, dist) + number(tk_call_without_enc('winfo', 'pixels', win, dist)) + end + def winfo_pixels(dist) + TkWinfo.pixels self, dist + end + + def TkWinfo.reqheight(win) + number(tk_call_without_enc('winfo', 'reqheight', win)) + end + def winfo_reqheight + TkWinfo.reqheight self + end + + def TkWinfo.reqwidth(win) + number(tk_call_without_enc('winfo', 'reqwidth', win)) + end + def winfo_reqwidth + TkWinfo.reqwidth self + end + + def TkWinfo.rgb(win, color) + list(tk_call_without_enc('winfo', 'rgb', win, color)) + end + def winfo_rgb(color) + TkWinfo.rgb self, color + end + + def TkWinfo.rootx(win) + number(tk_call_without_enc('winfo', 'rootx', win)) + end + def winfo_rootx + TkWinfo.rootx self + end + + def TkWinfo.rooty(win) + number(tk_call_without_enc('winfo', 'rooty', win)) + end + def winfo_rooty + TkWinfo.rooty self + end + + def TkWinfo.screen(win) + tk_call('winfo', 'screen', win) + end + def winfo_screen + TkWinfo.screen self + end + + def TkWinfo.screencells(win) + number(tk_call_without_enc('winfo', 'screencells', win)) + end + def winfo_screencells + TkWinfo.screencells self + end + + def TkWinfo.screendepth(win) + number(tk_call_without_enc('winfo', 'screendepth', win)) + end + def winfo_screendepth + TkWinfo.screendepth self + end + + def TkWinfo.screenheight (win) + number(tk_call_without_enc('winfo', 'screenheight', win)) + end + def winfo_screenheight + TkWinfo.screenheight self + end + + def TkWinfo.screenmmheight(win) + number(tk_call_without_enc('winfo', 'screenmmheight', win)) + end + def winfo_screenmmheight + TkWinfo.screenmmheight self + end + + def TkWinfo.screenmmwidth(win) + number(tk_call_without_enc('winfo', 'screenmmwidth', win)) + end + def winfo_screenmmwidth + TkWinfo.screenmmwidth self + end + + def TkWinfo.screenvisual(win) + tk_call_without_enc('winfo', 'screenvisual', win) + end + def winfo_screenvisual + TkWinfo.screenvisual self + end + + def TkWinfo.screenwidth(win) + number(tk_call_without_enc('winfo', 'screenwidth', win)) + end + def winfo_screenwidth + TkWinfo.screenwidth self + end + + def TkWinfo.server(win) + tk_call('winfo', 'server', win) + end + def winfo_server + TkWinfo.server self + end + + def TkWinfo.toplevel(win) + window(tk_call_without_enc('winfo', 'toplevel', win)) + end + def winfo_toplevel + TkWinfo.toplevel self + end + + def TkWinfo.visual(win) + tk_call_without_enc('winfo', 'visual', win) + end + def winfo_visual + TkWinfo.visual self + end + + def TkWinfo.visualid(win) + tk_call_without_enc('winfo', 'visualid', win) + end + def winfo_visualid + TkWinfo.visualid self + end + + def TkWinfo.visualsavailable(win, includeids=false) + if includeids + list(tk_call_without_enc('winfo', 'visualsavailable', + win, "includeids")) + else + list(tk_call_without_enc('winfo', 'visualsavailable', win)) + end + end + def winfo_visualsavailable(includeids=false) + TkWinfo.visualsavailable self, includeids + end + + def TkWinfo.vrootheight(win) + number(tk_call_without_enc('winfo', 'vrootheight', win)) + end + def winfo_vrootheight + TkWinfo.vrootheight self + end + + def TkWinfo.vrootwidth(win) + number(tk_call_without_enc('winfo', 'vrootwidth', win)) + end + def winfo_vrootwidth + TkWinfo.vrootwidth self + end + + def TkWinfo.vrootx(win) + number(tk_call_without_enc('winfo', 'vrootx', win)) + end + def winfo_vrootx + TkWinfo.vrootx self + end + + def TkWinfo.vrooty(win) + number(tk_call_without_enc('winfo', 'vrooty', win)) + end + def winfo_vrooty + TkWinfo.vrooty self + end + + def TkWinfo.width(win) + number(tk_call_without_enc('winfo', 'width', win)) + end + def winfo_width + TkWinfo.width self + end + + def TkWinfo.x(win) + number(tk_call_without_enc('winfo', 'x', win)) + end + def winfo_x + TkWinfo.x self + end + + def TkWinfo.y(win) + number(tk_call_without_enc('winfo', 'y', win)) + end + def winfo_y + TkWinfo.y self + end + + def TkWinfo.viewable(win) + bool(tk_call_without_enc('winfo', 'viewable', win)) + end + def winfo_viewable + TkWinfo.viewable self + end + + def TkWinfo.pointerx(win) + number(tk_call_without_enc('winfo', 'pointerx', win)) + end + def winfo_pointerx + TkWinfo.pointerx self + end + + def TkWinfo.pointery(win) + number(tk_call_without_enc('winfo', 'pointery', win)) + end + def winfo_pointery + TkWinfo.pointery self + end + + def TkWinfo.pointerxy(win) + list(tk_call_without_enc('winfo', 'pointerxy', win)) + end + def winfo_pointerxy + TkWinfo.pointerxy self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/winpkg.rb b/ruby_1_8_6/ext/tk/lib/tk/winpkg.rb new file mode 100644 index 0000000000..737fb959b5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/winpkg.rb @@ -0,0 +1,143 @@ +# +# tk/winpkg.rb : methods for Tcl/Tk packages for Microsoft Windows +# 2000/11/22 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp> +# +# ATTENTION !! +# This is NOT TESTED. Because I have no test-environment. +# +require 'tk' + +module TkWinDDE + extend Tk + extend TkWinDDE + + TkCommandNames = ['dde'.freeze].freeze + + PACKAGE_NAME = 'dde'.freeze + def self.package_name + PACKAGE_NAME + end + + 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) # dde 1.2 + + 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 + else + tk_call('dde', 'servername', *args) + 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/ruby_1_8_6/ext/tk/lib/tk/wm.rb b/ruby_1_8_6/ext/tk/lib/tk/wm.rb new file mode 100644 index 0000000000..1f432a3848 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tk/wm.rb @@ -0,0 +1,360 @@ +# +# tk/wm.rb : methods for wm command +# +require 'tk' + +module Tk + module Wm + include TkComm + + TkCommandNames = ['wm'.freeze].freeze + + TOPLEVEL_METHODCALL_OPTKEYS = {} + + def aspect(*args) + if args.length == 0 + list(tk_call_without_enc('wm', 'aspect', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call('wm', 'aspect', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['aspect'] = 'aspect' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['attributes'] = 'attributes' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['client'] = 'client' + + def colormapwindows(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'colormapwindows', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'colormapwindows', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['colormapwindows'] = 'colormapwindows' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['wm_command'] = 'wm_command' + + def deiconify(ex = true) + if ex + tk_call_without_enc('wm', 'deiconify', path) + else + self.iconify + end + 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 + TOPLEVEL_METHODCALL_OPTKEYS['focusmodel'] = 'focusmodel' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['geometry'] = 'geometry' + + def wm_grid(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'grid', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'grid', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['wm_grid'] = 'wm_grid' + + def group(leader = nil) + if leader + tk_call('wm', 'group', path, leader) + self + else + window(tk_call('wm', 'group', path)) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['group'] = 'group' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['iconbitmap'] = 'iconbitmap' + + def iconphoto(*imgs) + if imgs.empty? + @wm_iconphoto = nil unless defined? @wm_iconphoto + return @wm_iconphoto + end + + imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array) + tk_call_without_enc('wm', 'iconphoto', path, *imgs) + @wm_iconphoto = imgs + self + end + TOPLEVEL_METHODCALL_OPTKEYS['iconphoto'] = 'iconphoto' + + def iconphoto_default(*imgs) + imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array) + tk_call_without_enc('wm', 'iconphoto', path, '-default', *imgs) + self + end + + def iconify(ex = true) + if ex + tk_call_without_enc('wm', 'iconify', path) + else + self.deiconify + end + 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 + TOPLEVEL_METHODCALL_OPTKEYS['iconmask'] = 'iconmask' + + def iconname(name=nil) + if name + tk_call('wm', 'iconname', path, name) + self + else + tk_call('wm', 'iconname', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconname'] = 'iconname' + + def iconposition(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'iconposition', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'iconposition', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['iconposition'] = 'iconposition' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['iconwindow'] = 'iconwindow' + + def maxsize(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'maxsize', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'maxsize', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['maxsize'] = 'maxsize' + + def minsize(*args) + if args.size == 0 + list(tk_call_without_enc('wm', 'minsize', path)) + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'minsize', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['minsize'] = 'minsize' + + def overrideredirect(mode=None) + if mode == None + bool(tk_call_without_enc('wm', 'overrideredirect', path)) + else + tk_call_without_enc('wm', 'overrideredirect', path, mode) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['positionfrom'] = 'positionfrom' + + def protocol(name=nil, cmd=nil, &b) + if cmd + tk_call_without_enc('wm', 'protocol', path, name, cmd) + self + elsif b + tk_call_without_enc('wm', 'protocol', path, name, proc(&b)) + 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 protocols(kv=nil) + unless kv + ret = {} + self.protocol.each{|name| + ret[name] = self.protocol(name) + } + return ret + end + + unless kv.kind_of?(Hash) + fail ArgumentError, 'expect a hash of protocol=>command' + end + kv.each{|k, v| self.protocol(k, v)} + self + end + TOPLEVEL_METHODCALL_OPTKEYS['protocols'] = 'protocols' + + def resizable(*args) + if args.length == 0 + list(tk_call_without_enc('wm', 'resizable', path)).collect{|e| bool(e)} + else + args = args[0] if args.length == 1 && args[0].kind_of?(Array) + tk_call_without_enc('wm', 'resizable', path, *args) + self + end + end + TOPLEVEL_METHODCALL_OPTKEYS['resizable'] = 'resizable' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['sizefrom'] = 'sizefrom' + + 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(st=nil) + if st + tk_call_without_enc('wm', 'state', path, st) + self + else + tk_call_without_enc('wm', 'state', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['state'] = 'state' + + def title(str=nil) + if str + tk_call('wm', 'title', path, str) + self + else + tk_call('wm', 'title', path) + end + end + TOPLEVEL_METHODCALL_OPTKEYS['title'] = 'title' + + 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 + TOPLEVEL_METHODCALL_OPTKEYS['transient'] = 'transient' + + def withdraw(ex = true) + if ex + tk_call_without_enc('wm', 'withdraw', path) + else + self.deiconify + end + self + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tk/xim.rb b/ruby_1_8_6/ext/tk/lib/tk/xim.rb new file mode 100644 index 0000000000..0ac8559bb9 --- /dev/null +++ b/ruby_1_8_6/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, win = nil) + if value == None + if win + bool(tk_call_without_enc('tk', 'useinputmethods', + '-displayof', win)) + else + bool(tk_call_without_enc('tk', 'useinputmethods')) + end + else + if win + bool(tk_call_without_enc('tk', 'useinputmethods', + '-displayof', win, value)) + else + bool(tk_call_without_enc('tk', 'useinputmethods', value)) + end + end + end + + def TkXIM.useinputmethods_displayof(win, value = None) + TkXIM.useinputmethods(value, win) + end + + def TkXIM.caret(win, keys=nil) + if keys + tk_call_without_enc('tk', 'caret', win, *hash_kv(keys)) + self + else + lst = tk_split_list(tk_call_without_enc('tk', 'caret', win)) + info = {} + while key = lst.shift + info[key[1..-1]] = lst.shift + end + info + end + end + + def TkXIM.configure(win, slot, value=None) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot.kind_of? Hash + tk_call('imconfigure', win, *hash_kv(slot)) + else + tk_call('imconfigure', win, "-#{slot}", value) + end + end + rescue + end + end + + def TkXIM.configinfo(win, 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', win, "-#{slot}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_list(tk_call('imconfigure', win)).collect{|conf| + conf[0] = conf[0][1..-1] + conf + } + end + else + [] + end + rescue + [] + end + else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY + TkXIM.current_configinfo(win, slot) + end + end + + def TkXIM.current_configinfo(win, slot=nil) + begin + if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK + if slot + conf = tk_split_list(tk_call('imconfigure', win, "-#{slot}")) + { conf[0][1..-1] => conf[1] } + else + ret = {} + tk_split_list(tk_call('imconfigure', win)).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/ruby_1_8_6/ext/tk/lib/tkafter.rb b/ruby_1_8_6/ext/tk/lib/tkafter.rb new file mode 100644 index 0000000000..f65945884c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkafter.rb @@ -0,0 +1,4 @@ +# +# tkafter.rb - load tk/after.rb +# +require 'tk/timer' diff --git a/ruby_1_8_6/ext/tk/lib/tkbgerror.rb b/ruby_1_8_6/ext/tk/lib/tkbgerror.rb new file mode 100644 index 0000000000..deba7a57fa --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkbgerror.rb @@ -0,0 +1,4 @@ +# +# tkbgerror.rb - load tk/bgerror.rb +# +require 'tk/bgerror' diff --git a/ruby_1_8_6/ext/tk/lib/tkcanvas.rb b/ruby_1_8_6/ext/tk/lib/tkcanvas.rb new file mode 100644 index 0000000000..9524614291 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkcanvas.rb @@ -0,0 +1,4 @@ +# +# tkcanvas.rb - load tk/canvas.rb +# +require 'tk/canvas' diff --git a/ruby_1_8_6/ext/tk/lib/tkclass.rb b/ruby_1_8_6/ext/tk/lib/tkclass.rb new file mode 100644 index 0000000000..87f5acc453 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkclass.rb @@ -0,0 +1,47 @@ +# +# tkclass.rb - Tk classes +# Date: 2000/11/27 09:23:36 +# by Yukihiro Matsumoto <matz@caelum.co.jp> +# +# $Id$ + +require "tk" + +TopLevel = TkToplevel +Frame = TkFrame +Label = TkLabel +Button = TkButton +Radiobutton = TkRadioButton +Checkbutton = TkCheckButton +Message = TkMessage +Entry = TkEntry +Spinbox = TkSpinbox +Text = TkText +Scale = TkScale +Scrollbar = TkScrollbar +Listbox = TkListbox +Menu = TkMenu +Menubutton = TkMenubutton +Canvas = TkCanvas +Arc = TkcArc +Bitmap = TkcBitmap +Line = TkcLine +Oval = TkcOval +Polygon = TkcPolygon +Rectangle = TkcRectangle +TextItem = TkcText +WindowItem = TkcWindow +BitmapImage = TkBitmapImage +PhotoImage = TkPhotoImage +Selection = TkSelection +Winfo = TkWinfo +Pack = TkPack +Grid = TkGrid +Place = TkPlace +Variable = TkVariable +Font = TkFont +VirtualEvent = TkVirtualEvent + +def Mainloop + Tk.mainloop +end diff --git a/ruby_1_8_6/ext/tk/lib/tkconsole.rb b/ruby_1_8_6/ext/tk/lib/tkconsole.rb new file mode 100644 index 0000000000..9960ddb8ac --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkconsole.rb @@ -0,0 +1,4 @@ +# +# tkconsole.rb - load tk/console.rb +# +require 'tk/console' diff --git a/ruby_1_8_6/ext/tk/lib/tkdialog.rb b/ruby_1_8_6/ext/tk/lib/tkdialog.rb new file mode 100644 index 0000000000..bec5e5d29a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkdialog.rb @@ -0,0 +1,4 @@ +# +# tkdialog.rb - load tk/dialog.rb +# +require 'tk/dialog' diff --git a/ruby_1_8_6/ext/tk/lib/tkentry.rb b/ruby_1_8_6/ext/tk/lib/tkentry.rb new file mode 100644 index 0000000000..2dcfcab5da --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkentry.rb @@ -0,0 +1,4 @@ +# +# tkentry.rb - load tk/entry.rb +# +require 'tk/entry' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS.rb new file mode 100644 index 0000000000..18d84c05e9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS.rb @@ -0,0 +1,13 @@ +# +# ICONS support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/ICONS/setup.rb' + +# load library +require 'tkextlib/ICONS/icons' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS/icons.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS/icons.rb new file mode 100644 index 0000000000..b430bae55d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS/icons.rb @@ -0,0 +1,129 @@ +# +# tkextlib/ICONS/icons.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/ICONS/setup.rb' + +# TkPackage.require('icons', '1.0') +TkPackage.require('icons') + +module Tk + class ICONS < TkImage + extend Tk + + PACKAGE_NAME = 'icons'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('icons') + rescue + '' + end + end + + def self.create(*args) # icon, icon, ..., ?option=>value, ...? + if args[-1].kind_of?(Hash) + keys = args.pop + icons = simplelist(tk_call('::icons::icons', 'create', + *(hash_kv(keys) << (args.flatten)))) + else + icons = simplelist(tk_call('::icons::icons', 'create', + args.flatten)) + end + + icons.collect{|icon| self.new(icon, :without_creating=>true)} + end + + def self.delete(*icons) # icon, icon, ... + icons = icons.flatten + return if icons.empty? + icons.map!{|icon| + if icon.kind_of?(Tk::ICONS) + Tk_IMGTBL.delete(icon.path) + icon.name + elsif icon.to_s =~ /^::icon::(.*)/ + name = $1 + Tk_IMGTBL.delete(icon) + name + else + Tk_IMGTBL.delete("::icon::#{icon}") + icon + end + } + tk_call('::icons::icons', 'delete', icons) + end + + def self.query(*args) # icon, icon, ..., ?option=>value, ...? + if args[-1].kind_of?(Hash) + keys = args.pop + simplelist(tk_call('::icons::icons', 'query', + *(hash_kv(keys) << (args.flatten)))) + else + simplelist(tk_call('::icons::icons', 'query', args.flatten)) + end . map{|inf| list(inf) } + end + + ########################################## + + class << self + alias _new new + + def new(name, keys=nil) + if obj = Tk_IMGTBL["::icon::#{name}"] + if keys + keys = _symbolkey2str(keys) + unless keys.delete('without_creating') + tk_call('::icons::icons', 'create', *(hash_kv(keys) << obj.name)) + end + end + else + obj = _new(name, keys) + end + obj + end + end + + ########################################## + + def initialize(name, keys=nil) + if name.kind_of?(String) && name =~ /^::icon::(.+)$/ + @name = $1 + @path = name + else + @name = name.to_s + @path = "::icon::#{@name}" + end + keys = _symbolkey2str(keys) + unless keys.delete('without_creating') + tk_call('::icons::icons', 'create', *(hash_kv(keys) << @name)) + end + Tk_IMGTBL[@path] = self + end + + def name + @name + end + + def delete + Tk_IMGTBL.delete(@path) + tk_call('::icons::icons', 'delete', @name) + self + end + + def query(keys={}) + list(simplelist(tk_call('::icons::icons', 'query', + *(hash_kv(keys) << @name)) + )[0]) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/ICONS/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/SUPPORT_STATUS b/ruby_1_8_6/ext/tk/lib/tkextlib/SUPPORT_STATUS new file mode 100644 index 0000000000..15925cba72 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/SUPPORT_STATUS @@ -0,0 +1,196 @@ + + [ current support status of Tcl/Tk extensions ] + + *** RELEASE_DATE of the libraries => see 'tkextlib/version.rb' *** + +The following list shows *CURRENT* status when this file was modifyed +at last. If you want to add other Tcl/Tk extensions to the planed list +(or change its status position), please request them at the ruby-talk, +ruby-list, or ruby-dev ML. Although we cannot promise to support your +requests, we'll try to do. + +If you want to check that wrapper libraries are ready to use on your +environment, please execute 'pkg_checker.rb' with no arguments. The +script may give you some hints about that. + + + ***** IMPORTANT NOTE ********************************************** + + 'support' means that Ruby/Tk's wrapper libraries are released. + 'not support' does *NOT* mean that the extension doesn't work + on Ruby/Tk. + + The version number of each extension means the latest version + which is checked its feature. That is, it does NOT means only + version of working. Library files maybe include some features + which is included in the former version but removed from the + latest, and maybe able to support the later version then the + shown version. + + Even if the status of the extension is 'not support', you can + control the functions/widgets of the extension without wrapper + libraries by Tk.tk_call(), Tk.ip_eval(), and so on. + + If you cannot use installed Tcl/Tk extension, please check the + followings. + + (1) On your Tcl/Tk, does the extention work? + + (2) Do DLL libraries of the extension exist on DLL load-path? + (See also "<ruby archive>/ext/tcltklib/README.ActiveTcl") + + (3) Is the Tcl library directory of the extension included in + library search-path of the Tcl interpreter linked Ruby/Tk? + + The check results may request you to do some setup operations + before using the extension. If so, then please write the step + of setup oprations into the "setup.rb" file in the directory + of the wrapper libraries for the extention (It is the wrapper + libraries have the standard structure of the libraries in this + directory). The "setup" file is required before requiring the + Tcl library package (TkPackage.require(<libname>)). + + ******************************************************************* + + +===< support with some examples (may be beta quality) >======================= + +Tcllib 1.8 +Tklib 0.4.1 http://sourceforge.net/projects/tcllib ==> tcllib + +IWidgets 4.0.2 http://sourceforge.net/projects/incrtcl ==> iwidgets + +BWidgets 1.7 http://sourceforge.net/projects/tcllib ==> bwidget + +TkTable 2.9 http://sourceforge.net/projects/tktable ==> tktable + * see also <http://www.korus.hu/~fery/ruby/tktable.rb> + written by Ferenc Engard (ferenc@engard.hu) + +vu 2.3.0 http://sourceforge.net/projects/tktable ==> vu + +TkHTML 2.0 http://www.hwaci.com/sw/tkhtml/ ==> tkHTML + +ICONS 1.0 http://www.satisoft.com/tcltk/icons/ ==> ICONS + +TkImg 1.3 http://sourceforge.net/projects/tkimg ==> tkimg + + +BLT 2.4z http://sourceforge.net/projects/blt + * see also tcltk-ext library on RAA + (http://raa.ruby-lang.org/) + ==> blt + +TkTreeCtrl CVS/Hd(2005-12-02) + http://sourceforge.net/projects/tktreectrl ==> treectrl + +Tile 0.7.8 + http://sourceforge.net/projects/tktable ==> tile + + + +===< support (may be alpha or beta quality) >================================= + +IncrTcl CVS/Hd(2005-02-14) + http://sourceforge.net/projects/incrtcl ==> itcl, itk + +TclX CVS/Hd(2005-02-07) + http://sourceforge.net/projects/tclx + ==> tclx (partial support; infox command and + XPG/3 message catalogs only) + +Trofs 0.4.3 http://math.nist.gov/~DPorter/tcltk/trofs/ + + + +===< possibly available (not tested; alpha quality) >========================= + +winico 0.6 + http://sourceforge.net/projects/tktable + ==> winico (win32 only) + +TkTrans latest(2004-10-11) + http://www2.cmp.uea.ac.uk/~fuzz/tktrans/default.html + ==> tktrans (win32 only) + +TkDND 1.0a2 http://sourceforge.net/projects/tkdnd ==> tkDND + + + +===< plan to support (alpha quality libraries may be included) >============== + +GraphViz *** http://www.graphviz.org/ + +Tkgeomap *** http://tkgeomap.sourceforge.net/index.html + + + +===< not determined to supprt or not >======================================== + +Tix *** http://tixlibrary.sourceforge.net/ + * see also tcltk-ext library on RAA + (http://raa.ruby-lang.org/) + +TkZinc *** http://www.tkzinc.org/ + +Wbc *** http://home.t-online.de/home/csaba.nemethi/ + +Mentry *** http://home.t-online.de/home/csaba.nemethi/ + +Tablelist *** http://home.t-online.de/home/csaba.nemethi/ + +ANIGIF *** http://cardtable.sourceforge.net/tcltk/ + +IMG_ROTATE *** http://cardtable.sourceforge.net/tcltk/ + +TclVfs *** http://sourceforge.net/projects/tclvfs/ + +vfwtcl *** http://sourceforge.net/projects/avicaptcl + * Win32 only + +multicast *** http://sourceforge.net/projects/avicaptcl + * Win32 only + +XBit *** http://www.geocities.com/~chengye/ + * current implementation is for Windows only + +QuickTimeTcl *** http://hem.fyristorg.com/matben/qt/ + * works under Mac OS (8,9,X) or Windows + + + +===< may not support (already exist, out of Ruby/Tk scope, and so on) >======= + +TkCon *** http://sourceforge.net/projects/tkcon + +Expect *** http://sourceforge.net/projects/expect + +TclXML *** http://sourceforge.net/projects/tclxml + +TclXSLT *** http://sourceforge.net/projects/tclxml + +TclDOM *** http://sourceforge.net/projects/tclxml + +TclSOAP *** http://sourceforge.net/projects/tclsoap + +Snack *** http://www.speech.kth.se/~kare/snack2.2.tar.gz + * use Snack for Ruby + (see http://rbsnack.sourceforge.net/) + +Tcom *** http://www.vex.net/~cthuang/tcom/ + +tDOM *** http://www.tdom.org + +Mk4tcl *** http://www.equi4.com/metakit/tcl.html + +Memchan *** http://sourceforge.net/projects/memchan + +XOTcl *** http://www.xotcl.org/ + + +===< tool (may not supprt) >================================================== + +tbcload/tclcompiler + *** http://www.tcl.tk/software/tclpro/ + + +(End of List) diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt.rb new file mode 100644 index 0000000000..115eb927ba --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt.rb @@ -0,0 +1,187 @@ +# +# BLT support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/variable' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/blt/setup.rb' + +# load all image format handlers +#TkPackage.require('BLT', '2.4') +TkPackage.require('BLT') + +module Tk + module BLT + TkComm::TkExtlibAutoloadModule.unshift(self) + + extend TkCore + + VERSION = tk_call('set', 'blt_version') + PATCH_LEVEL = tk_call('set', 'blt_patchLevel') + + begin + lib = INTERP._invoke('set', 'blt_library') + rescue + lib = '' + end + LIBRARY = TkVarAccess.new('blt_library', lib) + + begin + lib = INTERP._invoke('set', 'blt_libPath') + rescue + lib = '' + end + LIB_PATH = TkVarAccess.new('blt_libPath', lib) + + PACKAGE_NAME = 'BLT'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('BLT') + rescue + '' + end + end + + #################################################### + + def self.beep(percent = 50) + tk_call('::blt::beep', percent) + end + + def self.bgexec(*args) + if args[0].kind_of?(TkVariable) + var = args.shift + else + var = TkVariable.new + end + params = [var] + + params.concat(hash_kv(args.shift, true)) if args[0].kind_of?(Hash) + + params << '--' if args[0] =~ /^\s*-[^-]/ + params.concat(args) + + tk_call('::blt::bgexec', *params) + var + end + + def self.detach_bgexec(*args) + if args[0].kind_of?(TkVariable) + var = args.shift + else + var = TkVariable.new + end + params = [var] + + params.concat(hash_kv(args.shift, true)) if args[0].kind_of?(Hash) + + params << '--' if args[0] =~ /^\s*-[^-]/ + params.concat(args) + params << '&' + + [var, tk_split_list(tk_call('::blt::bgexec', *params))] + end + + def self.bltdebug(lvl = nil) + if lvl + tk_call('::blt::bltdebug', lvl) + else + number(tk_call('::blt::bltdebug')) + end + end + + def self.crc32_file(name) + tk_call_without_enc('::blt::crc32', name) + end + def self.crc32_data(dat) + tk_call_without_enc('::blt::crc32', '-data', dat) + end + + #################################################### + + def self.active_legend(graph) + tk_call_without_enc('Blt_ActiveLegend', graph) + end + def self.crosshairs(graph) + tk_call_without_enc('Blt_Crosshairs', graph) + end + def self.zoom_stack(graph) + tk_call_without_enc('Blt_ZoomStack', graph) + end + def self.print_key(graph) + tk_call_without_enc('Blt_PrintKey', graph) + end + def self.closest_point(graph) + tk_call_without_enc('Blt_ClosestPoint', graph) + end + + module GraphCommand + def active_legend + tk_call_without_enc('Blt_ActiveLegend', @path) + self + end + def crosshairs + tk_call_without_enc('Blt_Crosshairs', @path) + self + end + def zoom_stack + tk_call_without_enc('Blt_ZoomStack', @path) + self + end + def print_key + tk_call_without_enc('Blt_PrintKey', @path) + self + end + def closest_point + tk_call_without_enc('Blt_ClosestPoint', @path) + self + end + end + + #################################################### + + autoload :PlotComponent,'tkextlib/blt/component.rb' + + autoload :Barchart, 'tkextlib/blt/barchart.rb' + autoload :Bitmap, 'tkextlib/blt/bitmap.rb' + autoload :Busy, 'tkextlib/blt/busy.rb' + autoload :Container, 'tkextlib/blt/container.rb' + autoload :CutBuffer, 'tkextlib/blt/cutbuffer.rb' + autoload :DragDrop, 'tkextlib/blt/dragdrop.rb' + autoload :EPS, 'tkextlib/blt/eps.rb' + autoload :Htext, 'tkextlib/blt/htext.rb' + autoload :Graph, 'tkextlib/blt/graph.rb' + autoload :Spline, 'tkextlib/blt/spline.rb' + autoload :Stripchart, 'tkextlib/blt/stripchart.rb' + autoload :Table, 'tkextlib/blt/table.rb' + autoload :Tabnotebook, 'tkextlib/blt/tabnotebook.rb' + autoload :Tabset, 'tkextlib/blt/tabset.rb' + autoload :Ted, 'tkextlib/blt/ted.rb' + autoload :Tile, 'tkextlib/blt/tile.rb' + autoload :Tree, 'tkextlib/blt/tree.rb' + autoload :TreeView, 'tkextlib/blt/treeview.rb' + autoload :Hiertable, 'tkextlib/blt/treeview.rb' + # Hierbox is obsolete + autoload :Vector, 'tkextlib/blt/vector.rb' + autoload :VectorAccess, 'tkextlib/blt/vector.rb' + autoload :Watch, 'tkextlib/blt/watch.rb' + autoload :Winop, 'tkextlib/blt/winop.rb' + autoload :WinOp, 'tkextlib/blt/winop.rb' + + # Unix only + autoload :DnD, 'tkextlib/blt/unix_dnd.rb' + + # Windows only + autoload :Printer, 'tkextlib/blt/win_printer.rb' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/barchart.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/barchart.rb new file mode 100644 index 0000000000..cb481c5889 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/barchart.rb @@ -0,0 +1,79 @@ +# +# tkextlib/blt/barchart.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' +require 'tkextlib/blt/component.rb' + +module Tk::BLT + class Barchart < TkWindow + TkCommandNames = ['::blt::barchart'.freeze].freeze + WidgetClassName = 'Barchart'.freeze + WidgetClassNames[WidgetClassName] = self + + include PlotComponent + include GraphCommand + + def __boolval_optkeys + ['bufferelements', 'buffergraph', 'invertxy'] + end + private :__boolval_optkeys + + def __strval_optkeys + ['text', 'label', 'title', 'file', + 'background', 'plotbackground'] + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'colormap' << 'fontmap' + end + private :__tkvariable_optkeys + +=begin + BarElement_ID = ['blt_barchart_bar'.freeze, '00000'.taint].freeze + + def bar(elem=nil, keys={}) + if elem.kind_of?(Hash) + keys = elem + elem = nil + end + unless elem + elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze + BarElement_ID[1].succ! + end + tk_send('bar', elem, keys) + Element.new(self, elem, :without_creating=>true) + end +=end + + def extents(item) + num_or_str(tk_send_without_enc('extents', item)) + end + + def invtransform(x, y) + list(tk_send_without_enc('invtransform', x, y)) + end + + def inside(x, y) + bool(tk_send_without_enc('inside', x, y)) + end + + def metafile(file=None) + # Windows only + tk_send('metafile', file) + self + end + + def snap(output, keys={}) + tk_send_without_enc('snap', *(hash_kv(keys, false) + output)) + self + end + + def transform(x, y) + list(tk_send_without_enc('transform', x, y)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/bitmap.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/bitmap.rb new file mode 100644 index 0000000000..31cf8d4229 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/bitmap.rb @@ -0,0 +1,99 @@ +# +# tkextlib/blt/bitmap.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Bitmap < TkObject + extend TkCore + + TkCommandNames = ['::blt::bitmap'.freeze].freeze + + BITMAP_ID_TBL = TkCore::INTERP.create_table + BITMAP_ID = ['blt_bitmap_id'.freeze, '00000'.taint].freeze + + def self.data(name) + dat = tk_simple_list(tk_call('::blt::bitmap', 'data', name)) + [ tk_split_list(dat[0]), tk_simple_list(dat[1]) ] + end + + def self.exist?(name) + bool(tk_call('::blt::bitmap', 'exists', name)) + end + + def self.height(name) + number(tk_call('::blt::bitmap', 'height', name)) + end + + def self.width(name) + number(tk_call('::blt::bitmap', 'width', name)) + end + + def self.source(name) + tk_simple_list(tk_call('::blt::bitmap', 'source', name)) + end + + ################################# + + class << self + alias _new new + + def new(data, keys={}) + _new(:data, nil, data, keys) + end + alias define new + + def new_with_name(name, data, keys={}) + _new(:data, name, data, keys) + end + alias define_with_name new_with_name + + def compose(text, keys={}) + _new(:text, nil, text, keys) + end + + def compose_with_name(name, text, keys={}) + _new(:text, name, text, keys) + end + end + + def initialize(type, name, data, keys = {}) + if name + @id = name + else + @id = BITMAP_ID.join(TkCore::INTERP._ip_id_) + BITMAP_ID[1].succ! + BITMAP_ID_TBL[@id] = self + end + + @path = @id + + unless bool(tk_call('::blt::bitmap', 'exists', @id)) + if type == :text + tk_call('::blt::bitmap', 'compose', @id, data, *hash_kv(keys)) + else # :data + tk_call('::blt::bitmap', 'define', @id, data, *hash_kv(keys)) + end + end + end + + def exist? + bool(tk_call('::blt::bitmap', 'exists', @id)) + end + + def height + number(tk_call('::blt::bitmap', 'height', @id)) + end + + def width + number(tk_call('::blt::bitmap', 'width', @id)) + end + + def source + tk_simple_list(tk_call('::blt::bitmap', 'source', @id)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/busy.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/busy.rb new file mode 100644 index 0000000000..4726e466f4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/busy.rb @@ -0,0 +1,82 @@ +# +# tkextlib/blt/busy.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/itemconfig.rb' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Busy + extend TkCore + extend TkItemConfigMethod + + TkCommandNames = ['::blt::busy'.freeze].freeze + + ########################### + + class Shield < TkWindow + def self.shield_path(win) + win = window(win) unless win.kind_of?(TkWindow) + if win.kind_of?(TkToplevel) + win.path + '._Busy' + else + win.path + '_Busy' + end + end + + def initialize(win) + @path = self.class.shield_path(win) + end + end + + def self.shield_path(win) + Tk::BLT::Busy::Shield.shield_path(win) + end + end +end + +class << Tk::BLT::Busy + def __item_config_cmd(win) + ['::blt::busy', 'configure', win] + end + private :__item_config_cmd + + undef itemcget + alias configure itemconfigure + alias configinfo itemconfiginfo + alias current_configinfo current_itemconfiginfo + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo + + ################################## + + def hold(win, keys={}) + tk_call('::blt::busy', 'hold', win, *hash_kv(keys)) + end + + def release(*wins) + tk_call('::blt::busy', 'release', *wins) + end + + def forget(*wins) + tk_call('::blt::busy', 'forget', *wins) + end + + def is_busy(pat=None) + tk_split_list(tk_call('::blt::busy', 'isbusy', pat)) + end + + def names(pat=None) + tk_split_list(tk_call('::blt::busy', 'names', pat)) + end + alias windows names + + def check(win) + bool(tk_call('::blt::busy', 'check', win)) + end + + def status(win) + bool(tk_call('::blt::busy', 'status', win)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/component.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/component.rb new file mode 100644 index 0000000000..ad78a5430b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/component.rb @@ -0,0 +1,1835 @@ +# +# tkextlib/blt/component.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module PlotComponent + include TkItemConfigMethod + + module OptKeys + def __item_font_optkeys(id) + ['font', 'tickfont', 'titlefont'] + end + private :__item_font_optkeys + + def __item_numstrval_optkeys(id) + ['xoffset', 'yoffset'] + end + private :__item_numstrval_optkeys + + def __item_boolval_optkeys(id) + ['hide', 'under', 'descending', 'logscale', 'loose', 'showticks', + 'titlealternate', 'scalesymbols', 'minor', 'raised', + 'center', 'decoration', 'landscape', 'maxpect'] + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + ['text', 'label', 'limits', 'title', + 'show', 'file', 'maskdata', 'maskfile', + 'color', 'titlecolor', 'fill', 'outline', 'offdash'] + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + ['bindtags'] + end + private :__item_listval_optkeys + + def __item_numlistval_optkeys(id) + ['dashes', 'majorticks', 'minorticks'] + end + private :__item_numlistval_optkeys + + def __item_tkvariable_optkeys(id) + ['variable', 'textvariable', 'colormap', 'fontmap'] + end + private :__item_tkvariable_optkeys + end + + include OptKeys + + def __item_cget_cmd(id) + if id.kind_of?(Array) + # id := [ type, name ] + [self.path, id[0], 'cget', id[1]] + else + [self.path, id, 'cget'] + end + end + private :__item_cget_cmd + + def __item_config_cmd(id) + if id.kind_of?(Array) + # id := [ type, name, ... ] + type, *names = id + [self.path, type, 'configure'].concat(names) + else + [self.path, id, 'configure'] + end + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + id = tagid(id[1]) + end + [self.path, id].join(';') + end + private :__item_pathname + + def axis_cget(id, option) + ret = itemcget(['axis', tagid(id)], option) + end + def axis_configure(*args) + slot = args.pop + if slot.kind_of?(Hash) + value = None + slot = _symbolkey2str(slot) + if cmd = slot.delete('command') + slot['command'] = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + else + value = slot + slot = args.pop + if slot == :command || slot == 'command' + cmd = value + value = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + end + id_list = args.flatten.collect!{|id| tagid(id)}.unshift('axis') + itemconfigure(id_list, slot, value) + end + def axis_configinfo(id, slot=nil) + itemconfiginfo(['axis', tagid(id)], slot) + end + def current_axis_configinfo(id, slot=nil) + current_itemconfiginfo(['axis', tagid(id)], slot) + end + + def crosshairs_cget(option) + itemcget('crosshairs', option) + end + def crosshairs_configure(slot, value=None) + itemconfigure('crosshairs', slot, value) + end + def crosshairs_configinfo(slot=nil) + itemconfiginfo('crosshairs', slot) + end + def current_crosshairs_configinfo(slot=nil) + current_itemconfiginfo('crosshairs', slot) + end + + def element_cget(id, option) + itemcget(['element', tagid(id)], option) + end + def element_configure(*args) + slot = args.pop + if slot.kind_of?(Hash) + value = None + else + value = slot + slot = args.pop + end + id_list = args.flatten.collect!{|id| tagid(id)}.unshift('element') + itemconfigure(id_list, slot, value) + end + def element_configinfo(id, slot=nil) + itemconfiginfo(['element', tagid(id)], slot) + end + def current_element_configinfo(id, slot=nil) + current_itemconfiginfo(['element', tagid(id)], slot) + end + + def bar_cget(id, option) + itemcget(['bar', tagid(id)], option) + end + def bar_configure(*args) + slot = args.pop + if slot.kind_of?(Hash) + value = None + else + value = slot + slot = args.pop + end + id_list = args.flatten.collect!{|id| tagid(id)}.unshift('bar') + itemconfigure(id_list, slot, value) + end + def bar_configinfo(id, slot=nil) + itemconfiginfo(['bar', tagid(id)], slot) + end + def current_bar_configinfo(id, slot=nil) + current_itemconfiginfo(['bar', tagid(id)], slot) + end + + def line_cget(id, option) + itemcget(['line', tagid(id)], option) + end + def line_configure(*args) + slot = args.pop + if slot.kind_of?(Hash) + value = None + else + value = slot + slot = args.pop + end + id_list = args.flatten.collect!{|id| tagid(id)}.unshift('line') + itemconfigure(id_list, slot, value) + end + def line_configinfo(id, slot=nil) + itemconfiginfo(['line', tagid(id)], slot) + end + def current_line_configinfo(id, slot=nil) + current_itemconfiginfo(['line', tagid(id)], slot) + end + + def gridline_cget(option) + itemcget('grid', option) + end + def gridline_configure(slot, value=None) + itemconfigure('grid', slot, value) + end + def gridline_configinfo(slot=nil) + itemconfiginfo('grid', slot) + end + def current_gridline_configinfo(slot=nil) + current_itemconfiginfo('grid', slot) + end + + def legend_cget(option) + itemcget('legend', option) + end + def legend_configure(slot, value=None) + itemconfigure('legend', slot, value) + end + def legend_configinfo(slot=nil) + itemconfiginfo('legend', slot) + end + def current_legend_configinfo(slot=nil) + current_itemconfiginfo('legend', slot) + end + + def pen_cget(id, option) + itemcget(['pen', tagid(id)], option) + end + def pen_configure(*args) + slot = args.pop + if slot.kind_of?(Hash) + value = None + else + value = slot + slot = args.pop + end + id_list = args.flatten.collect!{|id| tagid(id)}.unshift('pen') + itemconfigure(id_list, slot, value) + end + def pen_configinfo(id, slot=nil) + itemconfiginfo(['pen', tagid(id)], slot) + end + def current_pen_configinfo(id, slot=nil) + current_itemconfiginfo(['pen', tagid(id)], slot) + end + + def postscript_cget(option) + itemcget('postscript', option) + end + def postscript_configure(slot, value=None) + itemconfigure('postscript', slot, value) + end + def postscript_configinfo(slot=nil) + itemconfiginfo('postscript', slot) + end + def current_postscript_configinfo(slot=nil) + current_itemconfiginfo('postscript', slot) + end + + def marker_cget(id, option) + itemcget(['marker', tagid(id)], option) + end + def marker_configure(*args) + slot = args.pop + if slot.kind_of?(Hash) + value = None + else + value = slot + slot = args.pop + end + id_list = args.flatten.collect!{|id| tagid(id)}.unshift('marker') + itemconfigure(id_list, slot, value) + end + def marker_configinfo(id, slot=nil) + itemconfiginfo(['marker', tagid(id)], slot) + end + def current_marker_configinfo(id, slot=nil) + current_itemconfiginfo(['marker', tagid(id)], slot) + end + + alias __itemcget itemcget + alias __itemconfiginfo itemconfiginfo + alias __current_itemconfiginfo current_itemconfiginfo + private :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo + + def itemcget(tagOrId, option) + ret = __itemcget(tagid(tagOrId), option) + if option == 'bindtags' || option == :bindtags + ret.collect{|tag| TkBindTag.id2obj(tag)} + else + ret + end + end + def itemconfiginfo(tagOrId, slot = nil) + ret = __itemconfiginfo(tagid(tagOrId), slot) + + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + if slot == 'bindtags' || slot == :bindtags + ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)} + ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)} + end + else + if (inf = ret.assoc('bindtags')) + inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)} + inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)} + end + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if (inf = ret['bindtags']) + inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)} + inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)} + ret['bindtags'] = inf + end + end + + ret + end + def current_itemconfiginfo(tagOrId, slot = nil) + ret = __current_itemconfiginfo(tagid(tagOrId), slot) + + if (val = ret['bindtags']) + ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)} + end + + ret + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + ################# + + class Axis < TkObject + OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint].freeze + OBJ_TBL={} + + def self.id2obj(chart, id) + cpath = chart.path + return id unless OBJ_TBL[cpath] + OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id + end + + def self.new(chart, axis=nil, keys={}) + if axis.kind_of?(Hash) + keys = axis + axis = nil + end + OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] + return OBJ_TBL[chart.path][axis] if axis && OBJ_TBL[chart.path][axis] + super(chart, axis, keys) + end + + def initialize(chart, axis=nil, keys={}) + if axis.kind_of?(Hash) + keys = axis + axis = nil + end + if axis + @axis = @id = axis.to_s + else + @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze + OBJ_ID[1].succ! + end + @path = @id + @parent = @chart = chart + @cpath = @chart.path + Axis::OBJ_TBL[@cpath][@axis] = self + keys = _symbolkey2str(keys) + unless keys.delete('without_creating') + # @chart.axis_create(@axis, keys) + tk_call(@chart, 'axis', 'create', @axis, keys) + end + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.axis_cget(@id, option) + end + def configure(key, value=None) + @chart.axis_configure(@id, key, value) + self + end + def configinfo(key=nil) + @chart.axis_configinfo(@id, key) + end + def current_configinfo(key=nil) + @chart.current_axis_configinfo(@id, key) + end + + def command(cmd=nil, &b) + if cmd + configure('command', cmd) + elsif b + configure('command', Proc.new(&b)) + else + cget('command') + end + end + + def delete + @chart.axis_delete(@id) + self + end + + def invtransform(val) + @chart.axis_invtransform(@id, val) + end + + def limits + @chart.axis_limits(@id) + end + + def name + @axis + end + + def transform(val) + @chart.axis_transform(@id, val) + end + + def view + @chart.axis_view(@id) + self + end + + def use(name=None) # if @id == xaxis | x2axis | yaxis | y2axis + @chart.axis_use(@id, name) + end + + def use_as(axis) # axis := xaxis | x2axis | yaxis | y2axis + @chart.axis_use(axis, @id) + end + end + + ################# + + class Crosshairs < TkObject + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + Crosshairs::OBJ_TBL[@cpath] = self + @chart.crosshair_configure(keys) unless keys.empty? + @path = @id = 'crosshairs' + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.crosshair_cget(option) + end + def configure(key, value=None) + @chart.crosshair_configure(key, value) + self + end + def configinfo(key=nil) + @chart.crosshair_configinfo(key) + end + def current_configinfo(key=nil) + @chart.current_crosshair_configinfo(key) + end + + def off + @chart.crosshair_off + self + end + def on + @chart.crosshair_on + self + end + def toggle + @chart.crosshair_toggle + self + end + end + + ################# + + class Element < TkObject + extend Tk + extend TkItemFontOptkeys + extend TkItemConfigOptkeys + + extend Tk::BLT::PlotComponent::OptKeys + + ElementTypeName = 'element' + ElementTypeToClass = { ElementTypeName=>self } + ElementID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ ElementID_TBL.clear } + + OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint].freeze + OBJ_TBL={} + + def Element.type2class(type) + ElementTypeToClass[type] + end + + def Element.id2obj(chart, id) + cpath = chart.path + return id unless OBJ_TBL[cpath] + OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id + end + + def self.new(chart, element=nil, keys={}) + if element.kind_of?(Hash) + keys = element + element = nil + end + OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] + if element && OBJ_TBL[chart.path][element] + return OBJ_TBL[chart.path][element] + end + super(chart, element, keys) + end + + def initialize(chart, element=nil, keys={}) + if element.kind_of?(Hash) + keys = element + element = nil + end + if element + @element = @id = element.to_s + else + @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze + OBJ_ID[1].succ! + end + @path = @id + @parent = @chart = chart + @cpath = @chart.path + @typename = self.class::ElementTypeName + Element::OBJ_TBL[@cpath][@element] = self + keys = _symbolkey2str(keys) + unless keys.delete('without_creating') + # @chart.element_create(@element, keys) + tk_call(@chart, @typename, 'create', @element, keys) + end + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + # @chart.element_cget(@id, option) + @chart.__send__(@typename + '_cget', @id, option) + end + def configure(key, value=None) + # @chart.element_configure(@id, key, value) + @chart.__send__(@typename + '_configure', @id, key, value) + self + end + def configinfo(key=nil) + # @chart.element_configinfo(@id, key) + @chart.__send__(@typename + '_configinfo', @id, key) + end + def current_configinfo(key=nil) + # @chart.current_element_configinfo(@id, key) + @chart.__send__('current_' << @typename << '_configinfo', @id, key) + end + + def activate(*args) + @chart.element_activate(@id, *args) + end + + def closest(x, y, var, keys={}) + # @chart.element_closest(x, y, var, @id, keys) + @chart.__send__(@typename + '_closest', x, y, var, @id, keys) + end + + def deactivate + @chart.element_deactivate(@id) + self + end + + def delete + @chart.element_delete(@id) + self + end + + def exist? + @chart.element_exist?(@id) + end + + def name + @element + end + + def type + @chart.element_type(@id) + end + end + + class Bar < Element + ElementTypeName = 'bar'.freeze + ElementTypeToClass[ElementTypeName] = self + end + class Line < Element + ElementTypeName = 'line'.freeze + ElementTypeToClass[ElementTypeName] = self + end + + ################# + + class GridLine < TkObject + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + GridLine::OBJ_TBL[@cpath] = self + @chart.gridline_configure(keys) unless keys.empty? + @path = @id = 'grid' + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.gridline_cget(option) + end + def configure(key, value=None) + @chart.gridline_configure(key, value) + self + end + def configinfo(key=nil) + @chart.gridline_configinfo(key) + end + def current_configinfo(key=nil) + @chart.current_gridline_configinfo(key) + end + + def off + @chart.gridline_off + self + end + def on + @chart.gridline_on + self + end + def toggle + @chart.gridline_toggle + self + end + end + + ################# + + class Legend < TkObject + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + Crosshairs::OBJ_TBL[@cpath] = self + @chart.crosshair_configure(keys) unless keys.empty? + @path = @id = 'legend' + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.legend_cget(option) + end + def configure(key, value=None) + @chart.legend_configure(key, value) + self + end + def configinfo(key=nil) + @chart.legend_configinfo(key) + end + def current_configinfo(key=nil) + @chart.current_legend_configinfo(key) + end + + def activate(*args) + @chart.legend_activate(*args) + end + + def deactivate(*args) + @chart.legend_deactivate(*args) + end + + def get(pos, y=nil) + @chart.legend_get(pos, y) + end + end + + ################# + + class Pen < TkObject + OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint].freeze + OBJ_TBL={} + + def self.id2obj(chart, id) + cpath = chart.path + return id unless OBJ_TBL[cpath] + OBJ_TBL[cpath][id]? OBJ_TBL[cpath][id]: id + end + + def self.new(chart, pen=nil, keys={}) + if pen.kind_of?(Hash) + keys = pen + pen = nil + end + OBJ_TBL[chart.path] = {} unless OBJ_TBL[chart.path] + return OBJ_TBL[chart.path][pen] if pen && OBJ_TBL[chart.path][pen] + super(chart, pen, keys) + end + + def initialize(chart, pen=nil, keys={}) + if pen.kind_of?(Hash) + keys = pen + pen = nil + end + if pen + @pen = @id = pen.to_s + else + @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze + OBJ_ID[1].succ! + end + @path = @id + @parent = @chart = chart + @cpath = @chart.path + Pen::OBJ_TBL[@cpath][@pen] = self + keys = _symbolkey2str(keys) + unless keys.delete('without_creating') + # @chart.pen_create(@pen, keys) + tk_call(@chart, 'pen', 'create', @pen, keys) + end + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.pen_cget(@id, option) + end + def configure(key, value=None) + @chart.pen_configure(@id, key, value) + self + end + def configinfo(key=nil) + @chart.pen_configinfo(@id, key) + end + def current_configinfo(key=nil) + @chart.current_pen_configinfo(@id, key) + end + + def delete + @chart.pen_delete(@id) + self + end + + def name + @pen + end + end + + ################# + + class Postscript < TkObject + OBJ_TBL={} + + def self.new(chart, keys={}) + return OBJ_TBL[chart.path] if OBJ_TBL[chart.path] + super(chart, keys) + end + + def initialize(chart, keys={}) + @parent = @chart = chart + @cpath = @chart.path + Postscript::OBJ_TBL[@cpath] = self + @chart.postscript_configure(keys) unless keys.empty? + @path = @id = 'postscript' + end + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.postscript_cget(option) + end + def configure(key, value=None) + @chart.postscript_configure(key, value) + self + end + def configinfo(key=nil) + @chart.postscript_configinfo(key) + end + def current_configinfo(key=nil) + @chart.current_postscript_configinfo(key) + end + + def output(file=nil, keys={}) + if file.kind_of?(Hash) + keys = file + file = nil + end + + ret = @chart.postscript_output(file, keys) + + if file + self + else + ret + end + end + end + + ################# + class Marker < TkObject + extend Tk + extend TkItemFontOptkeys + extend TkItemConfigOptkeys + + extend Tk::BLT::PlotComponent::OptKeys + + MarkerTypeName = nil + MarkerTypeToClass = {} + MarkerID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{ MarkerID_TBL.clear } + + def Marker.type2class(type) + MarkerTypeToClass[type] + end + + def Marker.id2obj(chart, id) + cpath = chart.path + return id unless MarkerID_TBL[cpath] + MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id + end + + def self._parse_create_args(keys) + fontkeys = {} + methodkeys = {} + if keys.kind_of? Hash + keys = _symbolkey2str(keys) + + __item_font_optkeys(nil).each{|key| + fkey = key.to_s + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "kanji#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "latin#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + + fkey = "ascii#{key}" + fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) + } + + __item_methodcall_optkeys(nil).each{|key| + key = key.to_s + methodkeys[key] = keys.delete(key) if keys.key?(key) + } + + __item_ruby2val_optkeys(nil).each{|key, method| + key = key.to_s + keys[key] = method.call(keys[key]) if keys.has_key?(key) + } + + args = itemconfig_hash_kv(nil, keys) + else + args = [] + end + + [args, fontkeys] + end + private_class_method :_parse_create_args + + def self.create(chart, keys={}) + unless self::MarkerTypeName + fail RuntimeError, "#{self} is an abstract class" + end + args, fontkeys = _parse_create_args(keys) + idnum = tk_call_without_enc(chart.path, 'marker', 'create', + self::MarkerTypeName, *args) + chart.marker_configure(idnum, fontkeys) unless fontkeys.empty? + idnum.to_i # 'item id' is an integer number + end + + def self.create_type(chart, type, keys={}) + args, fontkeys = _parse_create_args(keys) + idnum = tk_call_without_enc(chart.path, 'marker', 'create', + type, *args) + chart.marker_configure(idnum, fontkeys) unless fontkeys.empty? + id = idnum.to_i # 'item id' is an integer number + obj = self.allocate + obj.instance_eval{ + @parent = @chart = chart + @cpath = chart.path + @id = id + unless Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] + Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] = {} + end + Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self + } + obj + end + + def initialize(parent, *args) + @parent = @chart = parent + @cpath = parent.path + + @path = @id = create_self(*args) # an integer number as 'item id' + unless Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] + Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] = {} + end + Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self + end + def create_self(*args) + self.class.create(@chart, *args) # return an integer as 'item id' + end + private :create_self + + def id + @id + end + + def to_eval + @id + end + + def cget(option) + @chart.marker_cget(@id, option) + end + def configure(key, value=None) + @chart.marker_configure(@id, key, value) + self + end + def configinfo(key=nil) + @chart.marker_configinfo(@id, key) + end + def current_configinfo(key=nil) + @chart.current_marker_configinfo(@id, key) + end + + def after(target=None) + @chart.marker_after(@id, target) + end + + def before(target=None) + @chart.marker_before(@id, target) + end + + def delete + @chart.marker_delete(@id) + end + + def exist? + @chart.marker_exist(@id) + end + + def type + @chart.marker_type(@id) + end + end + + class TextMarker < Marker + MarkerTypeName = 'text'.freeze + MarkerTypeToClass[MarkerTypeName] = self + end + class LineMarker < Marker + MarkerTypeName = 'line'.freeze + MarkerTypeToClass[MarkerTypeName] = self + end + class BitmapMarker < Marker + MarkerTypeName = 'bitmap'.freeze + MarkerTypeToClass[MarkerTypeName] = self + end + class ImageMarker < Marker + MarkerTypeName = 'image'.freeze + MarkerTypeToClass[MarkerTypeName] = self + end + class PolygonMarker < Marker + MarkerTypeName = 'polygon'.freeze + MarkerTypeToClass[MarkerTypeName] = self + end + class WindowMarker < Marker + MarkerTypeName = 'window'.freeze + MarkerTypeToClass[MarkerTypeName] = self + end + + ################# + + def __destroy_hook__ + Axis::OBJ_TBL.delete(@path) + Crosshairs::OBJ_TBL.delete(@path) + Element::OBJ_TBL.delete(@path) + GridLine::OBJ_TBL.delete(@path) + Legend::OBJ_TBL.delete(@path) + Pen::OBJ_TBL.delete(@path) + Postscript::OBJ_TBL.delete(@path) + Marker::OBJ_TBL.delete(@path) + super() + end + + ################# + + def tagid(tag) + if tag.kind_of?(Axis) || + tag.kind_of?(Crosshairs) || + tag.kind_of?(Element) || + tag.kind_of?(GridLine) || + tag.kind_of?(Legend) || + tag.kind_of?(Pen) || + tag.kind_of?(Postscript) || + tag.kind_of?(Marker) + tag.id + else + tag # maybe an Array of configure paramters + end + end + + def _component_bind(target, tag, context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, target, 'bind', tagid(tag)], context, cmd, *args) + self + end + def _component_bind_append(target, tag, context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, target, 'bind', tagid(tag)], context, cmd, *args) + self + end + def _component_bind_remove(target, tag, context) + _bind_remove([path, target, 'bind', tagid(tag)], context) + self + end + def _component_bindinfo(target, tag, context=nil) + _bindinfo([path, target, 'bind', tagid(tag)], context) + end + private :_component_bind, :_component_bind_append + private :_component_bind_remove, :_component_bindinfo + + def axis_bind(tag, context, *args) + _component_bind('axis', tag, context, *args) + end + def axis_bind_append(tag, context, *args) + _component_bind_append('axis', tag, context, *args) + end + def axis_bind_remove(tag, context) + _component_bind_remove('axis', tag, context) + end + def axis_bindinfo(tag, context=nil) + _component_bindinfo('axis', tag, context) + end + + def element_bind(tag, context, *args) + _component_bind('element', tag, context, *args) + end + def element_bind_append(tag, context, *args) + _component_bind_append('element', tag, context, *args) + end + def element_bind_remove(tag, context) + _component_bind_remove('element', tag, context) + end + def element_bindinfo(tag, context=nil) + _component_bindinfo('element', tag, context) + end + + def bar_bind(tag, context, *args) + _component_bind('bar', tag, context, *args) + end + def bar_bind_append(tag, context, *args) + _component_bind_append('bar', tag, context, *args) + end + def bar_bind_remove(tag, context) + _component_bind_remove('bar', tag, context) + end + def bar_bindinfo(tag, context=nil) + _component_bindinfo('bar', tag, context) + end + + def line_bind(tag, context, *args) + _component_bind('line', tag, context, *args) + end + def line_bind_append(tag, context, *args) + _component_bind_append('line', tag, context, *args) + end + def line_bind_remove(tag, context) + _component_bind_remove('line', tag, context) + end + def line_bindinfo(tag, context=nil) + _component_bindinfo('line', tag, context) + end + + def legend_bind(tag, context, *args) + _component_bind('legend', tag, context, *args) + end + def legend_bind_append(tag, context, *args) + _component_bind_append('legend', tag, context, *args) + end + def legend_bind_remove(tag, context) + _component_bind_remove('legend', tag, context) + end + def legend_bindinfo(tag, context=nil) + _component_bindinfo('legend', tag, context) + end + + def marker_bind(tag, context, *args) + _component_bind('marker', tag, context, *args) + end + def marker_bind_append(tag, context, *args) + _component_bind_append('marker', tag, context, *args) + end + def marker_bind_remove(tag, context) + _component_bind_remove('marker', tag, context) + end + def marker_bindinfo(tag, context=nil) + _component_bindinfo('marker', tag, context) + end + + ################### + + def axis_create(id=nil, keys={}) + # tk_send('axis', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Axis.new(self, tagid(id), keys) + end + def axis_delete(*ids) + tk_send('axis', 'delete', *(ids.collect{|id| tagid(id)})) + self + end + def axis_invtransform(id, val) + list(tk_send('axis', 'invtransform', tagid(id), val)) + end + def axis_limits(id) + list(tk_send('axis', 'limits', tagid(id))) + end + def axis_names(*pats) + simplelist(tk_send('axis', 'names', + *(pats.collect{|pat| tagid(pat)}))).collect{|axis| + Tk::BLT::PlotComponent::Axis.id2obj(self, axis) + } + end + def axis_transform(id, val) + list(tk_send('axis', 'transform', tagid(id), val)) + end + def axis_view(id) + tk_send('axis', 'view', tagid(id)) + self + end + def axis_use(id, target=nil) + if target + Tk::BLT::PlotComponent::Axis.id2obj(self, + tk_send('axis', 'use', + tagid(id), tagid(target))) + else + Tk::BLT::PlotComponent::Axis.id2obj(self, + tk_send('axis', 'use', tagid(id))) + end + end + + ################### + + def crosshairs_off + tk_send_without_enc('crosshairs', 'off') + self + end + def crosshairs_on + tk_send_without_enc('crosshairs', 'on') + self + end + def crosshairs_toggle + tk_send_without_enc('crosshairs', 'toggle') + self + end + + ################### + + def element_create(id=nil, keys={}) + # tk_send('element', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Element.new(self, tagid(id), keys) + end + def element_activate(*args) + if args.empty? + list(tk_send('element', 'activate')).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + else + # id, *indices + id = args.shift + tk_send('element', 'activate', tagid(id), *args) + end + end + def element_closest(x, y, var, *args) + if args[-1].kind_of?(Hash) + keys = args.pop + bool(tk_send('element', 'closest', x, y, var, + *(hash_kv(keys).concat(args.collect{|id| tagid(id)})))) + else + bool(tk_send('element', 'closest', x, y, var, + *(args.collect{|id| tagid(id)}))) + end + end + def element_deactivate(*ids) + tk_send('element', 'deactivate', *(ids.collect{|id| tagid(id)})) + self + end + def element_delete(*ids) + tk_send('element', 'delete', *(ids.collect{|id| tagid(id)})) + self + end + def element_exist?(id) + bool(tk_send('element', 'exists', tagid(id))) + end + def element_names(*pats) + simplelist(tk_send('element', 'names', + *(pats.collect{|pat| tagid(pat)}))).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + end + def element_show(*names) + if names.empty? + simplelist(tk_send('element', 'show')) + else + tk_send('element', 'show', *(names.collect{|n| tagid(n)})) + self + end + end + def element_type(id) + tk_send('element', 'type', tagid(id)) + end + + ################### + + def bar_create(id=nil, keys={}) + # tk_send('bar', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Bar.new(self, tagid(id), keys) + end + alias bar bar_create + def bar_activate(*args) + if args.empty? + list(tk_send('bar', 'activate')).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + else + # id, *indices + id = args.shift + tk_send('bar', 'activate', tagid(id), *args) + end + end + def bar_closest(x, y, var, *args) + if args[-1].kind_of?(Hash) + keys = args.pop + bool(tk_send('bar', 'closest', x, y, var, + *(hash_kv(keys).concat(args.collect{|id| tagid(id)})))) + else + bool(tk_send('bar', 'closest', x, y, var, + *(args.collect{|id| tagid(id)}))) + end + end + def bar_deactivate(*ids) + tk_send('bar', 'deactivate', *(ids.collect{|id| tagid(id)})) + self + end + def bar_delete(*ids) + tk_send('bar', 'delete', *(ids.collect{|id| tagid(id)})) + self + end + def bar_exist?(id) + bool(tk_send('bar', 'exists', tagid(id))) + end + def bar_names(*pats) + simplelist(tk_send('bar', 'names', + *(pats.collect{|pat| tagid(pat)}))).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + end + def bar_show(*names) + if names.empty? + simplelist(tk_send('bar', 'show')) + else + tk_send('bar', 'show', *(names.collect{|n| tagid(n)})) + self + end + end + def bar_type(id) + tk_send('bar', 'type', tagid(id)) + end + + ################### + + def line_create(id=nil, keys={}) + # tk_send('line', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Line.new(self, tagid(id), keys) + end + alias bar line_create + def line_activate(*args) + if args.empty? + list(tk_send('line', 'activate')).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + else + # id, *indices + id = args.shift + tk_send('line', 'activate', tagid(id), *args) + end + end + def line_closest(x, y, var, *args) + if args[-1].kind_of?(Hash) + keys = args.pop + bool(tk_send('line', 'closest', x, y, var, + *(hash_kv(keys).concat(args.collect{|id| tagid(id)})))) + else + bool(tk_send('line', 'closest', x, y, var, + *(args.collect{|id| tagid(id)}))) + end + end + def line_deactivate(*ids) + tk_send('line', 'deactivate', *(ids.collect{|id| tagid(id)})) + self + end + def line_delete(*ids) + tk_send('line', 'delete', *(ids.collect{|id| tagid(id)})) + self + end + def line_exist?(id) + bool(tk_send('line', 'exists', tagid(id))) + end + def line_names(*pats) + simplelist(tk_send('line', 'names', + *(pats.collect{|pat| tagid(pat)}))).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + end + def line_show(*names) + if names.empty? + simplelist(tk_send('line', 'show')) + else + tk_send('line', 'show', *(names.collect{|n| tagid(n)})) + self + end + end + def line_type(id) + tk_send('line', 'type', tagid(id)) + end + + ################### + + def gridline_off + tk_send_without_enc('grid', 'off') + self + end + def gridline_on + tk_send_without_enc('grid', 'on') + self + end + def gridline_toggle + tk_send_without_enc('grid', 'toggle') + self + end + + ################### + + def legend_window_create(parent=nil, keys=nil) + if parent.kind_of?(Hash) + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + widgetname = keys.delete('widgetname') + keys.delete('without_creating') + elsif keys + keys = _symbolkey2str(keys) + widgetname = keys.delete('widgetname') + keys.delete('without_creating') + end + + legend = self.class.new(parent, :without_creating=>true, + :widgetname=>widgetname) + class << legend + def __destroy_hook__ + TkCore::INTERP.tk_windows.delete(@path) + end + end + + if keys + self.legend_configure(keys.update('position'=>legend)) + else + self.legend_configure('position'=>legend) + end + legend + end + + def legend_activate(*pats) + list(tk_send('legend', 'activate', + *(pats.collect{|pat| tagid(pat)}))).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + end + def legend_deactivate(*pats) + list(tk_send('legend', 'deactivate', + *(pats.collect{|pat| tagid(pat)}))).collect{|elem| + Tk::BLT::PlotComponent::Element.id2obj(self, elem) + } + end + def legend_get(pos, y=nil) + if y + Tk::BLT::PlotComponent::Element.id2obj(self, + tk_send('legend', 'get', + _at(pos, y))) + else + Tk::BLT::PlotComponent::Element.id2obj(self, + tk_send('legend', 'get', pos)) + end + end + + ################### + + def pen_create(id=nil, keys={}) + # tk_send('pen', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Pen.new(self, tagid(id), keys) + end + def pen_delete(*ids) + tk_send('pen', 'delete', *(ids.collect{|id| tagid(id)})) + self + end + def pen_names(*pats) + simplelist(tk_send('pen', 'names', + *(pats.collect{|pat| tagid(pat)}))).collect{|pen| + Tk::BLT::PlotComponent::Pen.id2obj(self, pen) + } + end + + ################### + + def postscript_output(file=nil, keys={}) + if file.kind_of?(Hash) + keys = file + file = nil + end + + if file + tk_send('postscript', 'output', file, keys) + self + else + tk_send('postscript', 'output', keys) + end + end + + ################### + + def marker_create(type, keys={}) + case type + when :text, 'text' + Tk::BLT::PlotComponent::TextMarker.new(self, keys) + when :line, 'line' + Tk::BLT::PlotComponent::LineMarker.new(self, keys) + when :bitmap, 'bitmap' + Tk::BLT::PlotComponent::BitmapMarker.new(self, keys) + when :image, 'image' + Tk::BLT::PlotComponent::ImageMarker.new(self, keys) + when :polygon, 'polygon' + Tk::BLT::PlotComponent::PolygonMarker.new(self, keys) + when :window, 'window' + Tk::BLT::PlotComponent::WindowMarker.new(self, keys) + else + if type.kind_of?(Tk::BLT::PlotComponent::Marker) + type.new(self, keys) + else + Tk::BLT::PlotComponent::Marker.create_type(self, type, keys) + end + end + end + def marker_after(id, target=nil) + if target + tk_send_without_enc('marker', 'after', tagid(id), tagid(target)) + else + tk_send_without_enc('marker', 'after', tagid(id)) + end + self + end + def marker_before(id, target=None) + if target + tk_send_without_enc('marker', 'before', tagid(id), tagid(target)) + else + tk_send_without_enc('marker', 'before', tagid(id)) + end + self + end + def marker_delete(*ids) + tk_send('marker', 'delete', *(ids.collect{|id| tagid(id)})) + self + end + def marker_exist?(id) + bool(tk_send('marker', 'exists', tagid(id))) + end + def marker_names(*pats) + simplelist(tk_send('marker', 'names', + *(pats.collect{|pat| tagid(pat)}))).collect{|id| + Tk::BLT::PlotComponent::Marker.id2obj(self, id) + } + end + def marker_type(id) + tk_send('marker', 'type', tagid(id)) + end + + ################### + + def xaxis_cget(option) + itemcget('xaxis', option) + end + def xaxis_configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + if cmd = slot.delete('command') + slot['command'] = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + elsif slot == :command || slot == 'command' + cmd = value + value = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + itemconfigure('xaxis', slot, value) + end + def xaxis_configinfo(slot=nil) + itemconfiginfo('xaxis', slot) + end + def current_xaxis_configinfo(slot=nil) + current_itemconfiginfo('xaxis', slot) + end + def xaxis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'xaxis', 'bind'], context, cmd, *args) + self + end + def xaxis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'xaxis', 'bind'], context, cmd, *args) + self + end + def xaxis_bind_remove(context) + _bind_remove([path, 'xaxis', 'bind'], context) + self + end + def xaxis_bindinfo(context=nil) + _bindinfo([path, 'xaxis', 'bind'], context) + end + def xaxis_invtransform(val) + list(tk_send('xaxis', 'invtransform', val)) + end + def xaxis_limits + list(tk_send('xaxis', 'limits')) + end + def xaxis_transform(val) + list(tk_send('xaxis', 'transform', val)) + end + def xaxis_use(target=nil) + if target + Tk::BLT::PlotComponent::Axis.id2obj(self, + tk_send('xaxis', 'use', + tagid(target))) + else + Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('xaxis', 'use')) + end + end + + def x2axis_cget(option) + itemcget('x2axis', option) + end + def x2axis_configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + if cmd = slot.delete('command') + slot['command'] = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + elsif slot == :command || slot == 'command' + cmd = value + value = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + itemconfigure('x2axis', slot, value) + end + def x2axis_configinfo(slot=nil) + itemconfiginfo('x2axis', slot) + end + def current_x2axis_configinfo(slot=nil) + current_itemconfiginfo('x2axis', slot) + end + def x2axis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'x2axis', 'bind'], context, cmd, *args) + self + end + def x2axis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'x2axis', 'bind'], context, cmd, *args) + self + end + def x2axis_bind_remove(context) + _bind_remove([path, 'x2axis', 'bind'], context) + self + end + def x2axis_bindinfo(context=nil) + _bindinfo([path, 'x2axis', 'bind'], context) + end + def x2axis_invtransform(val) + list(tk_send('x2axis', 'invtransform', val)) + end + def x2axis_limits + list(tk_send('x2axis', 'limits')) + end + def x2axis_transform(val) + list(tk_send('x2axis', 'transform', val)) + end + def x2axis_use(target=nil) + if target + Tk::BLT::PlotComponent::Axis.id2obj(self, + tk_send('x2axis', 'use', + tagid(target))) + else + Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('x2axis', 'use')) + end + end + + def yaxis_cget(option) + itemcget('yaxis', option) + end + def yaxis_configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + if cmd = slot.delete('command') + slot['command'] = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + elsif slot == :command || slot == 'command' + cmd = value + value = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + itemconfigure('yaxis', slot, value) + end + def yaxis_configinfo(slot=nil) + itemconfiginfo('yaxis', slot) + end + def current_yaxis_configinfo(slot=nil) + current_itemconfiginfo('yaxis', slot) + end + def yaxis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'yaxis', 'bind'], context, cmd, *args) + self + end + def yaxis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'yaxis', 'bind'], context, cmd, *args) + self + end + def yaxis_bind_remove(context) + _bind_remove([path, 'yaxis', 'bind'], context) + self + end + def yaxis_bindinfo(context=nil) + _bindinfo([path, 'yaxis', 'bind'], context) + end + def yaxis_invtransform(val) + list(tk_send('yaxis', 'invtransform', val)) + end + def yaxis_limits + list(tk_send('yaxis', 'limits')) + end + def yaxis_transform(val) + list(tk_send('yaxis', 'transform', val)) + end + def yaxis_use(target=nil) + if target + Tk::BLT::PlotComponent::Axis.id2obj(self, + tk_send('yaxis', 'use', + tagid(target))) + else + Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('yaxis', 'use')) + end + end + + def y2axis_cget(option) + itemcget('y2axis', option) + end + def y2axis_configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + if cmd = slot.delete('command') + slot['command'] = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + elsif slot == :command || slot == 'command' + cmd = value + value = proc{|w, tick| + cmd.call(TkComm.window(w), TkComm.num_or_str(tick)) + } + end + itemconfigure('y2axis', slot, value) + end + def y2axis_configinfo(slot=nil) + axis_configinfo('y2axis', slot) + end + def current_y2axis_configinfo(slot=nil) + current_itemconfiginfo('y2axis', slot) + end + def y2axis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'y2axis', 'bind'], context, cmd, *args) + self + end + def y2axis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'y2axis', 'bind'], context, cmd, *args) + self + end + def y2axis_bind_remove(context) + _bind_remove([path, 'y2axis', 'bind'], context) + self + end + def y2axis_bindinfo(context=nil) + _bindinfo([path, 'y2axis', 'bind'], context) + end + def y2axis_invtransform(val) + list(tk_send('y2axis', 'invtransform', val)) + end + def y2axis_limits + list(tk_send('y2axis', 'limits')) + end + def y2axis_transform(val) + list(tk_send('y2axis', 'transform', val)) + end + def y2axis_use(target=nil) + if target + Tk::BLT::PlotComponent::Axis.id2obj(self, + tk_send('y2axis', 'use', + tagid(target))) + else + Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('y2axis', 'use')) + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/container.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/container.rb new file mode 100644 index 0000000000..cdbec21f25 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/container.rb @@ -0,0 +1,28 @@ +# +# tkextlib/blt/container.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Container < TkWindow + TkCommandNames = ['::blt::container'.freeze].freeze + WidgetClassName = 'Container'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'name' + end + private :__strval_optkeys + + def find_command(pat) + Hash[*simplelist(tk_send_without_enc('find', '-command', pat))] + end + + def find_name(pat) + Hash[*simplelist(tk_send_without_enc('find', '-name', pat))] + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/cutbuffer.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/cutbuffer.rb new file mode 100644 index 0000000000..1cc39dfb94 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/cutbuffer.rb @@ -0,0 +1,23 @@ +# +# tkextlib/blt/cutbuffer.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module CutBuffer + TkCommandNames = ['::blt::cutbuffer'.freeze].freeze + + def self.get(num = 0) + Tk.tk_call('::blt::cutbuffer', 'get', num) + end + def self.rotate(count = 1) + Tk.tk_call('::blt::cutbuffer', 'rotate', count) + end + def self.set(val, num = 0) + Tk.tk_call('::blt::cutbuffer', 'set', val, num) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/dragdrop.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/dragdrop.rb new file mode 100644 index 0000000000..68fb9e591a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/dragdrop.rb @@ -0,0 +1,214 @@ +# +# tkextlib/blt/dragdrop.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/itemconfig' +require 'tkextlib/blt.rb' + +module Tk::BLT + module DragDrop + extend TkCore + + TkCommandNames = ['::blt::drag&drop'.freeze].freeze + + class Token < TkWindow + WidgetClassName = 'DragDropToken'.freeze + WidgetClassNames[WidgetClassName] = self + + def initialize(arg) + if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token + arg = _symbolkey2str(arg) + install_win(nil, arg['widgetname']) + else # arg is a drag&drop source + tk_call('::blt::drag&drop', 'source', arg) + install_win(nil, tk_call('::blt::drag&drop', 'token', arg)) + end + end + end + + ################################### + + extend TkItemConfigMethod + extend Tk::ValidateConfigure + + class << self + def __item_config_cmd(id) # id := ['source'|'target', win] + ['::blt::drag&drop', id[0], id[1]] + end + private :__item_config_cmd + + def __item_boolval_optkeys(id) + super(id) << 'selftarget' + end + private :__item_boolval_optkeys + + def __item_listval_optkeys(id) + super(id) << 'send' + end + private :__item_listval_optkeys + + def __item_strval_optkeys(id) + super(id) << 'rejectbg' << 'rejectfg' << 'tokenbg' + end + private :__item_strval_optkeys + + undef itemcget + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo + + def source_configure(win, slot, value=None) + itemconfigure(['source', win], slot, value) + end + def source_configinfo(win, slot=nil) + itemconfiginfo(['source', win], slot) + end + def current_source_configinfo(win, slot=nil) + current_itemconfiginfo(['source', win], slot) + end + end + + class PackageCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?t, ?w, :token ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL) + + def self.ret_val(val) + val + end + end + + def self._config_keys + ['packagecmd'] + end + end + + class SiteCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?s, ?b, :compatible ], + [ ?t, ?w, :token ], + nil + ] + + PROC_TBL = [ + [ ?b, TkComm.method(:bool) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL) + + def self.ret_val(val) + val + end + end + + def self._config_keys + ['sitecmd'] + end + end + + def self.__validation_class_list + super() << PackageCommand << SiteCommand + end + + class << self + Tk::ValidateConfigure.__def_validcmd(binding, PackageCommand) + Tk::ValidateConfigure.__def_validcmd(binding, SiteCommand) + end + + ################################### + + class DnD_Handle < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?i, ?s, :ip_name ], + [ ?v, ?v, :value ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?i, TkComm.method(:string) ], + [ ?v, TkComm.method(:tk_tcl2ruby) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL) + end + + def self.source_handler(win, datatype, cmd=Proc.new, *args) + _bind_for_event_class(DnD_Handle, + ['::blt::drag&drop', 'source', win, 'handler'], + cmd, *args) + end + + def self.target_handler(win, datatype, cmd=Proc.new, *args) + _bind_for_event_class(DnD_Handle, + ['::blt::drag&drop', 'target', win, 'handler'], + cmd, *args) + end + + ################################### + + def self.init_source(win) + tk_call('::blt::drag&drop', 'source', win) + end + + def self.source() + list(tk_call('::blt::drag&drop', 'source')) + end + + def self.source_handler_list(win) + simplelist(tk_call('::blt::drag&drop', 'source', win, 'handler')) + end + def self.source_handler_info(win, type) + tk_tcl2ruby(tk_call('::blt::drag&drop', 'source', win, 'handler', type)) + end + + def self.target + list(tk_call('::blt::drag&drop', 'target')) + end + def self.target_handler_list(win) + simplelist(tk_call('::blt::drag&drop', 'target', win, 'handler')) + end + + def self.handle_target(win, type, val=None) + tk_call('::blt::drag&drop', 'target', win, 'handle', type, val) + end + + def self.token(win) + window(tk_call('::blt::drag&drop', 'token', win)) + end + + def self.drag(win, x, y) + tk_call('::blt::drag&drop', 'drag', win, x, y) + end + def self.drop(win, x, y) + tk_call('::blt::drag&drop', 'drop', win, x, y) + end + + def self.errors(cmd=Proc.new) + tk_call('::blt::drag&drop', 'errors', cmd) + end + + def self.active + bool(tk_call('::blt::drag&drop', 'active')) + end + + def self.location(x=None, y=None) + list(tk_call('::blt::drag&drop', 'location', x, y)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/eps.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/eps.rb new file mode 100644 index 0000000000..586a42470c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/eps.rb @@ -0,0 +1,32 @@ +# +# tkextlib/blt/eps.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/canvas' +require 'tkextlib/blt.rb' + +module Tk::BLT + class EPS < TkcItem + CItemTypeName = 'eps'.freeze + CItemTypeToClass[CItemTypeName] = self + end +end + +class TkCanvas + alias __BLT_EPS_item_strval_optkeys __item_strval_optkeys + def __item_strval_optkeys(id) + __BLT_EPS_item_strval_optkeys(id) + [ + 'shadowcolor', 'title', 'titlecolor' + ] + end + private :__item_strval_optkeys + + alias __BLT_EPS_item_boolval_optkeys __item_boolval_optkeys + def __item_boolval_optkeys(id) + __BLT_EPS_item_boolval_optkeys(id) + ['showimage'] + end + private :__item_boolval_optkeys +end + diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/graph.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/graph.rb new file mode 100644 index 0000000000..9ae99bff5c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/graph.rb @@ -0,0 +1,67 @@ +# +# tkextlib/blt/graph.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' +require 'tkextlib/blt/component.rb' + +module Tk::BLT + class Graph < TkWindow + TkCommandNames = ['::blt::graph'.freeze].freeze + WidgetClassName = 'Graph'.freeze + WidgetClassNames[WidgetClassName] = self + + include PlotComponent + include GraphCommand + + def __boolval_optkeys + ['bufferelements', 'invertxy'] + end + private :__boolval_optkeys + + def __strval_optkeys + ['text', 'label', 'title', 'file', 'plotbackground'] + end + private :__strval_optkeys + +=begin + BarElement_ID = ['blt_graph_bar'.freeze, '00000'.taint].freeze + + def bar(elem=nil, keys={}) + if elem.kind_of?(Hash) + keys = elem + elem = nil + end + unless elem + elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze + BarElement_ID[1].succ! + end + tk_send('bar', elem, keys) + Element.new(self, elem, :without_creating=>true) + end +=end + + def extents(item) + num_or_str(tk_send_without_enc('extents', item)) + end + + def invtransform(x, y) + list(tk_send_without_enc('invtransform', x, y)) + end + + def inside(x, y) + bool(tk_send_without_enc('inside', x, y)) + end + + def snap(output, keys={}) + tk_send_without_enc('snap', *(hash_kv(keys, false) + output)) + self + end + + def transform(x, y) + list(tk_send_without_enc('transform', x, y)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/htext.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/htext.rb new file mode 100644 index 0000000000..a0cf3dc036 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/htext.rb @@ -0,0 +1,110 @@ +# +# tkextlib/blt/htext.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/itemconfig.rb' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Htext<TkWindow + Htext_Var = TkVarAccess.new_hash('htext') + Htext_Widget = TkVarAccess.new('htext(widget)', :window) + Htext_File = TkVarAccess.new('htext(file)') + Htext_Line = TkVarAccess.new('htext(line)') + + include TkItemConfigMethod + include Scrollable + + TkCommandNames = ['::blt::htext'.freeze].freeze + WidgetClassName = 'Htext'.freeze + WidgetClassNames[WidgetClassName] = self + + alias window_cget itemcget + alias window_configure itemconfigure + alias window_configuinfo itemconfiginfo + alias current_window_configuinfo current_itemconfiginfo + + def __strval_optkeys + super() << 'filename' + end + private :__strval_optkeys + + def append(win, keys={}) + tk_send('append', _epath(win), keys) + self + end + + def goto_line(idx) + tk_send_without_enc('gotoline', idx) + self + end + def current_line + number(tk_send_without_enc('gotoline')) + end + + def index(str) + number(tk_send('index', str)) + end + + def line_pos(str) + tk_send('linepos', str) + end + + def range(from=None, to=None) + tk_send_without_enc('range', from, to) + end + + def scan_mark(pos) + tk_send_without_enc('scan', 'mark', pos) + self + end + + def scan_dragto(pos) + tk_send_without_enc('scan', 'dragto', pos) + self + end + + def search(pat, from=None, to=None) + num = number(tk_send('search', pat, from, to)) + (num < 0)? nil: num + end + + def selection_adjust(index) + tk_send_without_enc('selection', 'adjust', index) + self + end + def selection_clear() + tk_send_without_enc('selection', 'clear') + self + end + def selection_from(index) + tk_send_without_enc('selection', 'from', index) + self + end + def selection_line(index) + tk_send_without_enc('selection', 'line', index) + self + end + def selection_present() + bool(tk_send_without_enc('selection', 'present')) + end + def selection_range(first, last) + tk_send_without_enc('selection', 'range', first, last) + self + end + def selection_to(index) + tk_send_without_enc('selection', 'to', index) + self + end + def selection_word(index) + tk_send_without_enc('selection', 'word', index) + self + end + + def windows(pat=None) + list(tk_send('windows', pat)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/spline.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/spline.rb new file mode 100644 index 0000000000..9f75a0b217 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/spline.rb @@ -0,0 +1,23 @@ +# +# tkextlib/blt/spline.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Spline + extend TkCore + + TkCommandNames = ['::blt::spline'.freeze].freeze + + def self.natural(x, y, sx, sy) + tk_call('::blt::spline', 'natural', x, y, sx, sy) + end + + def self.quadratic(x, y, sx, sy) + tk_call('::blt::spline', 'quadratic', x, y, sx, sy) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/stripchart.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/stripchart.rb new file mode 100644 index 0000000000..fe5afbb095 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/stripchart.rb @@ -0,0 +1,74 @@ +# +# tkextlib/blt/stripchart.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' +require 'tkextlib/blt/component.rb' + +module Tk::BLT + class Stripchart < TkWindow + TkCommandNames = ['::blt::stripchart'.freeze].freeze + WidgetClassName = 'Stripchart'.freeze + WidgetClassNames[WidgetClassName] = self + + include PlotComponent + include GraphCommand + + def __boolval_optkeys + ['bufferelements', 'buffergraph', 'invertxy'] + end + private :__boolval_optkeys + + def __strval_optkeys + ['text', 'label', 'title', 'file', + 'background', 'plotbackground'] + end + private :__strval_optkeys + +=begin + BarElement_ID = ['blt_stripchart_bar'.freeze, '00000'.taint].freeze + + def bar(elem=nil, keys={}) + if elem.kind_of?(Hash) + keys = elem + elem = nil + end + unless elem + elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze + BarElement_ID[1].succ! + end + tk_send('bar', elem, keys) + Element.new(self, elem, :without_creating=>true) + end +=end + + def extents(item) + num_or_str(tk_send_without_enc('extents', item)) + end + + def invtransform(x, y) + list(tk_send_without_enc('invtransform', x, y)) + end + + def inside(x, y) + bool(tk_send_without_enc('inside', x, y)) + end + + def metafile(file=None) + # Windows only + tk_send('metafile', file) + self + end + + def snap(output, keys={}) + tk_send_without_enc('snap', *(hash_kv(keys, false) + output)) + self + end + + def transform(x, y) + list(tk_send_without_enc('transform', x, y)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/table.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/table.rb new file mode 100644 index 0000000000..0be9d8d42a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/table.rb @@ -0,0 +1,386 @@ +# +# tkextlib/blt/table.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/itemconfig.rb' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Table + include Tk + extend Tk + extend TkItemConfigMethod + + TkCommandNames = ['::blt::table'.freeze].freeze + + module TableContainer + def blt_table_add(*args) + Tk::BLT::Table.add(self, *args) + self + end + + def blt_table_arrange() + Tk::BLT::Table.arrange(self) + self + end + + def blt_table_cget(*args) + Tk::BLT::Table.cget(self, *args) + end + + def blt_table_configure(*args) + Tk::BLT::Table.configure(self, *args) + self + end + + def blt_table_configinfo(*args) + Tk::BLT::Table.configinfo(self, *args) + end + + def blt_table_current_configinfo(*args) + Tk::BLT::Table.current_configinfo(self, *args) + end + + def blt_table_locate(x, y) + Tk::BLT::Table.locate(self, x, y) + end + + def blt_table_delete(*args) + Tk::BLT::Table.delete(self, *args) + self + end + + def blt_table_extents(item) + Tk::BLT::Table.extents(self, item) + end + + def blt_table_insert(*args) + Tk::BLT::Table.insert(self, *args) + self + end + + def blt_table_insert_before(*args) + Tk::BLT::Table.insert_before(self, *args) + self + end + + def blt_table_insert_after(*args) + Tk::BLT::Table.insert_after(self, *args) + self + end + + def blt_table_join(first, last) + Tk::BLT::Table.join(self, first, last) + self + end + + def blt_table_save() + Tk::BLT::Table.save(self) + end + + def blt_table_search(*args) + Tk::BLT::Table.search(self, *args) + end + + def blt_table_split(*args) + Tk::BLT::Table.split(self, *args) + self + end + + def blt_table_itemcget(*args) + Tk::BLT::Table.itemcget(self, *args) + end + + def blt_table_itemconfigure(*args) + Tk::BLT::Table.itemconfigure(self, *args) + self + end + + def blt_table_itemconfiginfo(*args) + Tk::BLT::Table.itemconfiginfo(self, *args) + end + + def blt_table_current_itemconfiginfo(*args) + Tk::BLT::Table.current_itemconfiginfo(self, *args) + end + + def blt_table_iteminfo(item) + Tk::BLT::Table.iteminfo(self, item) + end + end + end +end + + +############################################ +class << Tk::BLT::Table + def __item_cget_cmd(id) # id := [ container, item ] + win = (id[0].kind_of?(TkWindow))? id[0].path: id[0].to_s + ['::blt::table', 'cget', win, id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) # id := [ container, item, ... ] + container, *items = id + win = (container.kind_of?(TkWindow))? container.path: container.to_s + ['::blt::table', 'configure', win, *items] + end + private :__item_config_cmd + + def __item_pathname(id) + win = (id[0].kind_of?(TkWindow))? id[0].path: id[0].to_s + win + ';' + end + private :__item_pathname + + alias __itemcget itemcget + alias __itemconfigure itemconfigure + alias __itemconfiginfo itemconfiginfo + alias __current_itemconfiginfo current_itemconfiginfo + + private :__itemcget, :__itemconfigure + private :__itemconfiginfo, :__current_itemconfiginfo + + def __boolval_optkeys + super() << 'propagate' + end + private :__boolval_optkeys + + def tagid(tag) + if tag.kind_of?(Array) + case tag[0] + when Integer + # [row, col] + tag.join(',') + when :c, :C, 'c', 'C', :r, :R, 'r', 'R' + # c0 or r1 or C*, and so on + tag.collect{|elem| elem.to_s}.join('') + else + tag + end + elsif tag.kind_of?(TkWindow) + _epath(tag) + else + tag + end + end + + def tagid2obj(tagid) + tagid + end + + ############################################ + + def cget(container, option) + __itemcget([container], option) + end + + def configure(container, *args) + __itemconfigure([container], *args) + end + + def configinfo(container, *args) + __itemconfiginfo([container], *args) + end + + def current_configinfo(container, *args) + __current_itemconfiginfo([container], *args) + end + + def itemcget(container, item, option) + __itemcget([container, tagid(item)], option) + end + + def itemconfigure(container, *args) + if args[-1].kind_of?(Hash) + # container, item, item, ... , hash_optkeys + keys = args.pop + fail ArgumentError, 'no item is given' if args.empty? + id = [container] + args.each{|item| id << tagid(item)} + __itemconfigure(id, keys) + else + # container, item, item, ... , option, value + val = args.pop + opt = args.pop + fail ArgumentError, 'no item is given' if args.empty? + id = [container] + args.each{|item| id << tagid(item)} + __itemconfigure(id, opt, val) + end + container + end + + def itemconfiginfo(container, *args) + slot = args[-1] + if slot.kind_of?(String) || slot.kind_of?(Symbol) + slot = slot.to_s + if slot[0] == ?. || slot =~ /^\d+,\d+$/ || slot =~ /^(c|C|r|R)(\*|\d+)/ + # widget || row,col || Ci or Ri + slot = nil + else + # option + slot = args.pop + end + else + slot = nil + end + + fail ArgumentError, 'no item is given' if args.empty? + + id = [container] + args.each{|item| id << tagid(item)} + __itemconfiginfo(id, slot) + end + + def current_itemconfiginfo(container, *args) + slot = args[-1] + if slot.kind_of?(String) || slot.kind_of?(Symbol) + slot = slot.to_s + if slot[0] == ?. || slot =~ /^\d+,\d+$/ || slot =~ /^(c|C|r|R)(\*|\d+)/ + # widget || row,col || Ci or Ri + slot = nil + else + # option + slot = args.pop + end + else + slot = nil + end + + fail ArgumentError, 'no item is given' if args.empty? + + id = [container] + args.each{|item| id << tagid(item)} + __current_itemconfiginfo(id, slot) + end + + def info(container) + ret = {} + inf = list(tk_call('::blt::table', 'info', container)) + until inf.empty? + opt = inf.slice!(0..1) + ret[opt[1..-1]] = opt[1] + end + ret + end + + def iteminfo(container, item) + inf = list(tk_call('::blt::table', 'info', container, tagid(item)).chomp) + + ret = [] + until inf.empty? || (inf[0].kind_of?(String) && inf[0] =~ /^-/) + ret << inf.shift + end + + if inf.length > 1 + keys = {} + while inf.length > 1 + opt = inf.slice!(0..1) + keys[opt[0][1..-1]] = opt[1] + end + ret << keys + end + + ret + end + + ############################################ + + def create_container(container) + tk_call('::blt::table', container) + begin + class << container + include Tk::BLT::Table::TableContainer + end + rescue + warn('fail to include TableContainer methods (frozen object?)') + end + container + end + + def add(container, *args) + if args.empty? + tk_call('::blt::table', container) + else + args = args.collect{|arg| + if arg.kind_of?(TkWindow) + _epath(arg) + elsif arg.kind_of?(Array) # index + arg.join(',') + else + arg + end + } + tk_call('::blt::table', container, *args) + end + container + end + + def arrange(container) + tk_call('::blt::table', 'arrange', container) + container + end + + def delete(container, *args) + tk_call('::blt::table', 'delete', container, *args) + end + + def extents(container, item) + ret = [] + inf = list(tk_call('::blt::table', 'extents', container, item)) + ret << inf.slice!(0..4) until inf.empty? + ret + end + + def forget(*wins) + wins = wins.collect{|win| _epath(win)} + tk_call('::blt::table', 'forget', *wins) + end + + def insert(container, *args) + tk_call('::blt::table', 'insert', container, *args) + end + + def insert_before(container, *args) + tk_call('::blt::table', 'insert', container, '-before', *args) + end + + def insert_after(container, *args) + tk_call('::blt::table', 'insert', container, '-after', *args) + end + + def join(container, first, last) + tk_call('::blt::table', 'join', container, first, last) + end + + def locate(container, x, y) + tk_call('::blt::table', 'locate', container, x, y) + end + + def containers(arg={}) + list(tk_call('::blt::table', 'containers', *hash_kv(arg))) + end + + def containers_pattern(pat) + list(tk_call('::blt::table', 'containers', '-pattern', pat)) + end + + def containers_slave(win) + list(tk_call('::blt::table', 'containers', '-slave', win)) + end + + def save(container) + tk_call('::blt::table', 'save', container) + end + + def search(container, keys={}) + list(tk_call('::blt::table', 'containers', *hash_kv(keys))) + end + + def split(container, *args) + tk_call('::blt::table', 'split', container, *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tabnotebook.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tabnotebook.rb new file mode 100644 index 0000000000..508fa2b82f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tabnotebook.rb @@ -0,0 +1,21 @@ +# +# tkextlib/blt/tabnotebook.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' +require 'tkextlib/blt/tabset.rb' + +module Tk::BLT + class Tabnotebook < Tabset + TkCommandNames = ['::blt::tabnotebook'.freeze].freeze + WidgetClassName = 'Tabnotebook'.freeze + WidgetClassNames[WidgetClassName] = self + + def get_tab(index) + Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('id', tagindex(index))) + end + alias get_id get_tab + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tabset.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tabset.rb new file mode 100644 index 0000000000..c26b6ee001 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tabset.rb @@ -0,0 +1,401 @@ +# +# tkextlib/blt/tabset.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Tabset < TkWindow + class Tab < TkObject + include TkTreatItemFont + + TabID_TBL = TkCore::INTERP.create_table + TabsetTab_ID = ['blt_tabset_tab'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TabID_TBL.clear } + + def self.id2obj(tabset, id) + tpath = tabset.path + return id unless TabID_TBL[tpath] + TabID_TBL[tpath][id]? TabID_TBL[tpath]: id + end + + def self.new(parent, pos=nil, name=nil, keys={}) + if pos.kind_of?(Hash) + keys = pos + name = nil + pos = nil + end + if name.kind_of?(Hash) + keys = name + name = nil + end + + if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name] + TabID_TBL[parent.path][name] + else + super(parent, pos, name, keys) + end + end + + def initialize(parent, pos, name, keys) + @t = parent + @tpath = parent.path + if name + @path = @id = name + TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath] + TabID_TBL[@tpath][@id] = self + + unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?) + if pos + idx = tk_call(@tpath, 'index', '-name', @id) + if pos.to_s == 'end' + tk_call(@tpath, idx, 'moveto', 'after', 'end') + else + tk_call(@tpath, idx, 'moveto', 'before', pos) + end + end + tk_call(@tpath, 'tab', 'configure', @id, keys) + return + end + + else + @path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_) + TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath] + TabID_TBL[@tpath][@id] = self + TabsetTab_ID[1].succ! + end + + pos = 'end' unless pos + tk_call(@tpath, 'insert', pos, @id, keys) + end + + #def bind(context, cmd=Proc.new, *args) + # @t.tab_bind(@id, context, cmd, *args) + # self + #end + def bind(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @t.tab_bind(@id, context, cmd, *args) + self + end + #def bind_append(context, cmd=Proc.new, *args) + # @t.tab_bind_append(@id, context, cmd, *args) + # self + #end + def bind_append(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @t.tab_bind_append(@id, context, cmd, *args) + self + end + def bind_remove(context) + @t.tab_bind_remove(@id, context) + self + end + def bindinfo(context=nil) + @t.tab_bindinfo(@id, context) + end + + def cget(*args) + @t.tab_cget(@id, *args) + end + def configure(*args) + @t.tab_configure(@id, *args) + end + def configinfo(*args) + @t.tab_configinfo(@id, *args) + end + def current_configinfo(*args) + @t.current_tab_configinfo(@id, *args) + end + + def delete() + @t.delete(@id) + TabID_TBL[@tpath].delete(@id) + self + end + + def get_name() + @id.dup + end + + def focus() + @t.focus(self.index) + end + + def index() + @t.index_name(@id) + end + + def invoke() + @t.invoke(self.index) + end + + def move_before(idx) + @t.move_before(self.index, idx) + end + def move_after(idx) + @t.move_after(self.index, idx) + end + + def perforation_highlight(mode) + @t.perforation.highlight(self.index, mode) + end + def perforation_invoke() + @t.perforation.invoke(self.index) + end + + def see() + @t.see(self.index) + end + + def tearoff(name=None) + @t.tab_tearoff(self.index, *args) + end + end + + ######################################## + + class NamedTab < Tab + def self.new(parent, name) + super(parent, nil, name, {}) + end + end + + ######################################## + + include X_Scrollable + include TkItemConfigMethod + + TkCommandNames = ['::blt::tabset'.freeze].freeze + WidgetClassName = 'Tabset'.freeze + WidgetClassNames[WidgetClassName] = self + + def __destroy_hook__ + Tk::BLT::Tabset::Tab::TabID_TBL.delete(@path) + end + + ######################################## + + def __boolval_optkeys + super() << 'samewidth' << 'tearoff' + end + private :__strval_optkeys + + def __strval_optkeys + super() << 'tabbackground' << 'tabforeground' + end + private :__strval_optkeys + + def __item_cget_cmd(id) + [self.path, 'tab', 'cget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'tab', 'configure', id] + end + private :__item_config_cmd + + def __item_pathname(tagOrId) + if tagOrId.kind_of?(Tk::BLT::Tabset::Tab) + self.path + ';' + tagOrId.id.to_s + else + self.path + ';' + tagOrId.to_s + end + end + private :__item_pathname + + alias tab_cget itemcget + alias tab_configure itemconfigure + alias tab_configinfo itemconfiginfo + alias current_tab_configinfo current_itemconfiginfo + + def __item_strval_optkeys(id) + super(id) << 'shadow' + end + private :__item_strval_optkeys + + def tagid(tab) + if tab.kind_of?(Tk::BLT::Tabset::Tab) + tab.id + else + tab + end + end + + def tagindex(tab) + if tab.kind_of?(Tk::BLT::Tabset::Tab) + tab.index + else + tab + end + end + + ######################################## + + def activate(index) + tk_send('activate', tagindex(index)) + self + end + alias highlight activate + + #def tabbind(tag, context, cmd=Proc.new, *args) + # _bind([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def tabbind(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, "bind", tagid(tag)], context, cmd, *args) + self + end + #def tabbind_append(tag, context, cmd=Proc.new, *args) + # _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def tabbind_append(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + self + end + def tabbind_remove(tag, context) + _bind_remove([path, "bind", tagid(tag)], context) + self + end + def tabbindinfo(tag, context=nil) + _bindinfo([path, "bind", tagid(tag)], context) + end + + def delete(first, last=None) + tk_send('delete', tagindex(first), tagindex(last)) + if first.kind_of?(Tk::BLT::Tabset::Tab) + TabID_TBL[@path].delete(first.id) + end + # middle tabs of the range are unknown + if last.kind_of?(Tk::BLT::Tabset::Tab) + TabID_TBL[@path].delete(last.id) + end + self + end + + def focus(index) + tk_send('focus', tagindex(index)) + self + end + + def get_tab(index) + Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('get', tagindex(index))) + end + + def index(str) + num_or_str(tk_send('index', str)) + end + def index_name(tab) + num_or_str(tk_send('index', '-mame', tagid(tab))) + end + + def insert(pos, tab, keys={}) + Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys) + end + + def invoke(index) + tk_send('invoke', tagindex(index)) + end + + def move_before(index, base_idx) + tk_send('move', tagindex(index), 'before', tagindex(base_idx)) + self + end + def move_after(index, base_idx) + tk_send('move', tagindex(index), 'after', tagindex(base_idx)) + self + end + + def nearest(x, y) + Tk::BLT::Tabset::Tab.id2obj(num_or_str(tk_send_without_enc('nearest', x, y))) + end + + def perforation_highlight(index, mode) + tk_send('perforation', 'highlight', tagindex(index), mode) + self + end + def perforation_invoke(index) + tk_send('perforation', 'invoke', tagindex(index)) + 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 see(index) + tk_send('see', tagindex(index)) + self + end + + def size() + number(tk_send_without_enc('size')) + end + + def select(index) + tk_send('select', tagindex(index)) + self + end + + def tab_names(pat=None) + simplelist(tk_send('tab', 'names', pat)).collect{|name| + Tk::BLT::Tabset::Tab.id2obj(name) + } + end + + def tab_tearoff(index, name=None) + window(tk_send('tab', 'tearoff', tagindex(index), name)) + end + + def xscrollcommand(cmd=Proc.new) + configure_cmd 'scrollcommand', cmd + self + end + alias scrollcommand xscrollcommand + + def xview(*index) + if index.empty? + list(tk_send_without_enc('view')) + else + tk_send_without_enc('view', *index) + self + end + end + alias view xview + alias view_moveto xview_moveto + alias view_scroll xview_scroll + + alias scrollbar xscrollbar + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/ted.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/ted.rb new file mode 100644 index 0000000000..39495842b4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/ted.rb @@ -0,0 +1,62 @@ +# +# tkextlib/blt/ted.rb +# +# *** This is alpha version, because there is no document on BLT. *** +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Ted + extend TkCore + + TkCommandNames = ['::blt::ted'.freeze].freeze + + ############################## + + extend TkItemConfigMethod + + class << self + def __item_cget_cmd(id) + ['::blt::ted', 'cget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + ['::blt::ted', 'configure', id] + end + private :__item_config_cmd + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + def cget(master, option) + itemconfigure(master, slot, value) + end + def configure(master, slot, value=None) + itemconfigure(master, slot, value) + end + def configinfo(master, slot=nil) + itemconfiginfo(master, slot) + end + def current_configinfo(master, slot=nil) + current_itemconfiginfo(master, slot) + end + end + + ############################## + + def self.edit(master, *args) + tk_call('::blt::ted', 'edit', master, *args) + end + def self.rep(master, *args) + tk_call('::blt::ted', 'rep', master, *args) + end + def self.select(master, *args) + tk_call('::blt::ted', 'select', master, *args) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile.rb new file mode 100644 index 0000000000..5f5242f299 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile.rb @@ -0,0 +1,21 @@ +# +# tkextlib/blt/tile.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Tile + autoload :Button, 'tkextlib/blt/tile/button.rb' + autoload :CheckButton, 'tkextlib/blt/tile/checkbutton.rb' + autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb' + autoload :Radiobutton, 'tkextlib/blt/tile/radiobutton.rb' + autoload :RadioButton, 'tkextlib/blt/tile/radiobutton.rb' + autoload :Frame, 'tkextlib/blt/tile/frame.rb' + autoload :Label, 'tkextlib/blt/tile/label.rb' + autoload :Scrollbar, 'tkextlib/blt/tile/scrollbar.rb' + autoload :Toplevel, 'tkextlib/blt/tile/toplevel.rb' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/button.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/button.rb new file mode 100644 index 0000000000..dd715c8b98 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/button.rb @@ -0,0 +1,16 @@ +# +# tkextlib/blt/tile/button.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/button' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class Button < TkButton + TkCommandNames = ['::blt::tile::button'.freeze].freeze + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb new file mode 100644 index 0000000000..ad58999d86 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/checkbutton.rb @@ -0,0 +1,17 @@ +# +# tkextlib/blt/tile/checkbutton.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/checkbutton' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class CheckButton < TkCheckButton + TkCommandNames = ['::blt::tile::checkbutton'.freeze].freeze + end + Checkbutton = CheckButton + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/frame.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/frame.rb new file mode 100644 index 0000000000..10469fd35f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/frame.rb @@ -0,0 +1,16 @@ +# +# tkextlib/blt/tile/frame.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class Frame < TkFrame + TkCommandNames = ['::blt::tile::frame'.freeze].freeze + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/label.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/label.rb new file mode 100644 index 0000000000..ec67babd58 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/label.rb @@ -0,0 +1,16 @@ +# +# tkextlib/blt/tile/label.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/label' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class Label < TkLabel + TkCommandNames = ['::blt::tile::label'.freeze].freeze + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb new file mode 100644 index 0000000000..2316923b19 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/radiobutton.rb @@ -0,0 +1,17 @@ +# +# tkextlib/blt/tile/radiobutton.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/radiobutton' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class RadioButton < TkRadioButton + TkCommandNames = ['::blt::tile::radiobutton'.freeze].freeze + end + Radiobutton = RadioButton + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb new file mode 100644 index 0000000000..ba3bf316f0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/scrollbar.rb @@ -0,0 +1,16 @@ +# +# tkextlib/blt/tile/scrollbar.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/scrollbar' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class Scrollbar < TkScrollbar + TkCommandNames = ['::blt::tile::scrollbar'.freeze].freeze + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/toplevel.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/toplevel.rb new file mode 100644 index 0000000000..6cc2c91415 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tile/toplevel.rb @@ -0,0 +1,16 @@ +# +# tkextlib/blt/tile/toplevel.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/toplevel' +require 'tkextlib/blt/tile.rb' + +module Tk::BLT + module Tile + class Toplevel < TkToplevel + TkCommandNames = ['::blt::tile::toplevel'.freeze].freeze + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tree.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tree.rb new file mode 100644 index 0000000000..07dc7ef7e8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/tree.rb @@ -0,0 +1,923 @@ +# +# tkextlib/blt/tree.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Tree < TkObject + TkCommandNames = ['::blt::tree'.freeze].freeze + + ################################### + + class Node < TkObject + TreeNodeID_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ TreeNodeID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeNodeID_TBL[tpath] + if TreeNodeID_TBL[tpath][id] + TreeNodeID_TBL[tpath][id] + else + begin + self.new(tree, nil, 'node'=>Integer(id)) + rescue + id + end + end + end + + def self.new(tree, parent, keys={}) + keys = _symbolkey2str(keys) + tpath = tree.path + + if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id]) + keys.delete('node') + tk_call(tree.path, 'move', id, parent, keys) if parent + return obj + end + + super(tree, parent, keys) + end + + def initialize(tree, parent, keys={}) + @parent = @tree = tree + @tpath = @parent.path + + parent = tk_call(@tpath, 'root') unless parent + + if (id = keys['node']) && bool(tk_call(@tpath, 'exists', id)) + @path = @id = id + keys.delete('node') + tk_call(@tpath, 'move', @id, parent, keys) if parent + else + @path = @id = tk_call(@tpath, 'insert', parent, keys) + end + + TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath] + TreeNodeID_TBL[@tpath][@id] = self + end + + def id + @id + end + + def apply(keys={}) + @tree.apply(@id, keys) + self + end + + def children() + @tree.children(@id) + end + + def copy(parent, keys={}) + @tree.copy(@id, parent, keys) + end + def copy_to(dest_tree, parent, keys={}) + @tree.copy_to(@id, dest_tree, parent, keys) + end + + def degree() + @tree.degree(@id) + end + + def delete() + @tree.delete(@id) + self + end + + def depth() + @tree.depth(@id) + end + + def dump() + @tree.dump(@id) + end + + def dump_to_file(file) + @tree.dump_to_file(@id, file) + self + end + + def exist?(keys={}) + @tree.exist?(@id, keys) + end + + def find(keys={}) + @tree.find(@id, keys) + end + + def find_child(label) + @tree.find_child(@id, label) + end + + def first_child() + @tree.first_child(@id) + end + + def get() + @tree.get(@id) + end + def get_value(key, default_val=None) + @tree.get_value(@id, key, default_val) + end + + def index() + @tree.index(@id) + end + + def leaf?() + @tree.leaf?(@id) + end + def link?() + @tree.link?(@id) + end + def root?() + @tree.root?(@id) + end + + def keys() + @tree.keys(@id) + end + + def label(text = nil) + @tree.label(@id, nil) + end + def label=(text) + @tree.label(@id, text) + end + + def last_child() + @tree.last_child(@id) + end + + def move(dest, keys={}) + @tree.keys(@id, dest, keys) + self + end + + def next() + @tree.next(@id) + end + + def next_sibling() + @tree.next_sibling(@id) + end + + def parent() + @tree.parent(@id) + end + + def fullpath() + @tree.fullpath(@id) + end + + def position() + @tree.position(@id) + end + + def previous() + @tree.previous(@id) + end + + def prev_sibling() + @tree.prev_sibling(@id) + end + + def restore(str, keys={}) + @tree.restore(@id, str, keys) + self + end + def restore_overwrite(str, keys={}) + @tree.restore_overwrite(@id, str, keys) + self + end + + def restore_from_file(file, keys={}) + @tree.restore_from_file(@id, file, keys) + self + end + def restore_overwrite_from_file(file, keys={}) + @tree.restore_overwrite_from_file(@id, file, keys) + self + end + + def root() + @tree.root(@id) + self + end + + def set(data) + @tree.set(@id, data) + self + end + + def size() + @tree.size(@id) + end + + def sort(keys={}) + @tree.sort(@id, keys) + self + end + + def type(key) + @tree.type(@id, key) + end + + def unset(*keys) + @tree.unset(@id, *keys) + self + end + + def values(key=None) + @tree.values(@id, key) + end + end + + ################################### + + class Tag < TkObject + TreeTagID_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ TreeTagID_TBL.clear } + TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint].freeze + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeTagID_TBL[tpath] + if TreeTagID_TBL[tpath][id] + TreeTagID_TBL[tpath][id] + else + self.new(tree, id) + end + end + + def initialize(tree, tag_str = nil) + @parent = @tree = tree + @tpath = @parent.path + + if tag_str + @path = @id = tag_str.dup.freeze + else + @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_) + TreeTagID_TBL[@id] = self + TreeTag_ID[1].succ! + end + TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] + TreeTagID_TBL[@tpath][@id] = self + end + + def id + @id + end + + def add(*nodes) + tk_call(@tpath, 'tag', 'add', @id, *nodes) + self + end + + def delete(*nodes) + tk_call(@tpath, 'tag', 'delete', @id, *nodes) + self + end + + def forget() + tk_call(@tpath, 'tag', 'forget', @id) + TreeTagID_TBL[@tpath].delete(@id) + self + end + + def nodes() + simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|node| + Tk::BLT::Tree::Node.id2obj(@path, node) + } + end + + def set(node) + tk_call(@tpath, 'tag', 'set', node, @id) + self + end + + def unset(node) + tk_call(@tpath, 'tag', 'unset', node, @id) + self + end + end + + ################################### + + class Notify < TkObject + NotifyID_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ NotifyID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless NotifyID_TBL[tpath] + if NotifyID_TBL[tpath][id] + NotifyID_TBL[tpath][id] + else + begin + self.new([tree, id]) + rescue + id + end + end + end + + def self.new(tree, *args, &b) + if tree.kind_of?(Array) + # not create + if obj = NotifyID_TBL[tree[0].path][tree[1]] + return obj + else + return super(false, tree[0], tree[1]) + end + end + + super(true, tree, *args, &b) + end + + def initialize(create, tree, *args, &b) + @parent = @tree = tree + @tpath = @parent.path + + unless create + @path = @id = args[0] + return + end + + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) + cmd = args.shift + # elsif args[-1].kind_of?(Proc) || args[-1].kind_of?(Method) + elsif TkComm._callback_entry?(args[-1]) + cmd = args.pop + elsif b + cmd = Proc.new(&b) + else + fail ArgumentError, "lack of 'command' argument" + end + + args = args.collect{|arg| '-' << arg.to_s} + + args << proc{|id, type| + cmd.call(Tk::BLT::Tree::Node.id2obj(@tree, id), + ((type[0] == ?-)? type[1..-1]: type)) + } + + @path = @id = tk_call(@tpath, 'notify', 'create', *args) + end + + def id + @id + end + + def delete() + tk_call(@tpath, 'notify', 'delete', @id) + NotifyID_TBL[tpath].delete(@id) + self + end + + def info() + lst = simplelist(tk_call(@tpath, 'notify', 'info', id)) + lst[0] = Tk::BLT::Tree::Notify.id2obj(@tree, lst[0]) + lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]} + lst[2] = tk_tcl2ruby(lst[2]) + lst + end + end + + ################################### + + class Trace < TkObject + TraceID_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ TraceID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TraceID_TBL[tpath] + if TraceID_TBL[tpath][id] + TraceID_TBL[tpath][id] + else + begin + self.new([tree, id]) + rescue + id + end + end + end + + def self.new(tree, *args, &b) + if tree.kind_of?(Array) + # not create + if obj = TraceID_TBL[tree[0].path][tree[1]] + return obj + else + return super(false, tree[0], tree[1]) + end + end + + super(true, tree, *args, &b) + end + + def initialize(create, tree, node, key, opts, cmd=nil, &b) + @parent = @tree = tree + @tpath = @parent.path + + unless create + @path = @id = node # == traceID + return + end + + if !cmd + if b + cmd = Proc.new(&b) + else + fail ArgumentError, "lack of 'command' argument" + end + end + + @path = @id = tk_call(@tpath, 'trace', 'create', node, key, opts, + proc{|t, id, k, ops| + tobj = Tk::BLT::Tree.id2obj(t) + if tobj.kind_of?(Tk::BLT::Tree) + nobj = Tk::BLT::Tree::Node.id2obj(tobj, id) + else + nobj = id + end + cmd.call(tobj, nobj, k, ops) + }) + end + + def id + @id + end + + def delete() + tk_call(@tpath, 'trace', 'delete', @id) + TraceID_TBL[tpath].delete(@id) + self + end + + def info() + lst = simplelist(tk_call(@tpath, 'trace', 'info', id)) + lst[0] = Tk::BLT::Tree::Trace.id2obj(@tree, lst[0]) + lst[2] = simplelist(lst[2]) + lst[3] = tk_tcl2ruby(lst[3]) + lst + end + end + + ################################### + + TreeID_TBL = TkCore::INTERP.create_table + Tree_ID = ['blt_tree'.freeze, '00000'.taint].freeze + + def __keyonly_optkeys + { + # apply / find command + 'invert'=>nil, 'leafonly'=>nil, 'nocase'=>nil, + + # apply / find / sort command + 'path'=>nil, + + # copy / restore / restorefile command + 'overwrite'=>nil, + + # copy command + 'recurse'=>nil, 'tags'=>nil, + + # sort command + 'ascii'=>nil, 'decreasing'=>nil, 'disctionary'=>nil, + 'integer'=>nil, 'real'=>nil, 'recurse'=>nil, 'reorder'=>nil, + } + end + + def self.id2obj(id) + TreeID_TBL[id]? TreeID_TBL[id]: id + end + + def self.names(pat = None) + simplelist(tk_call('::blt::tree', 'names', pat)).collect{|name| + id2obj(name) + } + end + + def self.destroy(*names) + tk_call('::blt::tree', 'destroy', + *(names.collect{|n| (n.kind_of?(Tk::BLT::Tree))? n.id: n }) ) + end + + def self.new(name = nil) + return TreeID_TBL[name] if name && TreeID_TBL[name] + super(name) + end + + def initialzie(name = nil) + if name + @path = @id = name + else + @path = @id = Tree_ID.join(TkCore::INTERP._ip_id_) + TreeID_TBL[@id] = self + Tree_ID[1].succ! + end + TreeID_TBL[@id] = self + tk_call('::blt::tree', 'create', @id) + end + + def __destroy_hook__ + Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path) + Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path) + Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path) + Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path) + end + + def tagid(tag) + if tag.kind_of?(Tk::BLT::Tree::Node) || + tag.kind_of?(Tk::BLT::Tree::Tag) || + tag.kind_of?(Tk::BLT::Tree::Notify) || + tag.kind_of?(Tk::BLT::Tree::Trace) + tag.id + else + tag # maybe an Array of configure paramters + end + end + + def destroy() + tk_call('::blt::tree', 'destroy', @id) + self + end + + def ancestor(node1, node2) + Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'ancestor', + tagid(node1), tagid(node2))) + end + + def apply(node, keys={}) + tk_call('::blt::tree', 'apply', tagid(node), __conv_keyonly_opts(keys)) + self + end + + def attach(tree_obj) + tk_call('::blt::tree', 'attach', tree_obj) + self + end + + def children(node) + simplelist(tk_call('::blt::tree', 'children', tagid(node))).collect{|n| + Tk::BLT::Tree::Node.id2obj(self, n) + } + end + + def copy(src, parent, keys={}) + id = tk_call('::blt::tree', 'copy', tagid(src), tagid(parent), + __conv_keyonly_opts(keys)) + Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) + end + def copy_to(src, dest_tree, parent, keys={}) + return copy(src, parent, keys={}) unless dest_tree + + id = tk_call('::blt::tree', 'copy', tagid(src), dest_tree, + tagid(parent), __conv_keyonly_opts(keys)) + Tk::BLT::Tree::Node.new(dest_tree, nil, 'node'=>id) + end + + def degree(node) + number(tk_call('::blt::tree', 'degree', tagid(node))) + end + + def delete(*nodes) + tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)})) + nodes.each{|node| + if node.kind_of?(Tk::BLT::Tree::Node) + Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id) + else + Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s) + end + } + self + end + + def depth(node) + number(tk_call('::blt::tree', 'depth', tagid(node))) + end + + def dump(node) + simplelist(tk_call('::blt::tree', 'dump', tagid(node))).collect{|n| + simplelist(n) + } + end + + def dump_to_file(node, file) + tk_call('::blt::tree', 'dumpfile', tagid(node), file) + self + end + + def exist?(node, key=None) + bool(tk_call('::blt::tree', 'exists', tagid(node), key)) + end + + def find(node, keys={}) + simplelist(tk_call('::blt::tree', 'find', tagid(node), + __conv_keyonly_opts(keys))).collect{|n| + Tk::BLT::Tree::Node.id2obj(self, n) + } + end + + def find_child(node, label) + ret = tk_call('::blt::tree', 'findchild', tagid(node), label) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def first_child(node) + ret = tk_call('::blt::tree', 'firstchild', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def get(node) + Hash[*simplelist(tk_call('::blt::tree', 'get', tagid(node)))] + end + def get_value(node, key, default_val=None) + tk_call('::blt::tree', 'get', tagid(node), key, default_val) + end + + def index(node) + Tk::BLT::Tree::Node.id2obj(self, + tk_call('::blt::tree', 'index', tagid(node))) + end + + def insert(parent, keys={}) + id = tk_call('::blt::tree', 'insert', tagid(parent), keys) + Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) + end + + def ancestor?(node1, node2) + bool(tk_call('::blt::tree', 'is', 'ancestor', + tagid(node1), tagid(node2))) + end + def before?(node1, node2) + bool(tk_call('::blt::tree', 'is', 'before', + tagid(node1), tagid(node2))) + end + def leaf?(node) + bool(tk_call('::blt::tree', 'is', 'leaf', tagid(node))) + end + def link?(node) + bool(tk_call('::blt::tree', 'is', 'link', tagid(node))) + end + def root?(node) + bool(tk_call('::blt::tree', 'is', 'root', tagid(node))) + end + + def keys(node, *nodes) + if nodes.empty? + simplelist(tk_call('blt::tree', 'keys', tagid(node))) + else + simplelist(tk_call('blt::tree', 'keys', tagid(node), + *(nodes.collect{|n| tagid(n)}))).collect{|lst| + simplelist(lst) + } + end + end + + def label(node, text=nil) + if text + tk_call('::blt::tree', 'label', tagid(node), text) + text + else + tk_call('::blt::tree', 'label', tagid(node)) + end + end + + def last_child(node) + ret = tk_call('::blt::tree', 'lastchild', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def link(parent, node, keys={}) + ret = tk_call('::blt::tree', 'link', tagid(parent), tagid(node), + __conv_keyonly_opts(keys)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def move(node, dest, keys={}) + tk_call('::blt::tree', 'move', tagid(node), tagid(dest), keys) + self + end + + def next(node) + ret = tk_call('::blt::tree', 'next', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def next_sibling(node) + ret = tk_call('::blt::tree', 'nextsibling', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def notify_create(*args, &b) + Tk::BLT::Tree::Notify.new(self, *args, &b) + end + + def notify_delete(id) + if id.kind_of?(Tk::BLT::Tree::Notify) + id.delete + else + tk_call(@path, 'notify', 'delete', id) + Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s) + end + self + end + + def notify_info(id) + lst = simplelist(tk_call(@path, 'notify', 'info', tagid(id))) + lst[0] = Tk::BLT::Tree::Notify.id2obj(self, lst[0]) + lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]} + lst[2] = tk_tcl2ruby(lst[2]) + lst + end + + def notify_names() + tk_call(@path, 'notify', 'names').collect{|id| + Tk::BLT::Tree::Notify.id2obj(self, id) + } + end + + def parent(node) + ret = tk_call('::blt::tree', 'parent', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def fullpath(node) + tk_call('::blt::tree', 'path', tagid(node)) + end + + def position(node) + number(tk_call('::blt::tree', 'position', tagid(node))) + end + + def previous(node) + ret = tk_call('::blt::tree', 'previous', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def prev_sibling(node) + ret = tk_call('::blt::tree', 'prevsibling', tagid(node)) + (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) + end + + def restore(node, str, keys={}) + tk_call('::blt::tree', 'restore', tagid(node), str, + __conv_keyonly_opts(keys)) + self + end + def restore_overwrite(node, str, keys={}) + keys = __conv_keyonly_opts(keys) + keys.delete('overwrite') + keys.delete(:overwrite) + tk_call('::blt::tree', 'restore', tagid(node), str, '-overwrite', keys) + self + end + + def restore_from_file(node, file, keys={}) + tk_call('::blt::tree', 'restorefile', tagid(node), file, + __conv_keyonly_opts(keys)) + self + end + def restore_overwrite_from_file(node, file, keys={}) + keys = __conv_keyonly_opts(keys) + keys.delete('overwrite') + keys.delete(:overwrite) + tk_call('::blt::tree', 'restorefile', tagid(node), file, + '-overwrite', keys) + self + end + + def root(node=None) + Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'root', + tagid(node))) + end + + def set(node, data) + unless data.kind_of?(Hash) + fail ArgumentError, 'Hash is expected for data' + end + args = [] + data.each{|k, v| args << k << v} + tk_call('::blt::tree', 'set', tagid(node), *args) + self + end + + def size(node) + number(tk_call('::blt::tree', 'size', tagid(node))) + end + + def sort(node, keys={}) + tk_call('::blt::tree', 'sort', tagid(node), __conv_keyonly_opts(keys)) + self + end + + def tag_add(tag, *nodes) + tk_call(@path, 'tag', 'add', tagid(tag), *(nodes.collect{|n| tagid(n)})) + self + end + + def tag_delete(tag, *nodes) + tk_call(@path, 'tag', 'delete', tagid(tag), + *(nodes.collect{|n| tagid(n)})) + self + end + + def tag_forget(tag) + tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag) + tk_call(@path, 'tag', 'forget', tag) + TreeTagID_TBL[@path].delete(tag) + self + end + + def tag_get(node, *patterns) + simplelist(tk_call(@tpath, 'tag', 'get', tagid(node), + *(patterns.collect{|pat| tagid(pat)}))).collect{|str| + Tk::BLT::Tree::Tag.id2obj(self, str) + } + end + + def tag_names(node = None) + simplelist(tk_call(@tpath, 'tag', 'names', tagid(node))).collect{|str| + Tk::BLT::Tree::Tag.id2obj(self, str) + } + end + + def tag_nodes(tag) + simplelist(tk_call(@tpath, 'tag', 'nodes', tagid(tag))).collect{|node| + Tk::BLT::Tree::Node.id2obj(self, node) + } + end + + def tag_set(node, *tags) + tk_call(@path, 'tag', 'set', tagid(node), *(tags.collect{|t| tagid(t)})) + self + end + + def tag_unset(node, *tags) + tk_call(@path, 'tag', 'unset', tagid(node), + *(tags.collect{|t| tagid(t)})) + self + end + + def trace_create(*args, &b) + Tk::BLT::Tree::Trace.new(self, *args, &b) + end + +=begin + def trace_delete(*args) + args.each{|id| + if id.kind_of?(Tk::BLT::Tree::Trace) + id.delete + else + tk_call(@path, 'trace', 'delete', id) + Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s) + end + self + } + end +=end + def trace_delete(*args) + args = args.collect{|id| tagid(id)} + tk_call(@path, 'trace', 'delete', *args) + args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)} + self + end + + def trace_info(id) + lst = simplelist(tk_call(@path, 'trace', 'info', tagid(id))) + lst[0] = Tk::BLT::Tree::Trace.id2obj(self, lst[0]) + lst[2] = simplelist(lst[2]) + lst[3] = tk_tcl2ruby(lst[3]) + lst + end + + def trace_names() + tk_call(@path, 'trace', 'names').collect{|id| + Tk::BLT::Tree::Trace.id2obj(self, id) + } + end + + def type(node, key) + tk_call('::blt::tree', 'type', tagid(node), key) + end + + def unset(node, *keys) + tk_call('::blt::tree', 'unset', tagid(node), *keys) + self + end + + def values(node, key=None) + simplelist(tk_call('::blt::tree', 'values', tagid(node), key)) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/treeview.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/treeview.rb new file mode 100644 index 0000000000..0343d28b9c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/treeview.rb @@ -0,0 +1,1146 @@ +# +# tkextlib/blt/treeview.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' +require 'tk/validation.rb' + +module Tk::BLT + class Treeview < TkWindow + module ConfigMethod + end + + module TagOrID_Methods + end + + class Node < TkObject + end + + class Tag < TkObject + end + end + + class Hiertable < Treeview + end +end + +###################################### + +module Tk::BLT::Treeview::ConfigMethod + include TkItemConfigMethod + + def __item_boolval_optkeys(id) + case id + when Array + # id := [ 'column', name ] + ['edit', 'hide'] + when 'sort' + ['decreasing'] + else + [] + end + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + case id + when Array + # id := [ 'column', name ] + super() << 'titleforeground' << 'titleshadow' + when 'sort' + ['decreasing'] + else + [] + end + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + case id + when 'entry' + ['bindtags'] + else + [] + end + end + private :__item_listval_optkeys + + def __item_cget_cmd(id) + if id.kind_of?(Array) + # id := [ type, name ] + [self.path, id[0], 'cget', id[1]] + else + [self.path, id, 'cget'] + end + end + private :__item_cget_cmd + + def __item_config_cmd(id) + if id.kind_of?(Array) + # id := [ type, name ] + [self.path, id[0], 'configure', id[1]] + else + [self.path, id, 'configure'] + end + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + id = tagid(id[1]) + end + [self.path, id].join(';') + end + private :__item_pathname + + def column_cget(name, option) + itemcget(['column', name], option) + end + def column_configure(name, slot, value=None) + itemconfigure(['column', name], slot, value) + end + def column_configinfo(name, slot=nil) + itemconfiginfo(['column', name], slot) + end + def current_column_configinfo(name, slot=nil) + current_itemconfiginfo(['column', name], slot) + end + + def button_cget(option) + itemcget('button', option) + end + def button_configure(slot, value=None) + itemconfigure('button', slot, value) + end + def button_configinfo(slot=nil) + itemconfiginfo('button', slot) + end + def current_button_configinfo(slot=nil) + current_itemconfiginfo('button', slot) + end + + def entry_cget(option) + ret = itemcget('entry', option) + if option == 'bindtags' || option == :bindtags + ret.collect{|tag| TkBindTag.id2obj(tag)} + else + ret + end + end + def entry_configure(slot, value=None) + itemconfigure('entry', slot, value) + end + def entry_configinfo(slot=nil) + ret = itemconfiginfo('entry', slot) + + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + if slot == 'bindtags' || slot == :bindtags + ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)} + ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)} + end + else + inf = ret.assoc('bindtags') + inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)} + inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)} + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if (inf = ret['bindtags']) + inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)} + inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)} + ret['bindtags'] = inf + end + end + + ret + end + def current_entry_configinfo(slot=nil) + ret = current_itemconfiginfo('entry', slot) + + if (val = ret['bindtags']) + ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)} + end + + ret + end + + def sort_cget(option) + itemcget('sort', option) + end + def sort_configure(slot, value=None) + itemconfigure('sort', slot, value) + end + def sort_configinfo(slot=nil) + itemconfiginfo('sort', slot) + end + def current_sort_configinfo(slot=nil) + current_itemconfiginfo('sort', slot) + end + + def text_cget(option) + itemcget('text', option) + end + def text_configure(slot, value=None) + itemconfigure('text', slot, value) + end + def text_configinfo(slot=nil) + itemconfiginfo('text', slot) + end + def current_text_configinfo(slot=nil) + current_itemconfiginfo('text', slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class Tk::BLT::Treeview + TkCommandNames = ['::blt::treeview'.freeze].freeze + WidgetClassName = 'TreeView'.freeze + WidgetClassNames[WidgetClassName] = self + + include Scrollable + include ValidateConfigure + include ItemValidateConfigure + include Tk::BLT::Treeview::ConfigMethod + + ######################## + + def __boolval_optkeys + ['autocreate', 'allowduplicates', 'exportselection', 'flat', 'hideroot', + 'newtags', 'showtitles', 'sortselection'] + end + private :__boolval_optkeys + + def __strval_optkeys + super() + ['focusforeground', 'linecolor', 'separator', 'trim'] + end + private :__strval_optkeys + + ######################## + + class OpenCloseCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?W, ?w, :widget ], + [ ?p, ?s, :name ], + [ ?P, ?s, :fullpath ], + [ ?#, ?x, :node_id ], + nil + ] + + PROC_TBL = [ + [ ?x, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + ['opencommand', 'closecomand'] + end + end + + def __validation_class_list + super() << OpenCloseCommand + end + + Tk::ValidateConfigure.__def_validcmd(binding, OpenCloseCommand) + + ######################## + + def __item_validation_class_list(id) + case id + when 'entry' + super(id) << OpenCloseCommand + else + super(id) + end + end + + Tk::ItemValidateConfigure.__def_validcmd(binding, OpenCloseCommand) + + ######################## + + def __destroy_hook__ + Tk::BLT::Treeview::Node::TreeNodeID_TBL.delete(@path) + Tk::BLT::Treeview::Tag::TreeTagID_TBL.delete(@path) + end + + def tagid(tag) + if tag.kind_of?(Tk::BLT::Treeview::Node) \ + || tag.kind_of?(Tk::BLT::Treeview::Tag) + tag.id + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + def tagid2obj(tagid) + if tagid.kind_of?(Integer) + Tk::BLT::Treeview::Node.id2obj(self, tagid.to_s) + elsif tagid.kind_of?(String) + if tagid =~ /^\d+$/ + Tk::BLT::Treeview::Node.id2obj(self, tagid) + else + Tk::BLT::Treeview::Tag.id2obj(self, tagid) + end + else + tagid + end + end + + def bbox(*tags) + list(tk_send('bbox', *(tags.collect{|tag| tagid(tag)}))) + end + + def screen_bbox(*tags) + list(tk_send('bbox', '-screen', *(tags.collect{|tag| tagid(tag)}))) + end + + def tag_bind(tag, seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'bind', tagid(tag)], seq, cmd, *args) + self + end + def tag_bind_append(tag, seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'bind', tagid(tag)], seq, cmd, *args) + self + end + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'bind', tagid(tag)], seq) + self + end + def tag_bindinfo(tag, seq=nil) + _bindinfo([@path, 'bind', tagid(tag)], seq) + end + + def button_activate(tag) + tk_send('button', 'activate', tagid(tag)) + self + end + + def button_bind(tag, seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'button', 'bind', tagid(tag)], seq, cmd, *args) + self + end + def button_bind_append(tag, seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'button', 'bind', tagid(tag)], seq, cmd, *args) + self + end + def button_bind_remove(tag, seq) + _bind_remove([@path, 'button', 'bind', tagid(tag)], seq) + self + end + def button_bindinfo(tag, seq=nil) + _bindinfo([@path, 'button', 'bind', tagid(tag)], seq) + end + + def close(*tags) + tk_send('close', *(tags.collect{|tag| tagid(tag)})) + self + end + def close_recurse(*tags) + tk_send('close', '-recurse', *(tags.collect{|tag| tagid(tag)})) + self + end + + def column_activate(column=None) + if column == None + tk_send('column', 'activate') + else + tk_send('column', 'activate', column) + self + end + end + + def column_delete(*fields) + tk_send('column', 'delete', *fields) + self + end + def column_insert(pos, field, *opts) + tk_send('column', 'insert', pos, field, *opts) + self + end + def column_invoke(field) + tk_send('column', 'invoke', field) + self + end + def column_move(name, dest) + tk_send('column', 'move', name, dest) + self + end + def column_names() + simplelist(tk_send('column', 'names')) + end + def column_nearest(x, y=None) + tk_send('column', 'nearest', x, y) + end + + def curselection + simplelist(tk_send('curselection')).collect{|id| tagid2obj(id)} + end + + def delete(*tags) + tk_send('delete', *(tags.collect{|tag| tagid(tag)})) + self + end + + def entry_activate(tag) + tk_send('entry', 'activate', tagid(tag)) + self + end + def entry_children(tag, first=None, last=None) + simplelist(tk_send('entry', 'children', tagid(tag), + first, last)).collect{|id| tagid2obj(id)} + end + def entry_delete(tag, first=None, last=None) + tk_send('entry', 'delete', tagid(tag), first, last) + end + def entry_before?(tag1, tag2) + bool(tk_send('entry', 'isbefore', tagid(tag1), tagid(tag2))) + end + def entry_hidden?(tag) + bool(tk_send('entry', 'ishidden', tagid(tag))) + end + def entry_open?(tag) + bool(tk_send('entry', 'isopen', tagid(tag))) + end + + def entry_size(tag) + number(tk_send('entry', 'size', tagid(tag))) + end + def entry_size_recurse(tag) + number(tk_send('entry', 'size', '-recurse', tagid(tag))) + end + + def _search_flags(keys) + keys = _symbolkey2str(keys) + keys['exact'] = None if keys.delete('exact') + keys['glob'] = None if keys.delete('glob') + keys['regexp'] = None if keys.delete('regexp') + keys['nonmatching'] = None if keys.delete('nonmatching') + end + private :_search_flags + + ################################ + + class FindExecFlagValue < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?W, ?w, :widget ], + [ ?p, ?s, :name ], + [ ?P, ?s, :fullpath ], + [ ?#, ?x, :node_id ], + nil + ] + + PROC_TBL = [ + [ ?x, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + [] + end + end + + def _find_exec_flag_value(val) + if val.kind_of?(Array) + cmd, *args = val + FindExecFlagValue.new(cmd, args.join(' ')) + elsif TkComm._callback_entry?(val) + FindExecFlagValue.new(val) + else + val + end + end + + ################################ + + def find(first, last, keys={}) + keys = _search_flags(keys) + keys['exec'] = _find_exec_flag_value(keys['exec']) if keys.key?('exec') + args = hash_kv(keys) << '--' << tagid(first) << tagid(last) + simplelist(tk_send('find', *args)).collect{|id| tagid2obj(id)} + end + + def tag_focus(tag) + tk_send('focus', tagid(tag)) + self + end + def get(*tags) + simplelist(tk_send('get', *(tags.collect{|tag| tagid(tag)}))) + end + def get_full(*tags) + simplelist(tk_send('get', '-full', *(tags.collect{|tag| tagid(tag)}))) + end + + def hide(*tags) + if tags[-1].kind_of?(Hash) + keys = tags.pop + else + keys = {} + end + keys = _search_flags(keys) + args = hash_kv(keys) << '--' + args.concat(tags.collect{|t| tagid(t)}) + tk_send('hide', *args) + self + end + + def index(str) + tagid2obj(tk_send('index', str)) + end + def index_at(tag, str) + tagid2obj(tk_send('index', '-at', tagid(tag), str)) + end + def index_at_path(tag, str) + tagid2obj(tk_send('index', '-at', tagid(tag), '-path', str)) + end + + def insert(pos, parent=nil, keys={}) + Tk::BLT::Treeview::Node.new(pos, parent, keys) + end + def insert_at(tag, pos, parent=nil, keys={}) + if parent.kind_of?(Hash) + keys = parent + parent = nil + end + + keys = _symbolkey2str(keys) + keys['at'] = tagid(tag) + + Tk::BLT::Treeview::Node.new(pos, parent, keys) + end + + def move_before(tag, dest) + tk_send('move', tagid(tag), 'before', tagid(dest)) + self + end + def move_after(tag, dest) + tk_send('move', tagid(tag), 'after', tagid(dest)) + self + end + def move_into(tag, dest) + tk_send('move', tagid(tag), 'into', tagid(dest)) + self + end + + def nearest(x, y, var=None) + tagid2obj(tk_send('nearest', x, y, var)) + end + + def open(*tags) + tk_send('open', *(tags.collect{|tag| tagid(tag)})) + self + end + def open_recurse(*tags) + tk_send('open', '-recurse', *(tags.collect{|tag| tagid(tag)})) + self + end + + def range(first, last) + simplelist(tk_send('range', tagid(first), tagid(last))).collect{|id| + tagid2obj(id) + } + end + def range_open(first, last) + simplelist(tk_send('range', '-open', + tagid(first), tagid(last))).collect{|id| + tagid2obj(id) + } + 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 see(tag) + tk_send_without_enc('see', tagid(tag)) + self + end + def see_anchor(anchor, tag) + tk_send_without_enc('see', '-anchor', anchor, tagid(tag)) + self + end + + def selection_anchor(tag) + tk_send_without_enc('selection', 'anchor', tagid(tag)) + self + end + def selection_cancel() + tk_send_without_enc('selection', 'cancel') + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', tagid(first), tagid(last)) + self + end + def selection_clear_all() + tk_send_without_enc('selection', 'clearall') + self + end + def selection_mark(tag) + tk_send_without_enc('selection', 'mark', tagid(tag)) + self + end + def selection_include?(tag) + bool(tk_send('selection', 'include', tagid(tag))) + end + def selection_present?() + bool(tk_send('selection', 'present')) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', tagid(first), tagid(last)) + self + end + def selection_toggle(first, last=None) + tk_send_without_enc('selection', 'toggle', tagid(first), tagid(last)) + self + end + + def show(*tags) + if tags[-1].kind_of?(Hash) + keys = tags.pop + else + keys = {} + end + keys = _search_flags(keys) + args = hash_kv(keys) << '--' + args.concat(tags.collect{|t| tagid(t)}) + tk_send('show', *args) + self + end + + def sort_auto(mode) + tk_send('sort', 'auto', mode) + self + end + def sort_auto=(mode) + tk_send('sort', 'auto', mode) + mode + end + def sort_auto? + bool(tk_send('sort', 'auto')) + end + def sort_once(*tags) + tk_send('sort', 'once', *(tags.collect{|tag| tagid(tag)})) + self + end + def sort_once_recurse(*tags) + tk_send('sort', 'once', '-recurse', *(tags.collect{|tag| tagid(tag)})) + self + end + + def tag_add(tag, *ids) + tk_send('tag', 'add', tagid(tag), *ids) + self + end + def tag_delete(tag, *ids) + tk_send('tag', 'delete', tagid(tag), *ids) + self + end + def tag_forget(tag) + tk_send('tag', 'forget', tagid(tag)) + self + end + def tag_names(id=nil) + id = (id)? tagid(id): None + + simplelist(tk_send('tag', 'nodes', id)).collect{|tag| + Tk::BLT::Treeview::Tag.id2obj(self, tag) + } + end + def tag_nodes(tag) + simplelist(tk_send('tag', 'nodes', tagid(tag))).collect{|id| + Tk::BLT::Treeview::Node.id2obj(self, id) + } + end + + def text_apply + tk_send('text', 'apply') + self + end + def text_cancel + tk_send('text', 'cancel') + self + end + + def text_delete(first, last) + tk_send('text', 'delete', first, last) + self + end + def text_get(x, y) + tk_send('text', 'get', x, y) + end + def text_get_root(x, y) + tk_send('text', 'get', '-root', x, y) + end + def text_icursor(idx) + tk_send('text', 'icursor', idx) + self + end + def text_index(idx) + num_or_str(tk_send('text', 'index', idx)) + end + def text_insert(idx, str) + tk_send('text', 'insert', idx, str) + self + end + + def text_selection_adjust(idx) + tk_send('text', 'selection', 'adjust', idx) + self + end + def text_selection_clear + tk_send('text', 'selection', 'clear') + self + end + def text_selection_from(idx) + tk_send('text', 'selection', 'from', idx) + self + end + def text_selection_present + num_or_str(tk_send('text', 'selection', 'present')) + end + def text_selection_range(start, last) + tk_send('text', 'selection', 'range', start, last) + self + end + def text_selection_to(idx) + tk_send('text', 'selection', 'to', idx) + self + end + + def toggle(tag) + tk_send('toggle', tagid(tag)) + self + end +end + +###################################### + +module Tk::BLT::Treeview::TagOrID_Methods + def bbox + @tree.bbox(self) + end + def screen_bbox + @tree.screen_bbox(self) + end + + def bind(seq, *args) + @tree.tag_bind(self, seq, *args) + self + end + def bind_append(seq, *args) + @tree.tag_bind_append(self, seq, *args) + self + end + def bind_remove(seq) + @tree.tag_bind_remove(self, seq) + self + end + def bindinfo(seq=nil) + @tree.tag_bindinfo(self, seq) + end + + def button_activate + @tree.button_activate(self) + self + end + + def button_bind(seq, *args) + @tree.button_bind(self, seq, *args) + self + end + def button_bind_append(seq, *args) + @tree.button_bind_append(self, seq, *args) + self + end + def button_bind_remove(seq) + @tree.button_bind_remove(self, seq) + self + end + def button_bindinfo(seq=nil) + @tree.button_bindinfo(self, seq) + end + + def close + @tree.close(self) + self + end + def close_recurse + @tree.close_recurse(self) + self + end + + def delete + @tree.delete(self) + self + end + + def entry_activate + @tree.entry_activate(self) + self + end + def entry_children(first=None, last=None) + @tree.entry_children(self, first, last) + end + def entry_delete(first=None, last=None) + @tree.entry_delete(self, first, last) + end + def entry_before?(tag) + @tree.entry_before?(self, tag) + end + def entry_hidden? + @tree.entry_before?(self) + end + def entry_open? + @tree.entry_open?(self) + end + + def entry_size + @tree.entry_size(self) + end + def entry_size_recurse + @tree.entry_size_recurse(self) + end + + def focus + @tree.tag_focus(self) + self + end + + def get + @tree.get(self) + end + def get_full + @tree.get_full(self) + end + + def hide + @tree.hide(self) + self + end + + def index(str) + @tree.index_at(self, str) + end + def index_path(str) + @tree.index_at_path(self, str) + end + + def insert(pos, parent=nil, keys={}) + @tree.insert_at(self, pos, parent, keys) + end + + def move_before(dest) + @tree.move_before(self, dest) + self + end + def move_after(dest) + @tree.move_after(self, dest) + self + end + def move_into(dest) + @tree.move_into(self, dest) + self + end + + def open + @tree.open(self) + self + end + def open_recurse + @tree.open_recurse(self) + self + end + + def range_to(tag) + @tree.range(self, tag) + end + def range_open_to(tag) + @tree.range(self, tag) + end + + def see + @tree.see(self) + self + end + def see_anchor(anchor) + @tree.see_anchor(anchor, self) + self + end + + def selection_anchor + @tree.selection_anchor(self) + self + end + def selection_clear + @tree.selection_clear(self) + self + end + def selection_mark + @tree.selection_mark(self) + self + end + def selection_include? + @tree.selection_include?(self) + end + def selection_set + @tree.selection_set(self) + self + end + def selection_toggle + @tree.selection_toggle(self) + self + end + + def show + @tree.show(self) + self + end + + def sort_once + @tree.sort_once(self) + self + end + def sort_once_recurse + @tree.sort_once_recurse(self) + self + end + + def toggle + @tree.toggle(self) + self + end +end + +###################################### + +class Tk::BLT::Treeview::Node < TkObject + include Tk::BLT::Treeview::TagOrID_Methods + + TreeNodeID_TBL = TkCore::INTERP.create_table + TreeNode_ID = ['blt_treeview_node'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TreeNodeID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeNodeID_TBL[tpath] + if TreeNodeID_TBL[tpath][id] + TreeNodeID_TBL[tpath][id] + else + begin + self.new(tree, nil, nil, 'node'=>Integer(id)) + rescue + id + end + end + end + + def self.new(tree, pos, parent=nil, keys={}) + if parent.kind_of?(Hash) + keys = parent + parent = nil + end + + keys = _symbolkey2str(keys) + tpath = tree.path + + if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id]) + keys.delete('node') + tk_call(tree.path, 'move', id, pos, parent) if parent + return obj + end + + super(tree, pos, parent, keys) + end + + def initialize(tree, pos, parent, keys) + @parent = @tree = tree + @tpath = @parent.path + + if (id = keys['node']) + @path = @id = id + tk_call(@tpath, 'move', @id, pos, tagid(parent)) if parent + else + name = TreeNode_ID.join(TkCore::INTERP._ip_id_).freeze + TreeNode_ID[1].succ! + + at = keys.delete['at'] + + if parent + if parent.kind_of?(Tk::BLT::Treeview::Node) || + parent.kind_of?(Tk::BLT::Treeview::Tag) + path = [get_full(parent.id)[0], name] + at = nil # ignore 'at' option + else + path = [parent.to_s, name] + end + else + path = name + end + + if at + @id = tk_call(@tpath, 'insert', '-at', tagid(at), pos, path, keys) + else + @id = tk_call(@tpath, 'insert', pos, path, keys) + end + @path = @id + end + + TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath] + TreeNodeID_TBL[@tpath][@id] = self + end + + def id + @id + end +end + +###################################### + +class Tk::BLT::Treeview::Tag < TkObject + include Tk::BLT::Treeview::TagOrID_Methods + + TreeTagID_TBL = TkCore::INTERP.create_table + TreeTag_ID = ['blt_treeview_tag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TreeTagID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeTagID_TBL[tpath] + if TreeTagID_TBL[tpath][id] + TreeTagID_TBL[tpath][id] + else + begin + self.new(tree, nil, nil, 'name'=>Integer(id)) + rescue + id + end + end + end + + def self.new_by_name(tree, name, *ids) + if (obj = TreeTagID_TBL[tree.path][name]) + return obj + end + new([tree, name], ids) + end + + def self.new(tree, *ids) + if tree.kind_of?(Array) + super(tree[0], tree[1], ids) + else + super(tree, nil, ids) + end + end + + def initialize(tree, name, ids) + @parent = @tree = tree + @tpath = @parent.path + + if name + @path = @id = name + else + @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_).freeze + TreeTag_ID[1].succ! + end + + TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] + TreeTagID_TBL[@tpath][@id] = self + + unless ids.empty? + tk_call(@tpath, 'tag', 'add', @id, *(ids.collect{|id| tagid(id)})) + end + end + + def tagid(tag) + if tag.kind_of?(Tk::BLT::Treeview::Node) \ + || tag.kind_of?(Tk::BLT::Treeview::Tag) + tag.id + else + tag + end + end + private :tagid + + def id + @id + end + + def add(*ids) + tk_call(@tpath, 'tag', 'add', @id, *(ids{|id| tagid(id)})) + self + end + + def remove(*ids) + tk_call(@tpath, 'tag', 'delete', @id, *(ids{|id| tagid(id)})) + self + end + + def forget + tk_call(@tpath, 'tag', 'forget', @id) + self + end + + def nodes + simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|id| + Tk::BLT::Treeview::Node.id2obj(@tree, id) + } + end +end + +class Tk::BLT::Hiertable + TkCommandNames = ['::blt::hiertable'.freeze].freeze + WidgetClassName = 'Hiertable'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/unix_dnd.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/unix_dnd.rb new file mode 100644 index 0000000000..3130c1e56f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/unix_dnd.rb @@ -0,0 +1,129 @@ +# +# tkextlib/blt/unix_dnd.rb +# +# *** This is alpha version, because there is no document on BLT. *** +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module DnD + extend TkCore + + TkCommandNames = ['::blt::dnd'.freeze].freeze + + ############################## + + extend TkItemConfigMethod + + class << self + def __item_cget_cmd(id) + ['::blt::dnd', *id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + ['::blt::dnd', *id] + end + private :__item_config_cmd + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + def cget(win, option) + itemconfigure(['cget', win], slot, value) + end + def configure(win, slot, value=None) + itemconfigure(['configure', win], slot, value) + end + def configinfo(win, slot=nil) + itemconfiginfo(['configure', win], slot) + end + def current_configinfo(win, slot=nil) + current_itemconfiginfo(['configure', win], slot) + end + + def tokwn_cget(win, option) + itemconfigure(['token', 'cget', win], slot, value) + end + def token_configure(win, slot, value=None) + itemconfigure(['token', 'configure', win], slot, value) + end + def token_configinfo(win, slot=nil) + itemconfiginfo(['token', 'configure', win], slot) + end + def current_token_configinfo(win, slot=nil) + current_itemconfiginfo(['token', 'configure', win], slot) + end + + def token_windowconfigure(win, slot, value=None) + itemconfigure(['token', 'window', win], slot, value) + end + def token_windowconfiginfo(win, slot=nil) + itemconfiginfo(['token', 'window', win], slot) + end + def current_token_windowconfiginfo(win, slot=nil) + current_itemconfiginfo(['token', 'window', win], slot) + end + end + + ############################## + + def self.cancel(win) + tk_call('::blt::dnd', 'cancel', *wins) + end + def self.delete(*wins) + tk_call('::blt::dnd', 'delete', *wins) + end + def self.delete_source(*wins) + tk_call('::blt::dnd', 'delete', '-source', *wins) + end + def self.delete_target(*wins) + tk_call('::blt::dnd', 'delete', '-target', *wins) + end + def self.drag(win, x, y, token=None) + tk_call('::blt::dnd', 'drag', win, x, y, token) + end + def self.drop(win, x, y, token=None) + tk_call('::blt::dnd', 'drop', win, x, y, token) + end + def self.get_data(win, fmt=nil, cmd=nil) + if fmt + tk_call('::blt::dnd', 'getdata', win, fmt, cmd) + else + list(tk_call('::blt::dnd', 'getdata', win)) + end + end + def self.names(pat=None) + list(tk_call('::blt::dnd', 'names', pat)) + end + def self.source_names(pat=None) + list(tk_call('::blt::dnd', 'names', '-source', pat)) + end + def self.target_names(pat=None) + list(tk_call('::blt::dnd', 'names', '-target', pat)) + end + def self.pull(win, fmt) + tk_call('::blt::dnd', 'pull', win, fmt) + end + def self.register(win, keys={}) + tk_call('::blt::dnd', 'register', win, keys) + end + def self.select(win, x, y, timestamp) + tk_call('::blt::dnd', 'select', win, x, y, timestamp) + end + def self.set_data(win, fmt=nil, cmd=nil) + if fmt + tk_call('::blt::dnd', 'setdata', win, fmt, cmd) + else + list(tk_call('::blt::dnd', 'setdata', win)) + end + end + def self.token(*args) + tk_call('::blt::dnd', 'token', *args) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/vector.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/vector.rb new file mode 100644 index 0000000000..540b6b9102 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/vector.rb @@ -0,0 +1,243 @@ +# +# tkextlib/blt/vector.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Vector < TkVariable + TkCommandNames = ['::blt::vector'.freeze].freeze + + def self.create(*args) + tk_call('::blt::vector', 'create', *args) + end + + def self.destroy(*args) + tk_call('::blt::vector', 'destroy', *args) + end + + def self.expr(expression) + tk_call('::blt::vector', 'expr', expression) + end + + def self.names(pat=None) + simplelist(tk_call('::blt::vector', 'names', pat)).collect{|name| + if TkVar_ID_TBL[name] + TkVar_ID_TBL[name] + elsif name[0..1] == '::' && TkVar_ID_TBL[name[2..-1]] + TkVar_ID_TBL[name[2..-1]] + else + name + end + } + end + + #################################### + + def initialize(size=nil, keys={}) + if size.kind_of?(Hash) + keys = size + size = nil + end + if size.kind_of?(Array) + # [first, last] + size = size.join(':') + end + if size + @id = INTERP._invoke('::blt::vector', 'create', + "#auto(#{size})", *hash_kv(keys)) + else + @id = INTERP._invoke('::blt::vector', 'create', + "#auto", *hash_kv(keys)) + end + + TkVar_ID_TBL[@id] = self + + @def_default = false + @default_val = nil + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @id) + end + + def destroy + tk_call('::blt::vector', 'destroy', @id) + end + + def inspect + '#<Tk::BLT::Vector: ' + @id + '>' + end + + def to_s + @id + end + + def *(item) + list(tk_call(@id, '*', item)) + end + + def +(item) + list(tk_call(@id, '+', item)) + end + + def -(item) + list(tk_call(@id, '-', item)) + end + + def /(item) + list(tk_call(@id, '/', item)) + end + + def append(*vectors) + tk_call(@id, 'append', *vectors) + end + + def binread(channel, len=None, keys={}) + if len.kind_of?(Hash) + keys = len + len = None + end + keys = _symbolkey2str(keys) + keys['swap'] = None if keys.delete('swap') + tk_call(@id, 'binread', channel, len, keys) + end + + def clear() + tk_call(@id, 'clear') + self + end + + def delete(*indices) + tk_call(@id, 'delete', *indices) + self + end + + def dup_vector(vec) + tk_call(@id, 'dup', vec) + self + end + + def expr(expression) + tk_call(@id, 'expr', expression) + self + end + + def index(idx, val=None) + number(tk_call(@id, 'index', idx, val)) + end + + def [](idx) + index(idx) + end + + def []=(idx, val) + index(idx, val) + end + + def length() + number(tk_call(@id, 'length')) + end + + def length=(size) + number(tk_call(@id, 'length', size)) + end + + def merge(*vectors) + tk_call(@id, 'merge', *vectors) + self + end + + def normalize(vec=None) + tk_call(@id, 'normalize', vec) + self + end + + def notify(keyword) + tk_call(@id, 'notify', keyword) + self + end + + def offset() + number(tk_call(@id, 'offset')) + end + + def offset=(val) + number(tk_call(@id, 'offset', val)) + end + + def random() + tk_call(@id, 'random') + end + + def populate(vector, density=None) + tk_call(@id, 'populate', vector, density) + self + end + + def range(first, last=None) + list(tk_call(@id, 'range', first, last)) + end + + def search(val1, val2=None) + list(tk_call(@id, 'search', val1, val2)) + end + + def set(item) + tk_call(@id, 'set', item) + self + end + + def seq(start, finish=None, step=None) + tk_call(@id, 'seq', start, finish, step) + self + end + + def sort(*vectors) + tk_call(@id, 'sort', *vectors) + self + end + + def sort_reverse(*vectors) + tk_call(@id, 'sort', '-reverse', *vectors) + self + end + + def split(*vectors) + tk_call(@id, 'split', *vectors) + self + end + + def variable(var) + tk_call(@id, 'variable', var) + self + end + end + + class VectorAccess < Vector + def self.new(name) + return TkVar_ID_TBL[name] if TkVar_ID_TBL[name] + super(name, size=nil, keys={}) + end + + def initialize(vec_name) + @id = vec_name + TkVar_ID_TBL[@id] = self + + @def_default = false + @default_val = nil + + @trace_var = nil + @trace_elem = nil + @trace_opts = nil + + # teach Tk-ip that @id is global var + INTERP._invoke_without_enc('global', @id) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/watch.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/watch.rb new file mode 100644 index 0000000000..ae5e50f126 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/watch.rb @@ -0,0 +1,142 @@ +# +# tkextlib/blt/watch.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Watch < TkObject + extend TkCore + + TkCommandNames = ['::blt::watch'.freeze].freeze + + WATCH_ID_TBL = TkCore::INTERP.create_table + BLT_WATCH_ID = ['blt_watch_id'.freeze, '00000'.taint].freeze + + def self.names(state = None) + tk_split_list(tk_call('::blt::watch', 'names', state)).collect{|name| + WATCH_ID_TBL[name] || name + } + end + + def __numval_optkeys + ['maxlevel'] + end + private :__numval_optkeys + + def __boolval_optkeys + ['active'] + end + private :__boolval_optkeys + + def __config_cmd + ['::blt::watch', 'configure', self.path] + end + private :__config_cmd + + def initialize(name = nil, keys = {}) + if name.kind_of?(Hash) + keys = name + name = nil + end + + if name + @id = name.to_s + else + @id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_) + BLT_WATCH_ID[1].succ! + end + + @path = @id + + WATCH_ID_TBL[@id] = self + tk_call('::blt::watch', 'create', @id, *hash_kv(keys)) + end + + def activate + tk_call('::blt::watch', 'activate', @id) + self + end + def deactivate + tk_call('::blt::watch', 'deactivate', @id) + self + end + def delete + tk_call('::blt::watch', 'delete', @id) + self + end + def info + ret = [] + lst = tk_split_simplelist(tk_call('::blt::watch', 'info', @id)) + until lst.empty? + k, v, *lst = lst + k = k[1..-1] + case k + when /^(#{__strval_optkeys.join('|')})$/ + # do nothing + + when /^(#{__numval_optkeys.join('|')})$/ + begin + v = number(v) + rescue + v = nil + end + + when /^(#{__numstrval_optkeys.join('|')})$/ + v = num_or_str(v) + + when /^(#{__boolval_optkeys.join('|')})$/ + begin + v = bool(v) + rescue + v = nil + end + + when /^(#{__listval_optkeys.join('|')})$/ + v = simplelist(v) + + when /^(#{__numlistval_optkeys.join('|')})$/ + v = list(v) + + else + if v.index('{') + v = tk_split_list(v) + else + v = tk_tcl2ruby(v) + end + end + + ret << [k, v] + end + + ret + end + def configinfo(slot = nil) + if slot + slot = slot.to_s + v = cget(slot) + if TkComm::GET_CONFIGINFO_AS_ARRAY + [slot, v] + else + {slot=>v} + end + else + if TkComm::GET_CONFIGINFO_AS_ARRAY + info + else + Hash[*(info.flatten)] + end + end + end + def cget(key) + key = key.to_s + begin + info.assoc(key)[1] + rescue + fail ArgumentError, "unknown option '#{key}'" + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/win_printer.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/win_printer.rb new file mode 100644 index 0000000000..7ac6a0dcfc --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/win_printer.rb @@ -0,0 +1,61 @@ +# +# tkextlib/blt/win_printer.rb +# +# *** Windows only *** +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + class Printer < TkObject + extend TkCore + + TkCommandNames = ['::blt::printer'.freeze].freeze + + def self.enum(attribute) + simplelist(tk_call('::blt::printer', 'enum', attribute)) + end + + def self.names(pat=None) + simplelist(tk_call('::blt::printer', 'names', pat)) + end + + def self.open(printer) + self.new(printer) + end + + ################################# + + def initialize(printer) + @printer_id = tk_call('::blt::printer', 'open', printer) + end + + def close + tk_call('::blt::print', 'close', @printer_id) + self + end + def get_attrs(var) + tk_call('::blt::print', 'getattrs', @printer_id, var) + var + end + def set_attrs(var) + tk_call('::blt::print', 'setattrs', @printer_id, var) + self + end + def snap(win) + tk_call('::blt::print', 'snap', @printer_id, win) + self + end + def write(str) + tk_call('::blt::print', 'write', @printer_id, str) + self + end + def write_with_title(title, str) + tk_call('::blt::print', 'write', @printer_id, title, str) + self + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/blt/winop.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/winop.rb new file mode 100644 index 0000000000..e371d28ab7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/blt/winop.rb @@ -0,0 +1,107 @@ +# +# tkextlib/blt/winop.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/blt.rb' + +module Tk::BLT + module Winop + extend TkCore + + TkCommandNames = ['::blt::winop'.freeze].freeze + end + WinOp = Winop +end + +class << Tk::BLT::Winop + def changes(win) + tk_call('::blt::winop', 'changes', win) + end + + def colormap(win) + Hash[*list(tk_call('::blt::winop', 'colormap', win))] + end + + def convolve(src, dest, filter) + tk_call('::blt::winop', 'convolve', src, dest, filter) + end + + def image_convolve(src, dest, filter) + tk_call('::blt::winop', 'image', 'convolve', src, dest, filter) + end + def image_gradient(photo, left, right, type) + tk_call('::blt::winop', 'image', 'gradient', photo, left, right, type) + end + def image_read_jpeg(file, photo) + tk_call('::blt::winop', 'image', 'readjpeg', file, photo) + end + def image_resample(src, dest, horiz_filter=None, vert_filter=None) + tk_call('::blt::winop', 'image', 'resample', + src, dest, horiz_filter, vert_filter) + end + def image_rotate(src, dest, angle) + tk_call('::blt::winop', 'image', 'rotate', src, dest, angle) + end + def image_snap(win, photo, width=None, height=None) + tk_call('::blt::winop', 'image', 'snap', win, photo, width, height) + end + def image_subsample(src, dest, x, y, width, height, + horiz_filter=None, vert_filter=None) + tk_call('::blt::winop', 'image', 'subsample', + src, dest, x, y, width, height, horiz_filter, vert_filter) + end + + def quantize(src, dest, colors) + tk_call('::blt::winop', 'quantize', src, dest, colors) + end + + def query() + tk_call('::blt::winop', 'query') + end + + def read_jpeg(file, photo) + tk_call('::blt::winop', 'readjpeg', file, photo) + end + + def resample(src, dest, horiz_filter=None, vert_filter=None) + tk_call('::blt::winop', 'resample', + src, dest, horiz_filter, vert_filter) + end + + def subsample(src, dest, x, y, width, height, + horiz_filter=None, vert_filter=None) + tk_call('::blt::winop', 'subsample', + src, dest, x, y, width, height, horiz_filter, vert_filter) + end + + def raise(*wins) + tk_call('::blt::winop', 'raise', *wins) + end + + def lower(*wins) + tk_call('::blt::winop', 'lower', *wins) + end + + def map(*wins) + tk_call('::blt::winop', 'map', *wins) + end + + def unmap(*wins) + tk_call('::blt::winop', 'unmap', *wins) + end + + def move(win, x, y) + tk_call('::blt::winop', 'move', win, x, y) + end + + def snap(win, photo) + tk_call('::blt::winop', 'snap', win, photo) + end + + def warpto(win = None) + tk_call('::blt::winop', 'warpto', win) + end + alias warp_to warpto +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget.rb new file mode 100644 index 0000000000..62631d8b54 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget.rb @@ -0,0 +1,151 @@ +# +# BWidget extension support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/bwidget/setup.rb' + +# load all image format handlers +#TkPackage.require('BWidget', '1.7') +TkPackage.require('BWidget') + +module Tk + module BWidget + TkComm::TkExtlibAutoloadModule.unshift(self) + + extend TkCore + + LIBRARY = tk_call('set', '::BWIDGET::LIBRARY') + + PACKAGE_NAME = 'BWidget'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('BWidget') + rescue + '' + end + end + + def self.XLFDfont(cmd, *args) + if args[-1].kind_of?(Hash) + keys = args.pop + args.concat(hash_kv(keys)) + end + tk_call('BWidget::XLFDfont', cmd, *args) + end + + def self.assert(exp, msg=None) + tk_call('BWidget::assert', exp, msg) + end + + def self.badOptionString(type, value, list) + tk_call('BWidget::badOptionString', type, value, list) + end + + def self.bindMouseWheel(widget) + tk_call('BWidget::bindMouseWheel', widget) + end + + def self.classes(klass) + list(tk_call('BWidget::classes', klass)) + end + + def self.clonename(menu) + tk_call('BWidget::clonename', menu) + end + + def self.focus(opt, path) + tk_call('BWidget::focus', opt, path) + end + + def self.get3dcolor(path, bgcolor) + tk_call('BWidget::get3dcolor', path, bgcolor) + end + + def self.getname(name) + tk_call('BWidget::getname', name) + end + + def self.grab(opt, path) + tk_call('BWidget::grab', opt, path) + end + + def self.inuse(klass) + bool(tk_call('BWidget::inuse', klass)) + end + + def self.library(klass, *klasses) + tk_call('BWidget::library', klass, *klasses) + end + + def self.lreorder(list, neworder) + tk_call('BWidget::lreorder', list, neworder) + end + + def self.parsetext(text) + tk_call('BWidget::parsetext', text) + end + + def self.place(path, w, h, *args) + if args[-1].kind_of?(Hash) + keys = args.pop + args.concat(hash_kv(keys)) + end + tk_call('BWidget::place', path, w, h, *(args.flatten)) + end + + def self.write(file, mode=None) + tk_call('BWidget::write', file, mode) + end + + def self.wrongNumArgsString(str) + tk_call('BWidget::wrongNumArgsString', str) + end + + #################################################### + + autoload :ArrowButton, 'tkextlib/bwidget/arrowbutton' + autoload :Bitmap, 'tkextlib/bwidget/bitmap' + autoload :Button, 'tkextlib/bwidget/button' + autoload :ButtonBox, 'tkextlib/bwidget/buttonbox' + autoload :ComboBox, 'tkextlib/bwidget/combobox' + autoload :Dialog, 'tkextlib/bwidget/dialog' + autoload :DragSite, 'tkextlib/bwidget/dragsite' + autoload :DropSite, 'tkextlib/bwidget/dropsite' + autoload :DynamicHelp, 'tkextlib/bwidget/dynamichelp' + autoload :Entry, 'tkextlib/bwidget/entry' + autoload :Label, 'tkextlib/bwidget/label' + autoload :LabelEntry, 'tkextlib/bwidget/labelentry' + autoload :LabelFrame, 'tkextlib/bwidget/labelframe' + autoload :ListBox, 'tkextlib/bwidget/listbox' + autoload :MainFrame, 'tkextlib/bwidget/mainframe' + autoload :MessageDlg, 'tkextlib/bwidget/messagedlg' + autoload :NoteBook, 'tkextlib/bwidget/notebook' + autoload :PagesManager, 'tkextlib/bwidget/pagesmanager' + autoload :PanedWindow, 'tkextlib/bwidget/panedwindow' + autoload :PasswdDlg, 'tkextlib/bwidget/passwddlg' + autoload :ProgressBar, 'tkextlib/bwidget/progressbar' + autoload :ProgressDlg, 'tkextlib/bwidget/progressdlg' + autoload :ScrollableFrame, 'tkextlib/bwidget/scrollableframe' + autoload :ScrolledWindow, 'tkextlib/bwidget/scrolledwindow' + autoload :ScrollView, 'tkextlib/bwidget/scrollview' + autoload :SelectColor, 'tkextlib/bwidget/selectcolor' + autoload :SelectFont, 'tkextlib/bwidget/selectfont' + autoload :Separator, 'tkextlib/bwidget/separator' + autoload :SpinBox, 'tkextlib/bwidget/spinbox' + autoload :TitleFrame, 'tkextlib/bwidget/titleframe' + autoload :Tree, 'tkextlib/bwidget/tree' + autoload :Widget, 'tkextlib/bwidget/widget' + + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb new file mode 100644 index 0000000000..770e5e9ef1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb @@ -0,0 +1,21 @@ +# +# tkextlib/bwidget/arrowbutton.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/button' + +module Tk + module BWidget + class ArrowButton < Tk::BWidget::Button + end + end +end + +class Tk::BWidget::ArrowButton + TkCommandNames = ['ArrowButton'.freeze].freeze + WidgetClassName = 'ArrowButton'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/bitmap.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/bitmap.rb new file mode 100644 index 0000000000..6cfde203e8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/bitmap.rb @@ -0,0 +1,21 @@ +# +# tkextlib/bwidget/bitmap.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tk/image' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class Bitmap < TkPhotoImage + end + end +end + +class Tk::BWidget::Bitmap + def initialize(name) + @path = tk_call_without_enc('Bitmap::get', name) + Tk_IMGTBL[@path] = self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/button.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/button.rb new file mode 100644 index 0000000000..4a9d4a7948 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/button.rb @@ -0,0 +1,31 @@ +# +# tkextlib/bwidget/button.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/button' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class Button < TkButton + end + end +end + +class Tk::BWidget::Button + TkCommandNames = ['Button'.freeze].freeze + WidgetClassName = 'Button'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helptext' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/buttonbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/buttonbox.rb new file mode 100644 index 0000000000..ef999239f9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/buttonbox.rb @@ -0,0 +1,78 @@ +# +# tkextlib/bwidget/buttonbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/button' + +module Tk + module BWidget + class ButtonBox < TkWindow + end + end +end + +class Tk::BWidget::ButtonBox + TkCommandNames = ['ButtonBox'.freeze].freeze + WidgetClassName = 'ButtonBox'.freeze + WidgetClassNames[WidgetClassName] = self + + include TkItemConfigMethod + + def __boolval_optkeys + super() << 'homogeneous' + end + private :__boolval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::BWidget::Button) + name = tagOrId[:name] + return index(name) unless name.empty? + end + if tagOrId.kind_of?(TkButton) + return index(tagOrId[:text]) + end + # index(tagOrId.to_s) + index(_get_eval_string(tagOrId)) + end + + def add(keys={}, &b) + win = window(tk_send('add', *hash_kv(keys))) + win.instance_eval(&b) if b + win + end + + def delete(idx) + tk_send('delete', tagid(idx)) + self + end + + def index(idx) + if idx.kind_of?(Tk::BWidget::Button) + name = idx[:name] + idx = name unless name.empty? + end + if idx.kind_of?(TkButton) + idx = idx[:text] + end + number(tk_send('index', idx.to_s)) + end + + def insert(idx, keys={}, &b) + win = window(tk_send('insert', tagid(idx), *hash_kv(keys))) + win.instance_eval(&b) if b + win + end + + def invoke(idx) + tk_send('invoke', tagid(idx)) + self + end + + def set_focus(idx) + tk_send('setfocus', tagid(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/combobox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/combobox.rb new file mode 100644 index 0000000000..31f71c3aaf --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/combobox.rb @@ -0,0 +1,45 @@ +# +# tkextlib/bwidget/combobox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/entry' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/listbox' +require 'tkextlib/bwidget/spinbox' + +module Tk + module BWidget + class ComboBox < Tk::BWidget::SpinBox + end + end +end + +class Tk::BWidget::ComboBox + include Scrollable + + TkCommandNames = ['ComboBox'.freeze].freeze + WidgetClassName = 'ComboBox'.freeze + WidgetClassNames[WidgetClassName] = self + + def get_listbox(&b) + win = window(tk_send_without_enc('getlistbox')) + win.instance_eval(&b) if b + win + end + + def icursor(idx) + tk_send_without_enc('icursor', idx) + end + + def post + tk_send_without_enc('post') + self + end + + def unpost + tk_send_without_enc('unpost') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dialog.rb new file mode 100644 index 0000000000..2790d88d24 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dialog.rb @@ -0,0 +1,157 @@ +# +# tkextlib/bwidget/dialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/buttonbox' + +module Tk + module BWidget + class Dialog < TkWindow + end + end +end + +class Tk::BWidget::Dialog + TkCommandNames = ['Dialog'.freeze].freeze + WidgetClassName = 'Dialog'.freeze + WidgetClassNames[WidgetClassName] = self + + include TkItemConfigMethod + + def __strval_optkeys + super() << 'title' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'transient' << 'homogeneous' + end + private :__boolval_optkeys + + def initialize(parent=nil, keys=nil) + @relative = '' + if parent.kind_of?(Hash) + keys = _symbolkey2str(parent) + @relative = keys['parent'] if keys.key?('parent') + @relative = keys.delete('relative') if keys.key?('relative') + super(keys) + elsif keys + keys = _symbolkey2str(keys) + @relative = keys.delete('parent') if keys.key?('parent') + @relative = keys.delete('relative') if keys.key?('relative') + super(parent, keys) + else + super(parent) + end + end + + def create_self(keys) + cmd = self.class::TkCommandNames[0] + if keys and keys != None + tk_call_without_enc(cmd, @path, '-parent', @relative, + *hash_kv(keys, true)) + else + tk_call_without_enc(cmd, @path, '-parent', @relative) + end + end + + def cget(slot) + if slot.to_s == 'relative' + super('parent') + else + super(slot) + end + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + slot['parent'] = slot.delete('relative') if slot.key?('relative') + super(slot) + else + if slot.to_s == 'relative' + super('parent', value) + else + super(slot, value) + end + end + end + + def configinfo(slot=nil) + if slot + if slot.to_s == 'relative' + super('parent') + else + super(slot) + end + else + ret = super() + if TkComm::GET_CONFIGINFO_AS_ARRAY + ret << ['relative', 'parent'] + else + ret['relative'] = 'parent' + end + end + end + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::BWidget::Button) + name = tagOrId[:name] + return index(name) unless name.empty? + end + if tagOrId.kind_of?(TkButton) + return index(tagOrId[:text]) + end + # index(tagOrId.to_s) + index(_get_eval_string(tagOrId)) + end + + def add(keys={}, &b) + win = window(tk_send('add', *hash_kv(keys))) + win.instance_eval(&b) if b + win + end + + def get_frame(&b) + win = window(tk_send('getframe')) + win.instance_eval(&b) if b + win + end + + def get_buttonbox(&b) + win = window(@path + '.bbox') + win.instance_eval(&b) if b + win + end + + def draw(focus_win=None) + tk_send('draw', focus_win) + end + + def enddialog(ret) + tk_send('enddialog', ret) + end + + def index(idx) + get_buttonbox.index(idx) + end + + def invoke(idx) + tk_send('invoke', tagid(idx)) + self + end + + def set_focus(idx) + tk_send('setfocus', tagid(idx)) + self + end + + def withdraw + tk_send('withdraw') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dragsite.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dragsite.rb new file mode 100644 index 0000000000..4d4de1780c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dragsite.rb @@ -0,0 +1,31 @@ +# +# tkextlib/bwidget/dragsite.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + module DragSite + end + end +end + +module Tk::BWidget::DragSite + include Tk + extend Tk + + def self.include(klass, type, event) + tk_call('DragSite::include', klass, type, event) + end + + def self.register(path, keys={}) + tk_call('DragSite::register', path, *hash_kv(keys)) + end + + def self.set_drag(path, subpath, initcmd, endcmd, force=None) + tk_call('DragSite::setdrag', path, subpath, initcmd, endcmd, force) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dropsite.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dropsite.rb new file mode 100644 index 0000000000..e5e98fbc51 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dropsite.rb @@ -0,0 +1,39 @@ +# +# tkextlib/bwidget/dropsite.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + module DropSite + end + end +end + +module Tk::BWidget::DropSite + include Tk + extend Tk + + def self.include(klass, type) + tk_call('DropSite::include', klass, type) + end + + def self.register(path, keys={}) + tk_call('DropSite::register', path, *hash_kv(keys)) + end + + def self.set_cursor(cursor) + tk_call('DropSite::setcursor', cursor) + end + + def self.set_drop(path, subpath, dropover, drop, force=None) + tk_call('DropSite::setdrop', path, subpath, dropover, drop, force) + end + + def self.set_operation(op) + tk_call('DropSite::setoperation', op) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb new file mode 100644 index 0000000000..224304f2ab --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb @@ -0,0 +1,56 @@ +# +# tkextlib/bwidget/dynamichelp.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + module DynamicHelp + end + end +end + +module Tk::BWidget::DynamicHelp + include Tk + extend Tk + + def self.__pathname + 'DynamicHelp::configure' + end + + def __strval_optkeys + super() << 'topbackground' + end + private :__strval_optkeys + + def self.__cget_cmd + ['DynamicHelp::configure'] + end + + def self.__config_cmd + ['DynamicHelp::configure'] + end + + def self.cget(slot) + self.current_configinfo(slot).values[0] + end + + def self.add(widget, keys={}) + tk_call('DynamicHelp::add', widget, *hash_kv(keys)) + end + + def self.delete(widget) + tk_call('DynamicHelp::delete', widget) + end + + def self.include(klass, type) + tk_call('DynamicHelp::include', klass, type) + end + + def self.sethelp(path, subpath, force=None) + tk_call('DynamicHelp::sethelp', path, subpath, force) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/entry.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/entry.rb new file mode 100644 index 0000000000..aafb4aa7ff --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/entry.rb @@ -0,0 +1,43 @@ +# +# tkextlib/bwidget/entry.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/entry' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class Entry < TkEntry + end + end +end + +class Tk::BWidget::Entry + include Scrollable + + TkCommandNames = ['Entry'.freeze].freeze + WidgetClassName = 'Entry'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helptext' << 'insertbackground' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'dragenabled' << 'dropenabled' << 'editable' + end + private :__boolval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys + + def invoke + tk_send_without_enc('invoke') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/label.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/label.rb new file mode 100644 index 0000000000..ce10ecaf8b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/label.rb @@ -0,0 +1,41 @@ +# +# tkextlib/bwidget/label.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/label' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class Label < TkLabel + end + end +end + +class Tk::BWidget::Label + TkCommandNames = ['Label'.freeze].freeze + WidgetClassName = 'Label'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helptext' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'dragenabled' << 'dropenabled' + end + private :__boolval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys + + def set_focus + tk_send_without_enc('setfocus') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/labelentry.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/labelentry.rb new file mode 100644 index 0000000000..931feb9b48 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/labelentry.rb @@ -0,0 +1,80 @@ +# +# tkextlib/bwidget/labelentry.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/entry' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/labelframe' +require 'tkextlib/bwidget/entry' + +module Tk + module BWidget + class LabelEntry < TkEntry + end + end +end + +class Tk::BWidget::LabelEntry + include Scrollable + + TkCommandNames = ['LabelEntry'.freeze].freeze + WidgetClassName = 'LabelEntry'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys + + def __font_optkeys + super() << 'labelfont' + end + private :__font_optkeys + + #def entrybind(*args) + # _bind([path, 'bind'], *args) + # self + #end + def entrybind(context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'bind'], context, cmd, *args) + self + end + + #def entrybind_append(*args) + # _bind_append([path, 'bind'], *args) + # self + #end + def entrybind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'bind'], context, cmd, *args) + self + end + + def entrybind_remove(*args) + _bind_remove([path, 'bind'], *args) + self + end + + def entrybindinfo(*args) + _bindinfo([path, 'bind'], *args) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/labelframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/labelframe.rb new file mode 100644 index 0000000000..f7b267eebb --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/labelframe.rb @@ -0,0 +1,46 @@ +# +# tkextlib/bwidget/labelframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/label' + +module Tk + module BWidget + class LabelFrame < TkWindow + end + end +end + +class Tk::BWidget::LabelFrame + TkCommandNames = ['LabelFrame'.freeze].freeze + WidgetClassName = 'LabelFrame'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helptext' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'dragenabled' << 'dropenabled' + end + private :__boolval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys + + def self.align(*args) + tk_call('LabelFrame::align', *args) + end + def get_frame(&b) + win = window(tk_send_without_enc('getframe')) + win.instance_eval(&b) if b + win + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/listbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/listbox.rb new file mode 100644 index 0000000000..1267500661 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/listbox.rb @@ -0,0 +1,339 @@ +# +# tkextlib/bwidget/listbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/canvas' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class ListBox < TkWindow + # is NOT a subclass of a listbox widget class. + # because it constructed on a canvas widget. + + class Item < TkObject + end + end + end +end + +class Tk::BWidget::ListBox + include TkItemConfigMethod + include Scrollable + + TkCommandNames = ['ListBox'.freeze].freeze + WidgetClassName = 'ListBox'.freeze + WidgetClassNames[WidgetClassName] = self + + class Event_for_Items < TkEvent::Event + def self._get_extra_args_tbl + [ + TkComm.method(:string) # item idenfier + ] + end + end + + def __boolval_optkeys + super() << 'autofocus' << 'dragenabled' << 'dropenabled' << 'selectfill' + end + private :__boolval_optkeys + + def tagid(tag) + if tag.kind_of?(Tk::BWidget::ListBox::Item) + tag.id + else + # tag + _get_eval_string(tag) + end + end + + #def imagebind(*args) + # _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + # self + #end + def imagebind(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_for_event_class(Event_for_Items, [path, 'bindImage'], + context, cmd, *args) + self + end + + #def imagebind_append(*args) + # _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + # self + #end + def imagebind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], + context, cmd, *args) + self + end + + def imagebind_remove(*args) + _bind_remove_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + self + end + + def imagebindinfo(*args) + _bindinfo_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + end + + #def textbind(*args) + # _bind_for_event_class(Event_for_Items, [path, 'bindText'], *args) + # self + #end + def textbind(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_for_event_class(Event_for_Items, [path, 'bindText'], + context, cmd, *args) + self + end + + #def textbind_append(*args) + # _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], *args) + # self + #end + def textbind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], + context, cmd, *args) + self + end + + def textbind_remove(*args) + _bind_remove_for_event_class(Event_for_Items, [path, 'bindText'], *args) + self + end + + def textbindinfo(*args) + _bindinfo_for_event_class(Event_for_Items, [path, 'bindText'], *args) + end + + def delete(*args) + tk_send('delete', *args) + self + end + + def edit(item, text, *args) + tk_send('edit', tagid(item), text, *args) + self + end + + def exist?(item) + bool(tk_send('exists', tagid(item))) + end + + def index(item) + num_or_str(tk_send('index', tagid(item))) + end + + def insert(idx, item, keys={}) + tk_send('insert', idx, tagid(item), *hash_kv(keys)) + self + end + + def get_item(idx) + tk_send('items', idx) + end + + def items(first=None, last=None) + list(tk_send('items', first, last)) + end + + def move(item, idx) + tk_send('move', tagid(item), idx) + self + end + + def reorder(neworder) + tk_send('reorder', neworder) + self + end + + def see(item) + tk_send('see', tagid(item)) + self + end + + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + + def selection_set(*args) + tk_send_without_enc('selection', 'set', + *(args.collect{|item| tagid(item)})) + self + end + + def selection_add(*args) + tk_send_without_enc('selection', 'add', + *(args.collect{|item| tagid(item)})) + self + end + + def selection_remove(*args) + tk_send_without_enc('selection', 'remove', + *(args.collect{|item| tagid(item)})) + self + end + + def selection_get(*args) + simplelist(tk_send_without_enc('selection', 'get')).collect{|item| + Tk::BWidget::ListBox::Item.id2obj(self, item) + } + end +end + +class Tk::BWidget::ListBox::Item + include TkTreatTagFont + + ListItem_TBL = TkCore::INTERP.create_table + ListItem_ID = ['bw:item'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ ListItem_TBL.clear } + + def self.id2obj(lbox, id) + lpath = lbox.path + return id unless ListItem_TBL[lpath] + ListItem_TBL[lpath][id]? ListItem_TBL[lpath][id]: id + end + + def initialize(lbox, *args) + if lbox.kind_of?(Tk::BWidget::ListBox) + @listbox = lbox + else + fail RuntimeError, + "expect Tk::BWidget::ListBox or Tk::BWidget::ListBox::Item for 1st argument" + end + + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = {} + end + + index = keys.delete('index') + unless args.empty? + index = args.shift + end + index = 'end' unless index + + unless args.empty? + fail RuntimeError, 'too much arguments' + end + + @lpath = @listbox.path + + if keys.key?('itemname') + @path = @id = keys.delete('itemname') + else + @path = @id = ListItem_ID.join(TkCore::INTERP._ip_id_) + ListItem_ID[1].succ! + end + + ListItem_TBL[@id] = self + ListItem_TBL[@lpath] = {} unless ListItem_TBL[@lpath] + ListItem_TBL[@lpath][@id] = self + + @listbox.insert(index, @id, keys) + end + + def listbox + @listbox + end + + def id + @id + end + + def [](key) + cget(key) + end + + def []=(key, val) + configure(key, val) + val + end + + def cget(key) + @listbox.itemcget(@id, key) + end + + def configure(key, val=None) + @listbox.itemconfigure(@id, key, val) + end + + def configinfo(key=nil) + @listbox.itemconfiginfo(@id, key) + end + + def current_configinfo(key=nil) + @listbox.current_itemconfiginfo(@id, key) + end + + def delete + @listbox.delete(@id) + self + end + + def edit(*args) + @listbox.edit(@id, *args) + self + end + + def exist? + @listbox.exist?(@id) + end + + def index + @listbox.index(@id) + end + + def move(index) + @listbox.move(@id, index) + end + + def see + @listbox.see(@id) + end + + def selection_add + @listbox.selection_add(@id) + end + + def selection_remove + @listbox.selection_remove(@id) + end + + def selection_set + @listbox.selection_set(@id) + end + + def selection_toggle + @listbox.selection_toggle(@id) + end +end + diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/mainframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/mainframe.rb new file mode 100644 index 0000000000..c54e878557 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/mainframe.rb @@ -0,0 +1,92 @@ +# +# tkextlib/bwidget/mainframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/progressbar' + +module Tk + module BWidget + class MainFrame < TkWindow + end + end +end + +class Tk::BWidget::MainFrame + TkCommandNames = ['MainFrame'.freeze].freeze + WidgetClassName = 'MainFrame'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'progressfg' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'progressvar' + end + private :__tkvariable_optkeys + + def __val2ruby_optkeys # { key=>proc, ... } + # The method is used to convert a opt-value to a ruby's object. + # When get the value of the option "key", "proc.call(value)" is called. + { + 'menu'=>proc{|v| simplelist(v).collect!{|elem| simplelist(v)}} + } + end + private :__val2ruby_optkeys + + def add_indicator(keys={}, &b) + win = window(tk_send('addindicator', *hash_kv(keys))) + win.instance_eval(&b) if b + win + end + + def add_toolbar(&b) + win = window(tk_send('addtoolbar')) + win.instance_eval(&b) if b + win + end + + def get_frame(&b) + win = window(tk_send('getframe')) + win.instance_eval(&b) if b + win + end + + def get_indicator(idx, &b) + win = window(tk_send('getindicator', idx)) + win.instance_eval(&b) if b + win + end + + def get_menu(menu_id, &b) + win = window(tk_send('getmenu', menu_id)) + win.instance_eval(&b) if b + win + end + + def get_toolbar(idx, &b) + win = window(tk_send('gettoolbar', idx)) + win.instance_eval(&b) if b + win + end + + def set_menustate(tag, state) + tk_send('setmenustate', tag, state) + self + end + + def show_statusbar(name) + tk_send('showstatusbar', name) + self + end + + def show_toolbar(idx, mode) + tk_send('showtoolbar', idx, mode) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/messagedlg.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/messagedlg.rb new file mode 100644 index 0000000000..9c946d0630 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/messagedlg.rb @@ -0,0 +1,178 @@ +# +# tkextlib/bwidget/messagedlg.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/dialog.rb' + +module Tk + module BWidget + class MessageDlg < TkWindow + end + end +end + +class Tk::BWidget::MessageDlg + TkCommandNames = ['MessageDlg'.freeze].freeze + WidgetClassName = 'MessageDlg'.freeze + WidgetClassNames[WidgetClassName] = self + + def initialize(parent=nil, keys=nil) + @relative = '' + if parent.kind_of?(Hash) + keys = _symbolkey2str(parent) + @relative = keys['parent'] if keys.key?('parent') + @relative = keys.delete('relative') if keys.key?('relative') + super(keys) + elsif keys + keys = _symbolkey2str(keys) + @relative = keys.delete('parent') if keys.key?('parent') + @relative = keys.delete('relative') if keys.key?('relative') + super(parent, keys) + else + super(parent) + end + end + + def create_self(keys) + # NOT create widget. + # Because the widget no longer exist when returning from creation. + @keys = _symbolkey2str(keys).update('parent'=>@relative) + @info = nil + end + private :create_self + + def __strval_optkeys + super() << 'message' << 'title' + end + private :__strval_optkeys + + def __listval_optkeys + super() << 'buttons' + end + private :__listval_optkeys + + def cget(slot) + slot = slot.to_s + if slot == 'relative' + slot = 'parent' + end + if winfo_exist? + val = super(slot) + @keys[slot] = val + end + @keys[slot] + end + + def configure(slot, value=None) + if winfo_exist? + super(slot, value) + end + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + slot['parent'] = slot.delete('relative') if slot.key?('relative') + @keys.update(slot) + + if @info + # update @info + slot.each{|k, v| + if TkComm::GET_CONFIGINFO_AS_ARRAY + if (inf = @info.assoc(k)) + inf[-1] = v + else + @info << [k, '', '', '', v] + end + else + if (inf = @info[k]) + inf[-1] = v + else + @info[k] = ['', '', '', v] + end + end + } + end + + else # ! Hash + slot = slot.to_s + slot = 'parent' if slot == 'relative' + @keys[slot] = value + + if @info + # update @info + if TkComm::GET_CONFIGINFO_AS_ARRAY + if (inf = @info.assoc(slot)) + inf[-1] = value + else + @info << [slot, '', '', '', value] + end + else + if (inf = @info[slot]) + inf[-1] = value + else + @info[slot] = ['', '', '', value] + end + end + end + end + + self + end + + def configinfo(slot=nil) + if winfo_exist? + @info = super() + if TkComm::GET_CONFIGINFO_AS_ARRAY + @info << ['relative', 'parent'] + else + @info['relative'] = 'parent' + end + end + + if TkComm::GET_CONFIGINFO_AS_ARRAY + if @info + if winfo_exist? + # update @keys + @info.each{|inf| @keys[inf[0]] = inf[-1] if inf.size > 2 } + end + else + @info = [] + @keys.each{|k, v| + @info << [k, '', '', '', v] + } + @info << ['relative', 'parent'] + end + + if slot + @info.asoc(slot.to_s).dup + else + @info.dup + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if @info + if winfo_exist? + # update @keys + @info.each{|k, inf| @keys[k] = inf[-1] if inf.size > 2 } + end + else + @info = {} + @keys.each{|k, v| + @info[k] = ['', '', '', v] + } + @info['relative'] = 'parent' + end + + if slot + @info[slot.to_s].dup + else + @info.dup + end + end + end + + def create + num_or_str(tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys))) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/notebook.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/notebook.rb new file mode 100644 index 0000000000..5146d4915d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/notebook.rb @@ -0,0 +1,148 @@ +# +# tkextlib/bwidget/notebook.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class NoteBook < TkWindow + end + end +end + +class Tk::BWidget::NoteBook + include TkItemConfigMethod + + TkCommandNames = ['NoteBook'.freeze].freeze + WidgetClassName = 'NoteBook'.freeze + WidgetClassNames[WidgetClassName] = self + + class Event_for_Tabs < TkEvent::Event + def self._get_extra_args_tbl + [ + TkComm.method(:string) # page idenfier + ] + end + end + + def __boolval_optkeys + super() << 'homogeneous' + end + private :__boolval_optkeys + + def tagid(id) + if id.kind_of?(TkWindow) + #id.path + id.epath + elsif id.kind_of?(TkObject) + id.to_eval + else + # id.to_s + _get_eval_string(id) + end + end + + #def tabbind(*args) + # _bind_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args) + # self + #end + def tabbind(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_for_event_class(Event_for_Tabs, [path, 'bindtabs'], + context, cmd, *args) + self + end + + #def tabbind_append(*args) + # _bind_append_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args) + # self + #end + def tabbind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append_for_event_class(Event_for_Tabs, [path, 'bindtabs'], + context, cmd, *args) + self + end + + def tabbind_remove(*args) + _bind_remove_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args) + self + end + + def tabbindinfo(*args) + _bindinfo_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args) + end + + def add(page, &b) + win = window(tk_send('add', tagid(page))) + win.instance_eval(&b) if b + win + end + + def compute_size + tk_send('compute_size') + self + end + + def delete(page, destroyframe=None) + tk_send('delete', tagid(page), destroyframe) + self + end + + def get_frame(page, &b) + win = window(tk_send('getframe', tagid(page))) + win.instance_eval(&b) if b + win + end + + def index(page) + num_or_str(tk_send('index', tagid(page))) + end + + def insert(index, page, keys={}, &b) + win = window(tk_send('insert', index, tagid(page), *hash_kv(keys))) + win.instance_eval(&b) if b + win + end + + def move(page, index) + tk_send('move', tagid(page), index) + self + end + + def get_page(page) + tk_send('pages', page) + end + + def pages(first=None, last=None) + list(tk_send('pages', first, last)) + end + + def raise(page=nil) + if page + tk_send('raise', page) + self + else + tk_send('raise') + end + end + + def see(page) + tk_send('see', page) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb new file mode 100644 index 0000000000..fc01284be6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb @@ -0,0 +1,61 @@ +# +# tkextlib/bwidget/pagesmanager.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class PagesManager < TkWindow + end + end +end + +class Tk::BWidget::PagesManager + TkCommandNames = ['PagesManager'.freeze].freeze + WidgetClassName = 'PagesManager'.freeze + WidgetClassNames[WidgetClassName] = self + + def tagid(id) + # id.to_s + _get_eval_string(id) + end + + def add(page, &b) + win = window(tk_send('add', tagid(page))) + win.instance_eval(&b) if b + win + end + + def compute_size + tk_send('compute_size') + self + end + + def delete(page) + tk_send('delete', tagid(page)) + self + end + + def get_frame(page, &b) + win = window(tk_send('getframe', tagid(page))) + win.instance_eval(&b) if b + win + end + + def get_page(page) + tk_send('pages', page) + end + + def pages(first=None, last=None) + list(tk_send('pages', first, last)) + end + + def raise(page=None) + tk_send('raise', page) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/panedwindow.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/panedwindow.rb new file mode 100644 index 0000000000..19982c6095 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/panedwindow.rb @@ -0,0 +1,31 @@ +# +# tkextlib/bwidget/panedwindow.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class PanedWindow < TkWindow + end + end +end + +class Tk::BWidget::PanedWindow + TkCommandNames = ['PanedWindow'.freeze].freeze + WidgetClassName = 'PanedWindow'.freeze + WidgetClassNames[WidgetClassName] = self + + def add(keys={}) + window(tk_send('add', *hash_kv(keys))) + end + + def get_frame(idx, &b) + win = window(tk_send_without_enc('getframe', idx)) + win.instance_eval(&b) if b + win + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/panelframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/panelframe.rb new file mode 100644 index 0000000000..13f8817d74 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/panelframe.rb @@ -0,0 +1,51 @@ +# +# tkextlib/bwidget/panelframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class PanelFrame < TkWindow + end + end +end + +class Tk::BWidget::PanelFrame + TkCommandNames = ['PanelFrame'.freeze].freeze + WidgetClassName = 'PanelFrame'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() + ['panelforeground', 'panelbackground'] + end + private :__strval_optkeys + + def add(win, keys={}) + tk_send('add', win, keys) + self + end + + def delete(*wins) + tk_send('delete', *wins) + self + end + + def get_frame(&b) + win = window(tk_send_without_enc('getframe')) + win.instance_eval(&b) if b + win + end + + def items + list(tk_send('items')) + end + + def remove(*wins) + tk_send('remove', *wins) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/passwddlg.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/passwddlg.rb new file mode 100644 index 0000000000..0b635d97bb --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/passwddlg.rb @@ -0,0 +1,44 @@ +# +# tkextlib/bwidget/passwddlg.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/messagedlg' + +module Tk + module BWidget + class PasswdDlg < Tk::BWidget::MessageDlg + end + end +end + +class Tk::BWidget::PasswdDlg + TkCommandNames = ['PasswdDlg'.freeze].freeze + WidgetClassName = 'PasswdDlg'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'loginhelptext' << 'loginlabel' << 'logintext' << + 'passwdlabel' << 'passwdtext' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'passwdeditable' << 'homogeneous' + end + private :__boolval_optkeys + + def __tkvariable_optkeys + super() << 'loginhelpvar' << 'logintextvariable' << + 'passwdhelpvar' << 'passwdtextvariable' + end + private :__tkvariable_optkeys + + def create + login, passwd = simplelist(tk_call(self.class::TkCommandNames[0], + @path, *hash_kv(@keys))) + [login, passwd] + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/progressbar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/progressbar.rb new file mode 100644 index 0000000000..0253ce2ada --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/progressbar.rb @@ -0,0 +1,20 @@ +# +# tkextlib/bwidget/progressbar.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class ProgressBar < TkWindow + end + end +end + +class Tk::BWidget::ProgressBar + TkCommandNames = ['ProgressBar'.freeze].freeze + WidgetClassName = 'ProgressBar'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/progressdlg.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/progressdlg.rb new file mode 100644 index 0000000000..fbf00f3b00 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/progressdlg.rb @@ -0,0 +1,54 @@ +# +# tkextlib/bwidget/progressdlg.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/variable' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/progressbar' +require 'tkextlib/bwidget/messagedlg' + +module Tk + module BWidget + class ProgressDlg < Tk::BWidget::MessageDlg + end + end +end + +class Tk::BWidget::ProgressDlg + TkCommandNames = ['ProgressDlg'.freeze].freeze + WidgetClassName = 'ProgressDlg'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + # NOT create widget for reusing the object + super(keys) + @keys['textvariable'] = TkVariable.new unless @keys.key?('textvariable') + @keys['variable'] = TkVariable.new unless @keys.key?('variable') + end + + def textvariable + @keys['textvariable'] + end + + def text + @keys['textvariable'].value + end + + def text= (txt) + @keys['textvariable'].value = txt + end + + def variable + @keys['variable'] + end + + def value + @keys['variable'].value + end + + def value= (val) + @keys['variable'].value = val + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb new file mode 100644 index 0000000000..a3986681a5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb @@ -0,0 +1,34 @@ +# +# tkextlib/bwidget/scrollableframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class ScrollableFrame < TkWindow + end + end +end + +class Tk::BWidget::ScrollableFrame + include Scrollable + + TkCommandNames = ['ScrollableFrame'.freeze].freeze + WidgetClassName = 'ScrollableFrame'.freeze + WidgetClassNames[WidgetClassName] = self + + def get_frame(&b) + win = window(tk_send_without_enc('getframe')) + win.instance_eval(&b) if b + win + end + + def see(win, vert=None, horiz=None) + tk_send_without_enc('see', win, vert, horiz) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb new file mode 100644 index 0000000000..e9e53235b7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb @@ -0,0 +1,32 @@ +# +# tkextlib/bwidget/scrolledwindow.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class ScrolledWindow < TkWindow + end + end +end + +class Tk::BWidget::ScrolledWindow + TkCommandNames = ['ScrolledWindow'.freeze].freeze + WidgetClassName = 'ScrolledWindow'.freeze + WidgetClassNames[WidgetClassName] = self + + def get_frame(&b) + win = window(tk_send_without_enc('getframe')) + win.instance_eval(&b) if b + win + end + + def set_widget(win) + tk_send_without_enc('setwidget', win) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrollview.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrollview.rb new file mode 100644 index 0000000000..0546af2c43 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/scrollview.rb @@ -0,0 +1,25 @@ +# +# tkextlib/bwidget/scrollview.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class ScrollView < TkWindow + end + end +end + +class Tk::BWidget::ScrollView + TkCommandNames = ['ScrollView'.freeze].freeze + WidgetClassName = 'ScrollView'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'fill' + end + private :__strval_optkeys +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/selectcolor.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/selectcolor.rb new file mode 100644 index 0000000000..742a84cd84 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/selectcolor.rb @@ -0,0 +1,45 @@ +# +# tkextlib/bwidget/selectcolor.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/messagedlg' + +module Tk + module BWidget + class SelectColor < Tk::BWidget::MessageDlg + end + end +end + +class Tk::BWidget::SelectColor + extend Tk + + TkCommandNames = ['SelectColor'.freeze].freeze + WidgetClassName = 'SelectColor'.freeze + WidgetClassNames[WidgetClassName] = self + + def dialog(keys={}) + newkeys = @keys.dup + newkeys.update(_symbolkey2str(keys)) + tk_call('SelectColor::dialog', @path, *hash_kv(newkeys)) + end + + def menu(*args) + if args[-1].kind_of?(Hash) + keys = args.pop + else + keys = {} + end + place = args.flatten + newkeys = @keys.dup + newkeys.update(_symbolkey2str(keys)) + tk_call('SelectColor::menu', @path, place, *hash_kv(newkeys)) + end + + def self.set_color(idx, color) + tk_call('SelectColor::setcolor', idx, color) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/selectfont.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/selectfont.rb new file mode 100644 index 0000000000..478787602a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/selectfont.rb @@ -0,0 +1,85 @@ +# +# tkextlib/bwidget/selectfont.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/messagedlg' + +module Tk + module BWidget + class SelectFont < Tk::BWidget::MessageDlg + class Dialog < Tk::BWidget::SelectFont + end + class Toolbar < TkWindow + end + end + end +end + +class Tk::BWidget::SelectFont + extend Tk + + TkCommandNames = ['SelectFont'.freeze].freeze + WidgetClassName = 'SelectFont'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'sampletext' << 'title' + end + private :__strval_optkeys + + def __font_optkeys + [] # without fontobj operation + end + private :__font_optkeys + + def create + tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys)) + end + + def self.load_font + tk_call('SelectFont::loadfont') + end +end + +class Tk::BWidget::SelectFont::Dialog + def __font_optkeys + [] # without fontobj operation + end + + def create_self(keys) + super(keys) + @keys['type'] = 'dialog' + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot.delete['type'] + slot.delete[:type] + return self if slot.empty? + else + return self if slot == 'type' || slot == :type + end + super(slot, value) + end + + def create + @keys['type'] = 'dialog' + tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], @path, *hash_kv(@keys)) + end +end + +class Tk::BWidget::SelectFont::Toolbar + def __font_optkeys + [] # without fontobj operation + end + + def create_self(keys) + keys = {} unless keys + keys = _symbolkey2str(keys) + keys['type'] = 'toolbar' + tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], @path, *hash_kv(keys)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/separator.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/separator.rb new file mode 100644 index 0000000000..d9c3458e51 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/separator.rb @@ -0,0 +1,20 @@ +# +# tkextlib/bwidget/separator.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class Separator < TkWindow + end + end +end + +class Tk::BWidget::Separator + TkCommandNames = ['Separator'.freeze].freeze + WidgetClassName = 'Separator'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/spinbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/spinbox.rb new file mode 100644 index 0000000000..ca4c046e5c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/spinbox.rb @@ -0,0 +1,98 @@ +# +# tkextlib/bwidget/entry.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' +require 'tkextlib/bwidget/arrowbutton' +require 'tkextlib/bwidget/entry' + +module Tk + module BWidget + class SpinBox < TkEntry + end + end +end + +class Tk::BWidget::SpinBox + include Scrollable + + TkCommandNames = ['SpinBox'.freeze].freeze + WidgetClassName = 'SpinBox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'dragenabled' << 'dropenabled' << 'editable' + end + private :__boolval_optkeys + + def __listval_optkeys + super() << 'values' + end + private :__listval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys + + #def entrybind(*args) + # _bind([path, 'bind'], *args) + # self + #end + def entrybind(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'bind'], context, cmd, *args) + self + end + + #def entrybind_append(*args) + # _bind_append([path, 'bind'], *args) + # self + #end + def entrybind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'bind'], context, cmd, *args) + self + end + + def entrybind_remove(*args) + _bind_remove([path, 'bind'], *args) + self + end + + def entrybindinfo(*args) + _bindinfo([path, 'bind'], *args) + self + end + + def get_index_of_value + number(tk_send_without_enc('getvalue')) + end + alias get_value get_index_of_value + alias get_value_index get_index_of_value + + def set_value_by_index(idx) + idx = "@#{idx}" if idx.kind_of?(Integer) + tk_send_without_enc('setvalue', idx) + self + end + alias set_value set_value_by_index + alias set_index_value set_value_by_index +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/statusbar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/statusbar.rb new file mode 100644 index 0000000000..df16e4c0b7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/statusbar.rb @@ -0,0 +1,46 @@ +# +# tkextlib/bwidget/statusbar.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class StatusBar < TkWindow + end + end +end + +class Tk::BWidget::StatusBar + TkCommandNames = ['StatusBar'.freeze].freeze + WidgetClassName = 'StatusBar'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'showresize' + end + private :__boolval_optkeys + + def add(win, keys={}) + tk_send('add', win, keys) + self + end + + def delete(*wins) + tk_send('delete', *wins) + self + end + + def get_frame(&b) + win = window(tk_send_without_enc('getframe')) + win.instance_eval(&b) if b + win + end + + def items + list(tk_send('items')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/titleframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/titleframe.rb new file mode 100644 index 0000000000..f519490430 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/titleframe.rb @@ -0,0 +1,27 @@ +# +# tkextlib/bwidget/titleframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/frame' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class TitleFrame < TkWindow + end + end +end + +class Tk::BWidget::TitleFrame + TkCommandNames = ['TitleFrame'.freeze].freeze + WidgetClassName = 'TitleFrame'.freeze + WidgetClassNames[WidgetClassName] = self + + def get_frame(&b) + win = window(tk_send_without_enc('getframe')) + win.instance_eval(&b) if b + win + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/tree.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/tree.rb new file mode 100644 index 0000000000..e7178debe2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/tree.rb @@ -0,0 +1,434 @@ +# +# tkextlib/bwidget/tree.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/canvas' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + class Tree < TkWindow + class Node < TkObject + end + end + end +end + +class Tk::BWidget::Tree + include TkItemConfigMethod + include Scrollable + + TkCommandNames = ['Tree'.freeze].freeze + WidgetClassName = 'Tree'.freeze + WidgetClassNames[WidgetClassName] = self + + class Event_for_Items < TkEvent::Event + def self._get_extra_args_tbl + [ + TkComm.method(:string) # item idenfier + ] + end + end + + def __strval_optkeys + super() << 'crossfill' << 'linesfill' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'dragenabled' << 'dropenabled' << + 'redraw' << 'selectfill' << 'showlines' + end + private :__boolval_optkeys + + def __tkvariable_optkeys + super() << 'helpvar' + end + private :__tkvariable_optkeys + + def tagid(tag) + if tag.kind_of?(Tk::BWidget::Tree::Node) + tag.id + else + # tag + _get_eval_string(tag) + end + end + + #def imagebind(*args) + # _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + # self + #end + def imagebind(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_for_event_class(Event_for_Items, [path, 'bindImage'], + context, cmd, *args) + self + end + + #def imagebind_append(*args) + # _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + # self + #end + def imagebind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], + context, cmd, *args) + self + end + + def imagebind_remove(*args) + _bind_remove_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + self + end + + def imagebindinfo(*args) + _bindinfo_for_event_class(Event_for_Items, [path, 'bindImage'], *args) + end + + #def textbind(*args) + # _bind_for_event_class(Event_for_Items, [path, 'bindText'], *args) + # self + #end + def textbind(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_for_event_class(Event_for_Items, [path, 'bindText'], + context, cmd, *args) + self + end + + #def textbind_append(*args) + # _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], *args) + # self + #end + def textbind_append(context, *args) + #if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], + context, cmd, *args) + self + end + + def textbind_remove(*args) + _bind_remove_for_event_class(Event_for_Items, [path, 'bindText'], *args) + self + end + + def textbindinfo(*args) + _bindinfo_for_event_class(Event_for_Items, [path, 'bindText'], *args) + end + + def close_tree(node, recurse=None) + tk_send('closetree', tagid(node), recurse) + self + end + + def delete(*args) + tk_send('delete', *(args.collect{|node| tagid(node)})) + self + end + + def edit(node, text, *args) + tk_send('edit', tagid(node), text, *args) + self + end + + def exist?(node) + bool(tk_send('exists', tagid(node))) + end + + def index(node) + num_or_str(tk_send('index', tagid(node))) + end + + def insert(idx, parent, node, keys={}) + tk_send('insert', idx, tagid(parent), tagid(node), *hash_kv(keys)) + self + end + + def move(parent, node, idx) + tk_send('move', tagid(parent), tagid(node), idx) + self + end + + def get_node(node, idx) + Tk::BWidget::Tree::Node.id2obj(self, tk_send('nodes', tagid(node), idx)) + end + + def nodes(node, first=None, last=None) + simplelist(tk_send('nodes', tagid(node), first, last)).collect{|node| + Tk::BWidget::Tree::Node.id2obj(self, node) + } + end + + def open?(node) + bool(@tree.itemcget(tagid(node), 'open')) + end + + def open_tree(node, recurse=None) + tk_send('opentree', tagid(node), recurse) + self + end + + def parent(node) + Tk::BWidget::Tree::Node.id2obj(self, tk_send('parent', tagid(node))) + end + + def reorder(node, neworder) + tk_send('reorder', tagid(node), neworder) + self + end + + def see(node) + tk_send('see', tagid(node)) + self + end + + def selection_add(*args) + tk_send_without_enc('selection', 'add', + *(args.collect{|node| tagid(node)})) + self + end + + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + + def selection_get + list(tk_send_without_enc('selection', 'get')) + end + + def selection_include?(*args) + bool(tk_send_without_enc('selection', 'get', + *(args.collect{|node| tagid(node)}))) + end + + def selection_range(*args) + tk_send_without_enc('selection', 'range', + *(args.collect{|node| tagid(node)})) + self + end + + def selection_remove(*args) + tk_send_without_enc('selection', 'remove', + *(args.collect{|node| tagid(node)})) + self + end + + def selection_set(*args) + tk_send_without_enc('selection', 'set', + *(args.collect{|node| tagid(node)})) + self + end + + def selection_toggle(*args) + tk_send_without_enc('selection', 'toggle', + *(args.collect{|node| tagid(node)})) + self + end + + def toggle(node) + tk_send_without_enc('toggle', tagid(node)) + self + end + + def visible(node) + bool(tk_send_without_enc('visible', tagid(node))) + end +end + +class Tk::BWidget::Tree::Node + include TkTreatTagFont + + TreeNode_TBL = TkCore::INTERP.create_table + TreeNode_ID = ['bw:node'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ TreeNode_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless TreeNode_TBL[tpath] + TreeNode_TBL[tpath][id]? TreeNode_TBL[tpath][id]: id + end + + def initialize(tree, *args) + if tree.kind_of?(Tk::BWidget::Tree) + @tree = tree + parent = args.shift + if parent.kind_of?(Tk::BWidget::Tree::Node) + if parent.tree.path != @tree.path + fail RuntimeError, 'tree of parent node is not match' + end + end + elsif tree.kind_of?(Tk::BWidget::Tree::Node) + @tree = tree.tree + parent = tree.parent + else + fail RuntimeError, + "expect Tk::BWidget::Tree or Tk::BWidget::Tree::Node for 1st argument" + end + + if args[-1].kind_of?(Hash) + keys = _symbolkey2str(args.pop) + else + keys = {} + end + + index = keys.delete('index') + unless args.empty? + index = args.shift + end + index = 'end' unless index + + unless args.empty? + fail RuntimeError, 'too much arguments' + end + + @tpath = @tree.path + + if keys.key?('nodename') + @path = @id = keys.delete('nodename') + else + @path = @id = TreeNode_ID.join(TkCore::INTERP._ip_id_) + TreeNode_ID[1].succ! + end + + TreeNode_TBL[@id] = self + TreeNode_TBL[@tpath] = {} unless TreeNode_TBL[@tpath] + TreeNode_TBL[@tpath][@id] = self + + @tree.insert(index, parent, @id, keys) + end + + def tree + @tree + end + + def id + @id + end + + def [](key) + cget(key) + end + + def []=(key, val) + configure(key, val) + val + end + + def cget(key) + @tree.itemcget(@id, key) + end + + def configure(key, val=None) + @tree.itemconfigure(@id, key, val) + end + + def configinfo(key=nil) + @tree.itemconfiginfo(@id, key) + end + + def current_configinfo(key=nil) + @tree.current_itemconfiginfo(@id, key) + end + + def close_tree(recurse=None) + @tree.close_tree(@id, recurse) + self + end + + def delete + @tree.delete(@id) + self + end + + def edit(*args) + @tree.edit(@id, *args) + self + end + + def exist? + @tree.exist?(@id) + end + + def index + @tree.index(@id) + end + + def move(index, parent=nil) + if parent + @tree.move(parent, @id, index) + else + @tree.move(self.parent, @id, index) + end + end + + def open_tree(recurse=None) + @tree.open_tree(@id, recurse) + self + end + + def open? + bool(@tree.itemcget(@id, 'open')) + end + + def parent + @tree.parent(@id) + end + + def reorder(neworder) + @tree.reorder(@id, neworder) + end + + def see + @tree.see(@id) + end + + def selection_add + @tree.selection_add(@id) + end + + def selection_remove + @tree.selection_remove(@id) + end + + def selection_set + @tree.selection_set(@id) + end + + def selection_toggle + @tree.selection_toggle(@id) + end + + def toggle + @tree.toggle(@id) + end + + def visible + @tree.visible(@id) + end +end + diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/widget.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/widget.rb new file mode 100644 index 0000000000..568e503a8b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/bwidget/widget.rb @@ -0,0 +1,113 @@ +# +# tkextlib/bwidget/widget.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/bwidget.rb' + +module Tk + module BWidget + module Widget + end + end +end + +module Tk::BWidget::Widget + include Tk + extend Tk + + def self.__pathname + 'Widget::configure' + end + + def self.__cget_cmd + ['Widget::cget'] + end + + def self.__config_cmd + ['Widget::configure'] + end + + def self.cget(slot) + self.current_configinfo(slot).values[0] + end + + def self.add_map(klass, subclass, subpath, opts) + tk_call('Widget::addmap', klass, subclass, subpath, opts) + end + + def self.bwinclude(klass, subclass, subpath, *args) + tk_call('Widget::bwinclude', klass, subclass, subpath, *args) + end + + def self.create(klass, path, rename=None, &b) + win = window(tk_call('Widget::create', klass, path, rename)) + win.instance_eval(&b) if b + win + end + + def self.declare(klass, optlist) + tk_call('Widget::declare', klass, optlist) + end + + def self.define(klass, filename, *args) + tk_call('Widget::define', klass, filename, *args) + end + + def self.destroy(win) + tk_call('Widget::destroy', _epath(win)) + end + + def self.focus_next(win) + tk_call('Widget::focusNext', win) + end + + def self.focus_ok(win) + tk_call('Widget::focusOk', win) + end + + def self.focus_prev(win) + tk_call('Widget::focusPrev', win) + end + + def self.generate_doc(dir, widgetlist) + tk_call('Widget::generate-doc', dir, widgetlist) + end + + def self.generate_widget_doc(klass, iscmd, file) + tk_call('Widget::generate-widget-doc', klass, iscmd, file) + end + + def self.get_option(win, option) + tk_call('Widget::getoption', win, option) + end + + def self.get_variable(win, varname, my_varname=None) + tk_call('Widget::getVariable', win, varname, my_varname) + end + + def self.has_changed(win, option, pvalue) + tk_call('Widget::hasChanged', win, option, pvalue) + end + + def self.init(klass, win, options) + tk_call('Widget::init', klass, win, options) + end + + def self.set_option(win, option, value) + tk_call('Widget::setoption', win, option, value) + end + + def self.sub_cget(win, subwidget) + tk_call('Widget::subcget', win, subwidget) + end + + def self.sync_options(klass, subclass, subpath, options) + tk_call('Widget::syncoptions', klass, subclass, subpath, options) + end + + def self.tkinclude(klass, tkwidget, subpath, *args) + tk_call('Widget::tkinclude', klass, tkwidget, subpath, *args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/itcl.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/itcl.rb new file mode 100644 index 0000000000..1d6ecf04f2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/itcl.rb @@ -0,0 +1,13 @@ +# +# [incr Tcl] support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/itcl/setup.rb' + +# load library +require 'tkextlib/itcl/incr_tcl.rb' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/itcl/incr_tcl.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/itcl/incr_tcl.rb new file mode 100644 index 0000000000..07abf3a7bf --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/itcl/incr_tcl.rb @@ -0,0 +1,172 @@ +# +# tkextlib/itk/incr_tcl.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script +require 'tkextlib/itcl.rb' + +# TkPackage.require('Itcl', '3.2') +TkPackage.require('Itcl') + +module Tk + module Itcl + include Tk + extend Tk + + LIBRARY = TkVarAccess.new('::itcl::library') + PURIST = TkVarAccess.new('::itcl::purist') + + VERSION = TkCore::INTERP._invoke("set", "::itcl::version").freeze + PATCHLEVEL = TkCore::INTERP._invoke("set", "::itcl::patchLevel").freeze + + PACKAGE_NAME = 'Itcl'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Itcl') + rescue + '' + end + end + + ############################################## + + class ItclObject < TkObject + ITCL_CLASSNAME = ''.freeze + + ITCL_OBJ_ID = ['itclobj'.freeze, '00000'.taint].freeze + ITCL_OBJ_TBL = {}.taint + + def initialize(*args) + if (@klass = self.class::ITCL_CLASSNAME).empty? + fail RuntimeError, 'unknown itcl class (abstract class?)' + end + @id = Tk::Itcl::ItclObject::TCL_OBJ_ID.join(TkCore::INTERP._ip_id_) + @path = @id + Tk::Itcl::ItclObject::ITCL_OBJ_ID[1].succ! + end + + def self.call_proc(name, *args) + tk_call("#{ITCL_CLASSNAME}::#{cmd}", *args) + end + + def call_method(name, *args) + tk_call(@path, name, *args) + end + + def isa(klass) + bool(tk_call(@path, 'isa', klass)) + end + alias itcl_kind_of? isa + + def info_class + tk_call(@path, 'info', 'class') + end + + def info_inherit + simplelist(tk_call(@path, 'info', 'inherit')) + end + + def info_heritage + list(tk_call(@path, 'info', 'heritage')) + end + + def info_function(*args) + if args[-1].kind_of?(Array) + params = args.pop + params.each{|param| + param = param.to_s + args << ( (param[0] == ?-)? param: "-#{param}" ) + } + end + list(tk_call(@path, 'info', 'function', *args)) + end + + def info_variable(*args) + if args[-1].kind_of?(Array) + params = args.pop + params.each{|param| + param = param.to_s + args << ( (param[0] == ?-)? param: "-#{param}" ) + } + end + list(tk_call(@path, 'info', 'variable', *args)) + end + end + + ############################################## + + def self.body(klass, func, args, body) + tk_call('::itcl::body', "#{klass}::#{func}", args, body) + end + + def self.code(cmd, *args) + tk_call('::itcl::code', cmd, *args) + end + + def self.code_in_namespace(namespace, cmd, *args) + tk_call('::itcl::code', '-namespace', namespace, cmd, *args) + end + + def self.configbody(klass, var, body) + tk_call('::itcl::configbody', "#{klass}::#{var}", body) + end + + def self.create_itcl_class(name, body) + TkCore::INTERP._invoke('::itcl::class', name, body) + klass = Class.new(Tk::Itcl::ItclObject) + klass.const_set('ITCL_CLASSNAME', name.dup.freeze) + klass + end + + def self.delete_itcl_class(*names) + tk_call('::itcl::delete', 'class', *names) + end + + def self.delete_itcl_object(*names) + tk_call('::itcl::delete', 'object', *names) + end + + def self.delete_namespace(*names) + tk_call('::itcl::delete', 'namespace', *names) + end + + def self.ensemble(name, *args) + tk_call('::itcl::ensemble', name, *args) + end + + def self.find_classes(pat=None) + simplelist(tk_call('::itcl::find', 'classes', pat)) + end + + def self.find_objects(*args) + simplelist(tk_call('::itcl::find', 'objects', *args)) + end + + def self.is_itcl_class(target) + bool(tk_call('::itcl::is', 'class', target)) + end + + def self.is_itcl_object(target) + bool(tk_call('::itcl::is', 'object', target)) + end + + def self.create_local_obj(klass, name, *args) + tk_call('::itcl::local', klass, name, *args) + end + + def self.is_itcl_instance(klass, target) + bool(tk_call('::itcl::is', 'object', '-class', klass, target)) + end + + def self.scope(var) + tk_call('::itcl::scope', var) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/itcl/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/itcl/setup.rb new file mode 100644 index 0000000000..5be0588703 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/itcl/setup.rb @@ -0,0 +1,13 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# + + +# set [incr Tcl] library directory + +# ENV['ITCL_LIBRARY'] = '/usr/local/ActiveTcl/lib/itcl3.2/' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/itk.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/itk.rb new file mode 100644 index 0000000000..7492bd3eb4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/itk.rb @@ -0,0 +1,13 @@ +# +# [incr Tk] support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/itk/setup.rb' + +# load library +require 'tkextlib/itk/incr_tk.rb' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/itk/incr_tk.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/itk/incr_tk.rb new file mode 100644 index 0000000000..0626536e36 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/itk/incr_tk.rb @@ -0,0 +1,428 @@ +# +# tkextlib/itk/incr_tk.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/menuspec' +require 'tkextlib/itcl.rb' + +# call setup script +require 'tkextlib/itk.rb' + +#TkPackage.require('Itk', '3.2') +TkPackage.require('Itk') + +module Tk + module Itk + include Tk + extend Tk + + LIBRARY = TkVarAccess.new('::itk::library') + + PACKAGE_NAME = 'Itk'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Itk') + rescue + '' + end + end + + def self.usual(arg, *args) + tk_call('::itk::usual', arg, *args) + end + + def self.usual_names + list(tk_call('::itk::usual')) + end + + ############################ + + class Archetype < TkWindow + TkCommandNames = [].freeze + # WidgetClassName = 'Archetype'.freeze + # WidgetClassNames[WidgetClassName] = self + + def self.to_eval + '::itk::' << self::WidgetClassName + end + + def __destroy_hook__ + Tk::Itk::Component::ComponentID_TBL.delete(self.path) + end + + #### [incr Tk] public methods + def component + simplelist(tk_send('component')) + end + + def component_path(name) + window(tk_send('component', name)) + end + alias component_widget component_path + + def component_invoke(name, cmd, *args) + window(tk_send('component', name, cmd, *args)) + end + + def component_obj(*names) + names = component if names.empty? + names.collect{|name| Tk::Itk::Component.new(self.path, name) } + end + + #### [incr Tk] protected methods +=begin + def itk_component_add(visibility, name, create_cmds, option_cmds=None) + args = [] + visibility.each{|v| v = v.to_s; args << ( (v[0] == ?-)? v: "-#{v}" )} + args << '--' << name << create_cmd << option_cmds + tk_call('itk_component', 'add', *args) + end + + def itk_component_delete(*names) + tk_call('itk_component', 'delete', *names) + end + + def itk_initialize(keys={}) + tk_call('itk_initialize', keys) + end + + def itk_option_add(*args) + tk_call('itk_option', 'add', *args) + end + + def itk_option_define(name, resource, klass, init, config=None) + tk_call('itk_option', 'define', name, resource, klass, init, config) + end + + def itk_option_remove(*args) + tk_call('itk_option', 'remove', *args) + end +=end + end + + ############################ + + class Toplevel < Archetype + TkCommandNames = ['::itk::Toplevel'].freeze + WidgetClassName = 'Toplevel'.freeze + WidgetClassNames[WidgetClassName] = self + + include Wm + include TkMenuSpec + + def __strval_optkeys + super() << 'title' + end + private :__strval_optkeys + end + + ############################ + + class Widget < Archetype + TkCommandNames = ['::itk::Widget'].freeze + WidgetClassName = 'Widget'.freeze + WidgetClassNames[WidgetClassName] = self + end + + + ############################ + + class Component < TkObject + def __cget_cmd + [self.master, 'component', self.name, 'cget'] + end + private :__cget_cmd + + def __config_cmd + [self.master, 'component', self.name, 'configure'] + end + private :__config_cmd + + ComponentID_TBL = TkCore::INTERP.create_table + Itk_Component_ID = ['itk:component'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ ComponentID_TBL.clear } + + def self.id2obj(master, id) + if master.kind_of?(TkObject) + master = master.path + else + master = master.to_s + end + return id unless ComponentID_TBL.key?(master) + (ComponentID_TBL.key?(id))? ComponentID_TBL[master][id]: id + end + + def self.new(master, component=nil) + if master.kind_of?(TkObject) + master = master.path + else + master = master.to_s + end + + if component.kind_of?(Tk::Itk::Component) + component = component.name + elsif component + component = component.to_s + else + component = Itk_Component_ID.join(TkCore::INTERP._ip_id_) + Itk_Component_ID[1].succ! + end + + if ComponentID_TBL.key?(master) + if ComponentID_TBL[master].key?(component) + return ComponentID_TBL[master][component] + end + else + ComponentID_TBL[master] = {} + end + + super(master, component) + end + + def initialize(master, component) + @master = master + @component = component + + ComponentID_TBL[@master][@component] = self + + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + @widget = nil + @path = nil + end + end + + def path + unless @path + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + @path + end + + def epath + path() + end + + def to_eval + path() + end + + def master + @master + end + + def name + @component + end + + def widget + unless @widget + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + @widget + end + + def widget_class + unless @widget + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + @widget.classname + rescue + nil + end + end + end + + def method_missing(id, *args) + name = id.id2name + + # try 1 : component command + begin + return tk_call(@master, 'component', @component, name, *args) + rescue + end + + # try 2 : component configure + len = args.length + begin + case len + when 1 + if name[-1] == ?= + return configure(name[0..-2], args[0]) + else + return configure(name, args[0]) + end + when 0 + return cget(name) + end + rescue + end + + # try 3 : widget method or widget configure + begin + unless @widget + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + end + @widget.__send__(id, *args) + rescue + end + + # unknown method + super(id, *args) + # fail RuntimeError, "unknown method '#{name}' for #{self.inspect}" + end + + def tk_send(cmd, *rest) + begin + tk_call(@master, 'component', @component, cmd, *rest) + rescue + unless @path + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + tk_call(@path, cmd, *rest) + end + end + + def tk_send_without_enc(cmd, *rest) + begin + tk_call_without_enc(@master, 'component', @component, cmd, *rest) + rescue + unless @path + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + tk_call_without_enc(@path, cmd, *rest) + end + end + + def tk_send_with_enc(cmd, *rest) + begin + tk_call_with_enc(@master, 'component', @component, cmd, *rest) + rescue + unless @path + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + tk_call_with_enc(@path, cmd, *rest) + end + end + + #def bind(*args) + # unless @widget + # begin + # @widget = window(tk_call(@master, 'component', @component)) + # @path = @widget.path + # rescue + # fail RuntimeError, 'component is not assigned to a widget' + # end + # end + # @widget.bind(*args) + #end + def bind(context, *args) + unless @widget + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @widget.bind(context, cmd, *args) + end + + #def bind_append(*args) + # unless @widget + # begin + # @widget = window(tk_call(@master, 'component', @component)) + # @path = @widget.path + # rescue + # fail RuntimeError, 'component is not assigned to a widget' + # end + # end + # @widget.bind_append(*args) + #end + def bind_append(context, *args) + unless @widget + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @widget.bind_append(context, cmd, *args) + end + + def bind_remove(*args) + unless @widget + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + @widget.bind_remove(*args) + end + + def bindinfo(*args) + unless @widget + begin + @widget = window(tk_call(@master, 'component', @component)) + @path = @widget.path + rescue + fail RuntimeError, 'component is not assigned to a widget' + end + end + @widget.bindinfo(*args) + end + + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/itk/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/itk/setup.rb new file mode 100644 index 0000000000..e47b64adae --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/itk/setup.rb @@ -0,0 +1,13 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# + + +# set [incr Tk] library directory + +# ENV['ITK_LIBRARY'] = '/usr/local/ActiveTcl/lib/itk3.2/' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets.rb new file mode 100644 index 0000000000..ebd4cf7507 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets.rb @@ -0,0 +1,94 @@ +# +# [incr Widgets] support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/itcl' +require 'tkextlib/itk' + +# call setup script for general 'tkextlib' libraries +#require 'tkextlib/setup.rb' + +# call setup script +#require 'tkextlib/iwidgets/setup.rb' + +# load all image format handlers +#TkPackage.require('Iwidgets', '4.0') +TkPackage.require('Iwidgets') + +module Tk + module Iwidgets + TkComm::TkExtlibAutoloadModule.unshift(self) + + extend TkCore + + PACKAGE_NAME = 'Iwidgets'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Iwidgets') + rescue + '' + end + end + + #################################################### + + autoload :Buttonbox, 'tkextlib/iwidgets/buttonbox' + autoload :Calendar, 'tkextlib/iwidgets/calendar' + autoload :Canvasprintbox, 'tkextlib/iwidgets/canvasprintbox' + autoload :Canvasprintdialog, 'tkextlib/iwidgets/canvasprintdialog' + autoload :Checkbox, 'tkextlib/iwidgets/checkbox' + autoload :Combobox, 'tkextlib/iwidgets/combobox' + autoload :Dateentry, 'tkextlib/iwidgets/dateentry' + autoload :Datefield, 'tkextlib/iwidgets/datefield' + autoload :Dialog, 'tkextlib/iwidgets/dialog' + autoload :Dialogshell, 'tkextlib/iwidgets/dialogshell' + autoload :Disjointlistbox, 'tkextlib/iwidgets/disjointlistbox' + autoload :Entryfield, 'tkextlib/iwidgets/entryfield' + autoload :Extbutton, 'tkextlib/iwidgets/extbutton' + autoload :Extfileselectionbox, 'tkextlib/iwidgets/extfileselectionbox' + autoload :Extfileselectiondialog,'tkextlib/iwidgets/extfileselectiondialog' + autoload :Feedback, 'tkextlib/iwidgets/feedback' + autoload :Fileselectionbox, 'tkextlib/iwidgets/fileselectionbox' + autoload :Fileselectiondialog, 'tkextlib/iwidgets/fileselectiondialog' + autoload :Finddialog, 'tkextlib/iwidgets/finddialog' + autoload :Hierarchy, 'tkextlib/iwidgets/hierarchy' + autoload :Hyperhelp, 'tkextlib/iwidgets/hyperhelp' + autoload :Labeledframe, 'tkextlib/iwidgets/labeledframe' + autoload :Labeledwidget, 'tkextlib/iwidgets/labeledwidget' + autoload :Mainwindow, 'tkextlib/iwidgets/mainwindow' + autoload :Menubar, 'tkextlib/iwidgets/menubar' + autoload :Messagebox, 'tkextlib/iwidgets/messagebox' + autoload :Messagedialog, 'tkextlib/iwidgets/messagedialog' + autoload :Notebook, 'tkextlib/iwidgets/notebook' + autoload :Optionmenu, 'tkextlib/iwidgets/optionmenu' + autoload :Panedwindow, 'tkextlib/iwidgets/panedwindow' + autoload :Pushbutton, 'tkextlib/iwidgets/pushbutton' + autoload :Promptdialog, 'tkextlib/iwidgets/promptdialog' + autoload :Radiobox, 'tkextlib/iwidgets/radiobox' + autoload :Scrolledcanvas, 'tkextlib/iwidgets/scrolledcanvas' + autoload :Scrolledframe, 'tkextlib/iwidgets/scrolledframe' + autoload :Scrolledhtml, 'tkextlib/iwidgets/scrolledhtml' + autoload :Scrolledlistbox, 'tkextlib/iwidgets/scrolledlistbox' + autoload :Scrolledtext, 'tkextlib/iwidgets/scrolledtext' + autoload :Scrolledwidget, 'tkextlib/iwidgets/scrolledwidget' + autoload :Selectionbox, 'tkextlib/iwidgets/selectionbox' + autoload :Selectiondialog, 'tkextlib/iwidgets/selectiondialog' + autoload :Shell, 'tkextlib/iwidgets/shell' + autoload :Spindate, 'tkextlib/iwidgets/spindate' + autoload :Spinint, 'tkextlib/iwidgets/spinint' + autoload :Spinner, 'tkextlib/iwidgets/spinner' + autoload :Spintime, 'tkextlib/iwidgets/spintime' + autoload :Tabnotebook, 'tkextlib/iwidgets/tabnotebook' + autoload :Tabset, 'tkextlib/iwidgets/tabset' + autoload :Timeentry, 'tkextlib/iwidgets/timeentry' + autoload :Timefield, 'tkextlib/iwidgets/timefield' + autoload :Toolbar, 'tkextlib/iwidgets/toolbar' + autoload :Watch, 'tkextlib/iwidgets/watch' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb new file mode 100644 index 0000000000..a055e07ac9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb @@ -0,0 +1,119 @@ +# +# tkextlib/iwidgets/buttonbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Buttonbox < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Buttonbox + TkCommandNames = ['::iwidgets::buttonbox'.freeze].freeze + WidgetClassName = 'Buttonbox'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'buttoncget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'buttonconfigure', id] + end + private :__item_config_cmd + + def __item_boolval_optkeys(id) + super(id) << 'defaultring' + end + private :__item_boolval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias buttoncget itemcget + alias buttonconfigure itemconfigure + alias buttonconfiginfo itemconfiginfo + alias current_buttonconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def add(tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'add', tagid(tag), *hash_kv(keys)) + tag + end + + def default(idx) + tk_call(@path, 'default', index(idx)) + self + end + + def delete(idx) + tk_call(@path, 'delete', index(idx)) + self + end + + def hide(idx) + tk_call(@path, 'hide', index(idx)) + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys)) + tag + end + + def invoke(idx=nil) + if idx + tk_call(@path, 'invoke', index(idx)) + else + tk_call(@path, 'invoke') + end + self + end + + def show(idx) + tk_call(@path, 'show', index(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/calendar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/calendar.rb new file mode 100644 index 0000000000..0152f8593a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/calendar.rb @@ -0,0 +1,106 @@ +# +# tkextlib/iwidgets/calendar.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Calendar < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Calendar + TkCommandNames = ['::iwidgets::calendar'.freeze].freeze + WidgetClassName = 'Calendar'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() + [ + 'buttonforeground', 'outline', 'selectcolor', + 'weekdaybackground', 'weekendbackground' + ] + end + private :__strval_optkeys + + def __listval_optkeys + super() << 'days' + end + private :__listval_optkeys + + def __font_optkeys + super() + ['currentdatefont', 'datefont', 'dayfont', 'titlefont'] + end + private :__font_optkeys + + #################################### + + include Tk::ValidateConfigure + + class CalendarCommand < TkValidateCommand + #class CalCmdArgs < TkUtil::CallbackSubst + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ [?d, ?s, :date], nil ] + PROC_TBL = [ [?s, TkComm.method(:string) ], nil ] + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + # array of config-option key (string or symbol) + ['command'] + end + + #def initialize(cmd = Proc.new, *args) + # _initialize_for_cb_class(CalCmdArgs, cmd, *args) + #end + end + + def __validation_class_list + super() << CalendarCommand + end + + Tk::ValidateConfigure.__def_validcmd(binding, CalendarCommand) +=begin + def command(cmd = Proc.new, args = nil) + if cmd.kind_of?(CalendarCommand) + configure('command', cmd) + elsif args + configure('command', [cmd, args]) + else + configure('command', cmd) + end + end +=end + + #################################### + + def get_string + tk_call(@path, 'get', '-string') + end + alias get get_string + + def get_clicks + number(tk_call(@path, 'get', '-clicks')) + end + + def select(date) + tk_call(@path, 'select', date) + self + end + + def show(date) + tk_call(@path, 'show', date) + self + end + def show_now + tk_call(@path, 'show', 'now') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb new file mode 100644 index 0000000000..fa5e90ad05 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb @@ -0,0 +1,53 @@ +# +# tkextlib/iwidgets/canvasprintbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Canvasprintbox < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Canvasprintbox + TkCommandNames = ['::iwidgets::canvasprintbox'.freeze].freeze + WidgetClassName = 'Canvasprintbox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'filename' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'stretch' + end + private :__boolval_optkeys + + def get_output + tk_call(@path, 'getoutput') + end + + def print + bool(tk_call(@path, 'print')) + end + + def refresh + tk_call(@path, 'refresh') + self + end + + def set_canvas(win) + tk_call(@path, 'setcanvas', win) + self + end + + def stop + tk_call(@path, 'stop') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb new file mode 100644 index 0000000000..bbf507677c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb @@ -0,0 +1,38 @@ +# +# tkextlib/iwidgets/canvasprintdialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Canvasprintdialog < Tk::Iwidgets::Dialog + end + end +end + +class Tk::Iwidgets::Canvasprintdialog + TkCommandNames = ['::iwidgets::canvasprintdialog'.freeze].freeze + WidgetClassName = 'Canvasprintdialog'.freeze + WidgetClassNames[WidgetClassName] = self + + def get_output + tk_call(@path, 'getoutput') + end + + def print + bool(tk_call(@path, 'print')) + end + + def refresh + tk_call(@path, 'refresh') + self + end + + def set_canvas(win) + tk_call(@path, 'setcanvas', win) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/checkbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/checkbox.rb new file mode 100644 index 0000000000..46ca389db2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/checkbox.rb @@ -0,0 +1,116 @@ +# +# tkextlib/iwidgets/checkbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Checkbox < Tk::Iwidgets::Labeledframe + end + end +end + +class Tk::Iwidgets::Checkbox + TkCommandNames = ['::iwidgets::checkbox'.freeze].freeze + WidgetClassName = 'Checkbox'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'buttoncget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'buttonconfigure', id] + end + private :__item_config_cmd + + def __item_boolval_optkeys(id) + super(id) << 'defaultring' + end + private :__item_boolval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias buttoncget itemcget + alias buttonconfigure itemconfigure + alias buttonconfiginfo itemconfiginfo + alias current_buttonconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def add(tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'add', tagid(tag), *hash_kv(keys)) + tag + end + + def delete(idx) + tk_call(@path, 'delete', index(idx)) + self + end + + def deselect(idx) + tk_call(@path, 'deselect', index(idx)) + self + end + + def flash(idx) + tk_call(@path, 'flash', index(idx)) + self + end + + def get(idx) + simplelist(tk_call(@path, 'get', index(idx))).collect{|id| + Tk::Itk::Component.id2obj(self, id) + } + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys)) + tag + end + + def select(idx) + tk_call(@path, 'select', index(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/combobox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/combobox.rb new file mode 100644 index 0000000000..a6d54d78fa --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/combobox.rb @@ -0,0 +1,104 @@ +# +# tkextlib/iwidgets/combobox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Combobox < Tk::Iwidgets::Entryfield + end + end +end + +class Tk::Iwidgets::Combobox + TkCommandNames = ['::iwidgets::combobox'.freeze].freeze + WidgetClassName = 'Combobox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'completion' << 'dropdown' << 'editable' << 'unique' + end + private :__boolval_optkeys + + def clear(component=None) + tk_call(@path, 'clear', component) + self + end + + def delete_list(first, last=None) + tk_call(@path, 'delete', 'list', first, last) + self + end + + def delete_entry(first, last=None) + tk_call(@path, 'delete', 'entry', first, last) + self + end + + def get_list_contents(index) + tk_call(@path, 'get', index) + end + + def insert_list(idx, *elems) + tk_call(@path, 'insert', 'list', idx, *elems) + self + end + + def insert_entry(idx, *elems) + tk_call(@path, 'insert', 'entry', idx, *elems) + self + end + + # listbox methods + def size + tk_send_without_enc('size').to_i + end + def see(index) + tk_send_without_enc('see', index) + self + end + def selection_anchor(index) + tk_send_without_enc('selection', 'anchor', index) + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', first, last) + self + end + def selection_includes(index) + bool(tk_send_without_enc('selection', 'includes', index)) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', first, last) + self + end + + # scrolledlistbox methods + def get_curselection + tk_call(@path, 'getcurselection') + end + def justify(dir) + tk_call(@path, 'justify', dir) + self + end + def sort(*params, &b) + # see 'lsort' man page about params + if b + tk_call(@path, 'sort', '-command', proc(&b), *params) + else + tk_call(@path, 'sort', *params) + end + self + end + def sort_ascending + tk_call(@path, 'sort', 'ascending') + self + end + def sort_descending + tk_call(@path, 'sort', 'descending') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dateentry.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dateentry.rb new file mode 100644 index 0000000000..0a8897f50d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dateentry.rb @@ -0,0 +1,20 @@ +# +# tkextlib/iwidgets/dateentry.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Dateentry < Tk::Iwidgets::Datefield + end + end +end + +class Tk::Iwidgets::Dateentry + TkCommandNames = ['::iwidgets::dateentry'.freeze].freeze + WidgetClassName = 'Dateentry'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/datefield.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/datefield.rb new file mode 100644 index 0000000000..632f3334dc --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/datefield.rb @@ -0,0 +1,58 @@ +# +# tkextlib/iwidgets/datefield.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Datefield < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Datefield + TkCommandNames = ['::iwidgets::datefield'.freeze].freeze + WidgetClassName = 'Datefield'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'gmt' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'textbackground' + end + private :__strval_optkeys + + def __font_optkeys + super() << 'textfont' + end + private :__font_optkeys + + def get_string + tk_call(@path, 'get', '-string') + end + alias get get_string + + def get_clicks + number(tk_call(@path, 'get', '-clicks')) + end + + def valid? + bool(tk_call(@path, 'isvalid')) + end + alias isvalid? valid? + + def show(date=None) + tk_call(@path, 'show', date) + self + end + def show_now + tk_call(@path, 'show', 'now') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dialog.rb new file mode 100644 index 0000000000..8540eae1b5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dialog.rb @@ -0,0 +1,20 @@ +# +# tkextlib/iwidgets/dialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Dialog < Tk::Iwidgets::Dialogshell + end + end +end + +class Tk::Iwidgets::Dialog + TkCommandNames = ['::iwidgets::dialog'.freeze].freeze + WidgetClassName = 'Dialog'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb new file mode 100644 index 0000000000..d6c668621d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb @@ -0,0 +1,119 @@ +# +# tkextlib/iwidgets/dialogshell.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Dialogshell < Tk::Iwidgets::Shell + end + end +end + +class Tk::Iwidgets::Dialogshell + TkCommandNames = ['::iwidgets::dialogshell'.freeze].freeze + WidgetClassName = 'Dialogshell'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'buttoncget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'buttonconfigure', id] + end + private :__item_config_cmd + + def __item_boolval_optkeys(id) + super(id) << 'defaultring' + end + private :__item_boolval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias buttoncget itemcget + alias buttonconfigure itemconfigure + alias buttonconfiginfo itemconfiginfo + alias current_buttonconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def add(tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'add', tagid(tag), *hash_kv(keys)) + tag + end + + def default(idx) + tk_call(@path, 'default', index(idx)) + self + end + + def delete(idx) + tk_call(@path, 'delete', index(idx)) + self + end + + def hide(idx) + tk_call(@path, 'hide', index(idx)) + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys)) + tag + end + + def invoke(idx=nil) + if idx + tk_call(@path, 'invoke', index(idx)) + else + tk_call(@path, 'invoke') + end + self + end + + def show(idx) + tk_call(@path, 'show', index(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb new file mode 100644 index 0000000000..9bc063ba69 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb @@ -0,0 +1,50 @@ +# +# tkextlib/iwidgets/disjointlistbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Disjointlistbox < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Disjointlistbox + TkCommandNames = ['::iwidgets::disjointlistbox'.freeze].freeze + WidgetClassName = 'Disjointlistbox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'lhslabeltext' << 'rhslabeltext' << 'lhsbuttonlabel' << 'rhsbuttonlabel' + end + private :__strval_optkeys + + def set_lhs(*items) + tk_call(@path, 'setlhs', items) + self + end + def set_rhs(*items) + tk_call(@path, 'setrhs', items) + self + end + + def get_lhs + simplelist(tk_call(@path, 'getlhs')) + end + def get_rhs + simplelist(tk_call(@path, 'getrhs')) + end + + def insert_lhs(*items) + tk_call(@path, 'insertlhs', items) + self + end + def insert_rhs(*items) + tk_call(@path, 'insertrhs', items) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/entryfield.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/entryfield.rb new file mode 100644 index 0000000000..6aa933ce06 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/entryfield.rb @@ -0,0 +1,166 @@ +# +# tkextlib/iwidgets/entryfield.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Entryfield < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Entryfield + TkCommandNames = ['::iwidgets::entryfield'.freeze].freeze + WidgetClassName = 'Entryfield'.freeze + WidgetClassNames[WidgetClassName] = self + + def __font_optkeys + super() << 'textfont' + end + private :__font_optkeys + + #################################### + + include Tk::ValidateConfigure + + class EntryfieldValidate < TkValidateCommand + #class CalCmdArgs < TkUtil::CallbackSubst + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?c, ?s, :char ], + [ ?P, ?s, :post ], + [ ?S, ?s, :current ], + [ ?W, ?w, :widget ], + nil + ] + PROC_TBL = [ + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + nil + ] + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + def self._config_keys + ['validate', 'invalid'] + end + end + + def __validation_class_list + super() << EntryfieldValidate + end + + Tk::ValidateConfigure.__def_validcmd(binding, EntryfieldValidate) +=begin + def validate(cmd = Proc.new, args = nil) + if cmd.kind_of?(ValidateCmd) + configure('validate', cmd) + elsif args + configure('validate', [cmd, args]) + else + configure('validate', cmd) + end + end + + def invalid(cmd = Proc.new, args = nil) + if cmd.kind_of?(ValidateCmd) + configure('invalid', cmd) + elsif args + configure('invalid', [cmd, args]) + else + configure('invalid', cmd) + end + end +=end + + #################################### + + def clear + tk_call(@path, 'clear') + self + end + + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + + def value + _fromUTF8(tk_send_without_enc('get')) + end + def value= (val) + tk_send_without_enc('delete', 0, 'end') + tk_send_without_enc('insert', 0, _get_eval_enc_str(val)) + val + end + alias get value + alias set value= + + def cursor=(index) + tk_send_without_enc('icursor', index) + #self + index + end + alias icursor cursor= + + def index(index) + number(tk_send_without_enc('index', index)) + end + + def insert(pos,text) + tk_send_without_enc('insert', pos, _get_eval_enc_str(text)) + self + end + + def mark(pos) + tk_send_without_enc('scan', 'mark', pos) + self + end + def dragto(pos) + tk_send_without_enc('scan', 'dragto', pos) + self + end + def selection_adjust(index) + tk_send_without_enc('selection', 'adjust', index) + self + end + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + def selection_from(index) + tk_send_without_enc('selection', 'from', index) + self + end + def selection_present() + bool(tk_send_without_enc('selection', 'present')) + end + def selection_range(s, e) + tk_send_without_enc('selection', 'range', s, e) + self + end + def selection_to(index) + tk_send_without_enc('selection', 'to', index) + self + end + + # based on tk/scrollable.rb + def xview(*index) + if index.size == 0 + list(tk_send_without_enc('xview')) + else + tk_send_without_enc('xview', *index) + self + end + end + def xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extbutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extbutton.rb new file mode 100644 index 0000000000..158d9d474a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extbutton.rb @@ -0,0 +1,40 @@ +# +# tkextlib/iwidgets/extbutton.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Extbutton < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Extbutton + TkCommandNames = ['::iwidgets::extbutton'.freeze].freeze + WidgetClassName = 'Extbutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'bitmapforeground' << 'ringbackground' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'defaultring' + end + private :__boolval_optkeys + + def invoke + tk_call(@path, 'invoke') + self + end + + def flash + tk_call(@path, 'flash') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb new file mode 100644 index 0000000000..501f4c90a0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb @@ -0,0 +1,46 @@ +# +# tkextlib/iwidgets/extfileselectionbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Extfileselectionbox < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Extfileselectionbox + TkCommandNames = ['::iwidgets::extfileselectionbox'.freeze].freeze + WidgetClassName = 'Extfileselectionbox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() + [ + 'dirslabel', 'fileslabel', 'filterlabel', 'mask', 'nomatchstring', + 'selectionlabel' + ] + end + private :__strval_optkeys + + def __boolval_optkeys + super() + ['dirson', 'fileson', 'filteron', 'selectionon'] + end + private :__boolval_optkeys + + def child_site + window(tk_call(@path, 'childsite')) + end + + def filter + tk_call(@path, 'filter') + self + end + + def get + tk_call(@path, 'get') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb new file mode 100644 index 0000000000..14388be7c4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb @@ -0,0 +1,33 @@ +# +# tkextlib/iwidgets/extfileselectiondialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Extfileselectiondialog < Tk::Iwidgets::Dialog + end + end +end + +class Tk::Iwidgets::Extfileselectiondialog + TkCommandNames = ['::iwidgets::extfileselectiondialog'.freeze].freeze + WidgetClassName = 'Extfileselectiondialog'.freeze + WidgetClassNames[WidgetClassName] = self + + def child_site + window(tk_call(@path, 'childsite')) + end + + def filter + tk_call(@path, 'filter') + self + end + + def get + tk_call(@path, 'get') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/feedback.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/feedback.rb new file mode 100644 index 0000000000..0a25237a24 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/feedback.rb @@ -0,0 +1,35 @@ +# +# tkextlib/iwidgets/feedback.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Feedback < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Feedback + TkCommandNames = ['::iwidgets::feedback'.freeze].freeze + WidgetClassName = 'Feedback'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'barcolor' + end + private :__strval_optkeys + + def reset + tk_call(@path, 'reset') + self + end + + def step(inc=1) + tk_call(@path, 'step', inc) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb new file mode 100644 index 0000000000..7b331d0b40 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb @@ -0,0 +1,46 @@ +# +# tkextlib/iwidgets/fileselectionbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Fileselectionbox < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Fileselectionbox + TkCommandNames = ['::iwidgets::fileselectionbox'.freeze].freeze + WidgetClassName = 'Fileselectionbox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() + [ + 'directory', 'dirslabel', 'fileslabel', 'filterlabel', 'mask', + 'nomatchstring', 'selectionlabel' + ] + end + private :__strval_optkeys + + def __boolval_optkeys + super() + ['dirson', 'fileson', 'filteron', 'selectionon'] + end + private :__boolval_optkeys + + def child_site + window(tk_call(@path, 'childsite')) + end + + def filter + tk_call(@path, 'filter') + self + end + + def get + tk_call(@path, 'get') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb new file mode 100644 index 0000000000..50f459e56d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb @@ -0,0 +1,33 @@ +# +# tkextlib/iwidgets/fileselectiondialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Fileselectiondialog < Tk::Iwidgets::Dialog + end + end +end + +class Tk::Iwidgets::Fileselectiondialog + TkCommandNames = ['::iwidgets::fileselectiondialog'.freeze].freeze + WidgetClassName = 'Fileselectiondialog'.freeze + WidgetClassNames[WidgetClassName] = self + + def child_site + window(tk_call(@path, 'childsite')) + end + + def filter + tk_call(@path, 'filter') + self + end + + def get + tk_call(@path, 'get') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/finddialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/finddialog.rb new file mode 100644 index 0000000000..75e219c37e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/finddialog.rb @@ -0,0 +1,42 @@ +# +# tkextlib/iwidgets/finddialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Finddialog < Tk::Iwidgets::Dialogshell + end + end +end + +class Tk::Iwidgets::Finddialog + TkCommandNames = ['::iwidgets::finddialog'.freeze].freeze + WidgetClassName = 'Finddialog'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() + [ + 'patternbackground', 'patternforeground', + 'searchbackground', 'searchforeground' + ] + end + private :__strval_optkeys + + def __val2ruby_optkeys # { key=>proc, ... } + super().update('textwidget'=>proc{|v| window(v)}) + end + private :__val2ruby_optkeys + + def clear + tk_call(@path, 'clear') + self + end + + def find + tk_call(@path, 'find') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb new file mode 100644 index 0000000000..4cc6aeecbd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb @@ -0,0 +1,309 @@ +# +# tkextlib/iwidgets/hierarchy.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/text' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Hierarchy < Tk::Iwidgets::Scrolledwidget + end + end +end + +class Tk::Iwidgets::Hierarchy + ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze + include TkTextTagConfig + + TkCommandNames = ['::iwidgets::hierarchy'.freeze].freeze + WidgetClassName = 'Hierarchy'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include Tk::ValidateConfigure + + class QueryCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ [?n, ?s, :node], nil ] + PROC_TBL = [ [?s, TkComm.method(:string) ], nil ] + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + # array of config-option key (string or symbol) + ['querycommand'] + end + end + + class IndicatorCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?n, ?s, :node ], + [ ?s, ?b, :status ], + nil + ] + + PROC_TBL = [ + [ ?s, TkComm.method(:string) ], + [ ?b, TkComm.method(:bool) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + # array of config-option key (string or symbol) + ['iconcommand', 'icondblcommand', 'imagedblcommand'] + end + end + + class IconCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?n, ?s, :node ], + [ ?i, ?s, :icon ], + nil + ] + PROC_TBL = [ [ ?s, TkComm.method(:string) ], nil ] + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + # array of config-option key (string or symbol) + ['dblclickcommand', 'imagecommand', 'selectcommand'] + end + end + + def __validation_class_list + super() << QueryCommand << IndicatorCommand << IconCommand + end + + Tk::ValidateConfigure.__def_validcmd(binding, QueryCommand) + Tk::ValidateConfigure.__def_validcmd(binding, IndicatorCommand) + Tk::ValidateConfigure.__def_validcmd(binding, IconCommand) + + #################################### + + def __boolval_optkeys + super() << 'alwaysquery' << 'expanded' << 'filter' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'markbackground' << 'markforeground' << 'textbackground' + end + private :__strval_optkeys + + def __font_optkeys + super() << 'textfont' + end + private :__font_optkeys + + def clear + tk_call(@path, 'clear') + self + end + + def collapse(node) + tk_call(@path, 'collapse') + self + end + + def current + tk_call(@path, 'current') + end + + def draw(mode=None) + case mode + when None + # do nothing + when 'now', :now + mode = '-now' + when 'eventually', :eventually + mode = '-eventually' + when String, Symbol + mode = mode.to_s + mode = '-' << mode if mode[0] != ?- + end + tk_call(@path, 'draw', mode) + end + + def expand(node) + tk_call(@path, 'expand', node) + self + end + + def expanded?(node) + bool(tk_call(@path, 'expanded', node)) + end + + def exp_state + list(tk_call(@path, 'expState')) + end + alias expand_state exp_state + alias expanded_list exp_state + + def mark_clear + tk_call(@path, 'mark', 'clear') + self + end + def mark_add(*nodes) + tk_call(@path, 'mark', 'add', *nodes) + self + end + def mark_remove(*nodes) + tk_call(@path, 'mark', 'remove', *nodes) + self + end + def mark_get + list(tk_call(@path, 'mark', 'get')) + end + + def refresh(node) + tk_call(@path, 'refresh', node) + self + end + + def prune(node) + tk_call(@path, 'prune', node) + self + end + + def selection_clear + tk_call(@path, 'selection', 'clear') + self + end + def selection_add(*nodes) + tk_call(@path, 'selection', 'add', *nodes) + self + end + def selection_remove(*nodes) + tk_call(@path, 'selection', 'remove', *nodes) + self + end + def selection_get + list(tk_call(@path, 'selection', 'get')) + end + + def toggle(node) + tk_call(@path, 'toggle', node) + self + end + + # based on TkText widget + + 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 debug + bool(tk_send_without_enc('debug')) + end + def debug=(boolean) + tk_send_without_enc('debug', boolean) + #self + boolean + end + + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + + def dlineinfo(index) + list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index))) + end + + def get(*index) + _fromUTF8(tk_send_without_enc('get', *index)) + end + + def index(index) + tk_send_without_enc('index', _get_eval_enc_str(index)) + 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 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 see(index) + tk_send_without_enc('see', index) + self + end + + # based on tk/scrollable.rb + def xview(*index) + if index.size == 0 + list(tk_send_without_enc('xview')) + else + tk_send_without_enc('xview', *index) + self + end + end + def xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + 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 yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb new file mode 100644 index 0000000000..77b0e090cd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb @@ -0,0 +1,50 @@ +# +# tkextlib/iwidgets/hyperhelp.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Hyperhelp < Tk::Iwidgets::Shell + end + end +end + +class Tk::Iwidgets::Hyperhelp + TkCommandNames = ['::iwidgets::hyperhelp'.freeze].freeze + WidgetClassName = 'Hyperhelp'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'helpdir' + end + private :__strval_optkeys + + def __listval_optkeys + super() << 'topics' + end + private :__listval_optkeys + + def show_topic(topic) + tk_call(@path, 'showtopic', topic) + self + end + + def follow_link(href) + tk_call(@path, 'followlink', href) + self + end + + def forward + tk_call(@path, 'forward') + self + end + + def back + tk_call(@path, 'back') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb new file mode 100644 index 0000000000..e77e85045d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb @@ -0,0 +1,39 @@ +# +# tkextlib/iwidgets/labeledframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Labeledframe < Tk::Itk::Archetype + end + end +end + +class Tk::Iwidgets::Labeledframe + TkCommandNames = ['::iwidgets::labeledframe'.freeze].freeze + WidgetClassName = 'Labeledframe'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'labeltext' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'labelvariable' + end + private :__tkvariable_optkeys + + def __font_optkeys + super() << 'labelfont' + end + private :__font_optkeys + + def child_site + window(tk_call(@path, 'childsite')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb new file mode 100644 index 0000000000..99387710cb --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb @@ -0,0 +1,45 @@ +# +# tkextlib/iwidgets/labeledwidget.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Labeledwidget < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Labeledwidget + extend TkCore + + TkCommandNames = ['::iwidgets::labeledwidget'.freeze].freeze + WidgetClassName = 'Labeledwidget'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'labeltext' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'labelvariable' + end + private :__tkvariable_optkeys + + def __font_optkeys + super() << 'labelfont' + end + private :__font_optkeys + + def self.alignlabels(*wins) + tk_call('::iwidgets::Labeledwidget::alignlabels', *wins) + end + + def child_site + window(tk_call(@path, 'childsite')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb new file mode 100644 index 0000000000..4b2541b997 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb @@ -0,0 +1,67 @@ +# +# tkextlib/iwidgets/mainwindow.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Mainwindow < Tk::Iwidgets::Shell + end + end +end + +class Tk::Iwidgets::Mainwindow + TkCommandNames = ['::iwidgets::mainwindow'.freeze].freeze + WidgetClassName = 'Mainwindow'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'helpline' << 'statusline' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'menubarbackground' << 'menubarforeground' << 'toolbarforeground' + end + private :__strval_optkeys + + def __font_optkeys + super() << 'menubarfont' << 'toolbarfont' + end + private :__font_optkeys + + def child_site + window(tk_call(@path, 'childsite')) + end + + def menubar(*args) + unless args.empty? + tk_call(@path, 'menubar', *args) + end + window(tk_call(@path, 'menubar')) + end + + def mousebar(*args) + unless args.empty? + tk_call(@path, 'mousebar', *args) + end + window(tk_call(@path, 'mousebar')) + end + + def msgd(*args) + unless args.empty? + tk_call(@path, 'msgd', *args) + end + window(tk_call(@path, 'msgd')) + end + + def toolbar(*args) + unless args.empty? + tk_call(@path, 'toolbar', *args) + end + window(tk_call(@path, 'toolbar')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/menubar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/menubar.rb new file mode 100644 index 0000000000..dea3d34c2a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/menubar.rb @@ -0,0 +1,210 @@ +# +# tkextlib/iwidgets/menubar.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Menubar < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Menubar + TkCommandNames = ['::iwidgets::menubar'.freeze].freeze + WidgetClassName = 'Menubar'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'menubuttons' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'helpvariable' + end + private :__tkvariable_optkeys + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'menucget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'menuconfigure', id] + end + private :__item_config_cmd + + def __item_strval_optkeys(id) + super(id) << 'selectcolor' + end + private :__item_strval_optkeys + + def __item_tkvariable_optkeys(id) + super(id) << 'helpstr' + end + private :__item_tkvariable_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias menucget itemcget + alias menuconfigure itemconfigure + alias menuconfiginfo itemconfiginfo + alias current_menuconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def __methodcall_optkeys + {'menubuttons'=>'menubuttons'} + end + + def menubuttons(val = nil) + unless val + return tk_call(@path, 'cget', '-menubuttons') + end + + tk_call(@path, 'configure', '-menubuttons', _parse_menu_spec(val)) + self + end + + def _parse_menu_spec(menu_spec) + ret = '' + menu_spec.each{|spec| + next unless spec + + if spec.kind_of?(Hash) + args = [spec] + type = 'options' + else + type, *args = spec + end + + type = type.to_s + case type + when 'options' + keys = args[0] + ary = [type] + ary.concat(hash_kv(keys)) + ret << array2tk_list(ary) << "\n" + + when 'menubutton', 'cascade' + name, keys = args + if keys + ary = [type, name] + keys = _symbolkey2str(keys) + keys['menu'] = _parse_menu_spec(keys['menu']) if keys.key?('menu') + ary.concat(hash_kv(keys)) + ret << array2tk_list(ary) << "\n" + else + ret << array2tk_list([type, name]) << "\n" + end + + else + name, keys = args + if keys + ary = [type, name] + ary.concat(hash_kv(keys)) + ret << array2tk_list(ary) << "\n" + else + ret << array2tk_list([type, name]) << "\n" + end + end + } + ret + end + + #################################### + + def add(type, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + keys = _symbolkey2str(keys) + keys['menu'] = _parse_menu_spec(keys['menu']) if keys.key?('menu') + tk_call(@path, 'add', type, tagid(tag), *hash_kv(keys)) + tag + end + + def delete(path1, path2=nil) + if path2 + else + tk_call(@path, 'delete', index(idx)) + end + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, type, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + keys = _symbolkey2str(keys) + keys['menu'] = _parse_menu_spec(keys['menu']) if keys.key?('menu') + tk_call(@path, 'insert', index(idx), type, tagid(tag), *hash_kv(keys)) + tag + end + + def invoke(idx) + tk_call(@path, 'invoke', index(idx)) + self + end + + def menupath(pat) + if (win = tk_call(@path, 'path', pat)) == '-1' + return nil + end + window(win) + end + def menupath_glob(pat) + if (win = tk_call(@path, 'path', '-glob', pat)) == '-1' + return nil + end + window(win) + end + def menupath_tclregexp(pat) + if (win = tk_call(@path, 'path', '-regexp', pat)) == '-1' + return nil + end + window(win) + end + + def type(path) + tk_call(@path, 'type', path) + end + + def yposition(path) + number(tk_call(@path, 'yposition', path)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/messagebox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/messagebox.rb new file mode 100644 index 0000000000..2bbbec7666 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/messagebox.rb @@ -0,0 +1,91 @@ +# +# tkextlib/iwidgets/messagebox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Messagebox < Tk::Iwidgets::Scrolledwidget + end + end +end + +class Tk::Iwidgets::Messagebox + TkCommandNames = ['::iwidgets::messagebox'.freeze].freeze + WidgetClassName = 'Messagebox'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'type', 'cget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'type', 'configure', id] + end + private :__item_config_cmd + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + def __item_boolval_optkeys(id) + super(id) << 'bell' << 'show' + end + private :__item_boolval_optkeys + + alias typecget itemcget + alias typeconfigure itemconfigure + alias typeconfiginfo itemconfiginfo + alias current_typeconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def __strval_optkeys + super() << 'filename' << 'savedir' + end + private :__strval_optkeys + + def type_add(tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + unless tag + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'type', 'add', tagid(tag), *hash_kv(keys)) + tag + end + + def clear + tk_call(@path, 'clear') + self + end + + def export(file) + tk_call(@path, 'export', file) + self + end + + def issue(string, type=None, *args) + tk_call(@path, 'issue', string, tagid(type), *args) + self + end + +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb new file mode 100644 index 0000000000..c19b83e517 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb @@ -0,0 +1,20 @@ +# +# tkextlib/iwidgets/messagedialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Messagedialog < Tk::Iwidgets::Dialog + end + end +end + +class Tk::Iwidgets::Messagedialog + TkCommandNames = ['::iwidgets::messagedialog'.freeze].freeze + WidgetClassName = 'Messagedialog'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/notebook.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/notebook.rb new file mode 100644 index 0000000000..0f9d713ea1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/notebook.rb @@ -0,0 +1,168 @@ +# +# tkextlib/iwidgets/notebook.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Notebook < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Notebook + TkCommandNames = ['::iwidgets::notebook'.freeze].freeze + WidgetClassName = 'Notebook'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'pagecget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'pageconfigure', id] + end + private :__item_config_cmd + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias pagecget itemcget + alias pageconfigure itemconfigure + alias pageconfiginfo itemconfiginfo + alias current_pageconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def __boolval_optkeys + super() << 'auto' + end + private :__boolval_optkeys + + def add(keys={}) + window(tk_call(@path, 'add', *hash_kv(keys))) + end + + def child_site_list + list(tk_call(@path, 'childsite')) + end + + def child_site(idx) + if (new_idx = self.index(idx)) < 0 + new_idx = tagid(idx) + end + window(tk_call(@path, 'childsite', new_idx)) + end + + def delete(idx1, idx2=nil) + if (new_idx1 = self.index(idx1)) < 0 + new_idx1 = tagid(idx1) + end + if idx2 + if (new_idx2 = self.index(idx2)) < 0 + new_idx2 = tagid(idx2) + end + tk_call(@path, 'delete', new_idx1, new_idx2) + else + tk_call(@path, 'delete', new_idx1) + end + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, keys={}) + if (new_idx = self.index(idx)) < 0 + new_idx = tagid(idx) + end + window(tk_call(@path, 'insert', new_idx, *hash_kv(keys))) + end + + def next + tk_call(@path, 'next') + self + end + + def prev + tk_call(@path, 'prev') + self + end + + def select(idx) + if (new_idx = self.index(idx)) < 0 + new_idx = tagid(idx) + end + tk_call(@path, 'select', new_idx) + self + end + + def scrollcommand(cmd=Proc.new) + configure_cmd 'scrollcommand', cmd + self + end + alias xscrollcommand scrollcommand + alias yscrollcommand scrollcommand + + def xscrollbar(bar=nil) + if bar + @scrollbar = bar + @scrollbar.orient 'horizontal' + self.scrollcommand {|*arg| @scrollbar.set(*arg)} + @scrollbar.command {|*arg| self.xview(*arg)} + Tk.update # avoid scrollbar trouble + end + @scrollbar + end + def yscrollbar(bar=nil) + if bar + @scrollbar = bar + @scrollbar.orient 'vertical' + self.scrollcommand {|*arg| @scrollbar.set(*arg)} + @scrollbar.command {|*arg| self.yview(*arg)} + Tk.update # avoid scrollbar trouble + end + @scrollbar + end + alias scrollbar yscrollbar + + def view(*idxs) + if idxs.size == 0 + window(tk_send_without_enc('view')) + else + tk_send_without_enc('view', *idxs) + self + end + end + alias xview view + alias yview view + + def view_moveto(*idxs) + view('moveto', *idxs) + end + alias xview_moveto view_moveto + alias yview_moveto view_moveto + def view_scroll(*idxs) + view('scroll', *idxs) + end + alias xview_scroll view_scroll + alias yview_scroll view_scroll +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb new file mode 100644 index 0000000000..0c74440be7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb @@ -0,0 +1,92 @@ +# +# tkextlib/iwidgets/optionmenu.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Optionmenu < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Optionmenu + TkCommandNames = ['::iwidgets::optionmenu'.freeze].freeze + WidgetClassName = 'Optionmenu'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'cyclicon' + end + private :__boolval_optkeys + + def delete(first, last=nil) + if last + tk_call(@path, 'delete', first, last) + else + tk_call(@path, 'delete', first) + end + self + end + + def disable(idx) + tk_call(@path, 'disable', idx) + self + end + + def enable(idx) + tk_call(@path, 'enable', idx) + self + end + + def get(first=nil, last=nil) + if last + simplelist(tk_call(@path, 'get', first, last)) + elsif first + tk_call(@path, 'get', first) + else + tk_call(@path, 'get') + end + end + def get_range(first, last) + get(first, last) + end + def get_selected + get() + end + + def index(idx) + number(tk_call(@path, 'index', idx)) + end + + def insert(idx, *args) + tk_call(@path, 'insert', idx, *args) + self + end + + def select(idx) + tk_call(@path, 'select', idx) + self + end + + def sort(*params, &b) + # see 'lsort' man page about params + if b + tk_call(@path, 'sort', '-command', proc(&b), *params) + else + tk_call(@path, 'sort', *params) + end + self + end + def sort_ascending + tk_call(@path, 'sort', 'ascending') + self + end + def sort_descending + tk_call(@path, 'sort', 'descending') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb new file mode 100644 index 0000000000..035df0a5b8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb @@ -0,0 +1,132 @@ +# +# tkextlib/iwidgets/panedwindow.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Panedwindow < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Panedwindow + TkCommandNames = ['::iwidgets::panedwindow'.freeze].freeze + WidgetClassName = 'Panedwindow'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'panecget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'paneconfigure', id] + end + private :__item_config_cmd + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias panecget itemcget + alias paneconfigure itemconfigure + alias paneconfiginfo itemconfiginfo + alias current_paneconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def __boolval_optkeys + super() << 'showhandle' + end + private :__boolval_optkeys + + def add(tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + window(tk_call(@path, 'add', tagid(tag), *hash_kv(keys))) + tag + end + + def child_site_list + list(tk_call(@path, 'childsite')) + end + + def child_site(idx) + window(tk_call(@path, 'childsite', index(idx))) + end + + def delete(idx) + tk_call(@path, 'delete', index(idx)) + self + end + + def fraction(*percentages) + tk_call(@path, 'fraction', *percentages) + self + end + + def hide(idx) + tk_call(@path, 'hide', index(idx)) + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + window(tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys))) + tag + end + + def invoke(idx=nil) + if idx + tk_call(@path, 'invoke', index(idx)) + else + tk_call(@path, 'invoke') + end + self + end + + def reset + tk_call(@path, 'reset') + self + end + + def show(idx) + tk_call(@path, 'show', index(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb new file mode 100644 index 0000000000..620b14b5d5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb @@ -0,0 +1,131 @@ +# +# tkextlib/iwidgets/promptdialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Promptdialog < Tk::Iwidgets::Dialog + end + end +end + +class Tk::Iwidgets::Promptdialog + TkCommandNames = ['::iwidgets::promptdialog'.freeze].freeze + WidgetClassName = 'Promptdialog'.freeze + WidgetClassNames[WidgetClassName] = self + + # index method is not available, because it shows index of the entry field + def default(name) + tk_call(@path, 'default', tagid(name)) + self + end + + def hide(name) + tk_call(@path, 'hide', tagid(name)) + self + end + + def invoke(name=nil) + if name + tk_call(@path, 'invoke', tagid(name)) + else + tk_call(@path, 'invoke') + end + self + end + + def show(name) + tk_call(@path, 'show', tagid(name)) + self + end + + + # based on Tk::Iwidgets::Entryfield + def clear + tk_call(@path, 'clear') + self + end + + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + + def value + _fromUTF8(tk_send_without_enc('get')) + end + def value= (val) + tk_send_without_enc('delete', 0, 'end') + tk_send_without_enc('insert', 0, _get_eval_enc_str(val)) + val + end + alias get value + alias set value= + + def cursor=(index) + tk_send_without_enc('icursor', index) + #self + index + end + alias icursor cursor= + + def index(idx) + number(tk_send_without_enc('index', idx)) + end + + def insert(pos,text) + tk_send_without_enc('insert', pos, _get_eval_enc_str(text)) + self + end + + def mark(pos) + tk_send_without_enc('scan', 'mark', pos) + self + end + def dragto(pos) + tk_send_without_enc('scan', 'dragto', pos) + self + end + def selection_adjust(index) + tk_send_without_enc('selection', 'adjust', index) + self + end + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + def selection_from(index) + tk_send_without_enc('selection', 'from', index) + self + end + def selection_present() + bool(tk_send_without_enc('selection', 'present')) + end + def selection_range(s, e) + tk_send_without_enc('selection', 'range', s, e) + self + end + def selection_to(index) + tk_send_without_enc('selection', 'to', index) + self + 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 xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb new file mode 100644 index 0000000000..c21007ca6c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb @@ -0,0 +1,35 @@ +# +# tkextlib/iwidgets/pushbutton.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Pushbutton < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Pushbutton + TkCommandNames = ['::iwidgets::pushbutton'.freeze].freeze + WidgetClassName = 'Pushbutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'defaultring' + end + private :__boolval_optkeys + + def invoke + tk_call_without_enc(@path, 'invoke') + self + end + + def flash + tk_call_without_enc(@path, 'flash') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/radiobox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/radiobox.rb new file mode 100644 index 0000000000..1a2821bd6a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/radiobox.rb @@ -0,0 +1,116 @@ +# +# tkextlib/iwidgets/radiobox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Radiobox < Tk::Iwidgets::Labeledframe + end + end +end + +class Tk::Iwidgets::Radiobox + TkCommandNames = ['::iwidgets::radiobox'.freeze].freeze + WidgetClassName = 'Radiobox'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'buttoncget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'buttonconfigure', id] + end + private :__item_config_cmd + + def __item_boolval_optkeys(id) + super(id) << 'defaultring' + end + private :__item_boolval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias buttoncget itemcget + alias buttonconfigure itemconfigure + alias buttonconfiginfo itemconfiginfo + alias current_buttonconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def add(tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'add', tagid(tag), *hash_kv(keys)) + tag + end + + def delete(idx) + tk_call(@path, 'delete', index(idx)) + self + end + + def deselect(idx) + tk_call(@path, 'deselect', index(idx)) + self + end + + def flash(idx) + tk_call(@path, 'flash', index(idx)) + self + end + + def get(idx) + simplelist(tk_call(@path, 'get', index(idx))).collect{|id| + Tk::Itk::Component.id2obj(self, id) + } + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys)) + tag + end + + def select(idx) + tk_call(@path, 'select', index(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb new file mode 100644 index 0000000000..bddef50841 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb @@ -0,0 +1,24 @@ +# +# tkextlib/iwidgets/buttonbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scopedobject < TkObject + end + end +end + +class Tk::Iwidgets::Scopedobject + TkCommandNames = ['::iwidgets::scopedobject'.freeze].freeze + WidgetClassName = 'Scopedobject'.freeze + WidgetClassNames[WidgetClassName] = self + + def initialize(obj_name, keys={}) + @path = tk_call(self.class::TkCommandNames[0], obj_name, *hash_kv(keys)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb new file mode 100644 index 0000000000..407c8f2aad --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb @@ -0,0 +1,347 @@ +# +# tkextlib/iwidgets/scrolledcanvas.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/canvas' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scrolledcanvas < Tk::Iwidgets::Scrolledwidget + end + end +end + +class Tk::Iwidgets::Scrolledcanvas + TkCommandNames = ['::iwidgets::scrolledcanvas'.freeze].freeze + WidgetClassName = 'Scrolledcanvas'.freeze + WidgetClassNames[WidgetClassName] = self + + ################################ + + def __boolval_optkeys + super() << 'autoresize' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'textbackground' + end + private :__strval_optkeys + + def initialize(*args) + super(*args) + @canvas = component_widget('canvas') + end + + def method_missing(id, *args) + if @canvas.methods.include?(id.id2name) + @canvas.__send__(id, *args) + else + super(id, *args) + end + end + + ################################ + + def child_site + window(tk_call(@path, 'childsite')) + end + + def justify(dir) + tk_call(@path, 'justify', dir) + self + end + + ########################## + include TkCanvasItemConfig + + def tagid(tag) + if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag) + tag.id + elsif tag.kind_of?(Tk::Itk::Component) + tag.name + else + tag # maybe an Array of configure paramters + end + end + private :tagid + + # create a canvas item without creating a TkcItem object + def create(type, *args) + type.create(self, *args) + end + + ####################### + + def addtag(tag, mode, *args) + tk_send_without_enc('addtag', tagid(tag), mode, *args) + self + end + def addtag_above(tagOrId, target) + addtag(tagOrId, 'above', tagid(target)) + end + def addtag_all(tagOrId) + addtag(tagOrId, 'all') + end + def addtag_below(tagOrId, target) + addtag(tagOrId, 'below', tagid(target)) + end + def addtag_closest(tagOrId, x, y, halo=None, start=None) + addtag(tagOrId, 'closest', x, y, halo, start) + end + def addtag_enclosed(tagOrId, x1, y1, x2, y2) + addtag(tagOrId, 'enclosed', x1, y1, x2, y2) + end + def addtag_overlapping(tagOrId, x1, y1, x2, y2) + addtag(tagOrId, 'overlapping', x1, y1, x2, y2) + end + def addtag_withtag(tagOrId, tag) + addtag(tagOrId, 'withtag', tagid(tag)) + end + + def bbox(tagOrId, *tags) + list(tk_send_without_enc('bbox', tagid(tagOrId), + *tags.collect{|t| tagid(t)})) + end + + #def itembind(tag, context, cmd=Proc.new, *args) + # _bind([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def itembind(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, "bind", tagid(tag)], context, cmd, *args) + self + end + + #def itembind_append(tag, context, cmd=Proc.new, *args) + # _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + # self + #end + def itembind_append(tag, context, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, "bind", tagid(tag)], context, cmd, *args) + self + end + + def itembind_remove(tag, context) + _bind_remove([path, "bind", tagid(tag)], context) + self + end + + def itembindinfo(tag, context=nil) + _bindinfo([path, "bind", tagid(tag)], context) + end + + def canvasx(screen_x, *args) + #tk_tcl2ruby(tk_send_without_enc('canvasx', screen_x, *args)) + number(tk_send_without_enc('canvasx', screen_x, *args)) + end + def canvasy(screen_y, *args) + #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args)) + number(tk_send_without_enc('canvasy', screen_y, *args)) + end + + def coords(tag, *args) + if args == [] + tk_split_list(tk_send_without_enc('coords', tagid(tag))) + else + tk_send_without_enc('coords', tagid(tag), *(args.flatten)) + self + end + end + + def dchars(tag, first, last=None) + tk_send_without_enc('dchars', tagid(tag), + _get_eval_enc_str(first), _get_eval_enc_str(last)) + self + end + + def delete(*args) + if TkcItem::CItemID_TBL[self.path] + find('withtag', *args).each{|item| + if item.kind_of?(TkcItem) + TkcItem::CItemID_TBL[self.path].delete(item.id) + end + } + end + tk_send_without_enc('delete', *args.collect{|t| tagid(t)}) + self + end + alias remove delete + + def dtag(tag, tag_to_del=None) + tk_send_without_enc('dtag', tagid(tag), tag_to_del) + self + end + + def find(mode, *args) + list(tk_send_without_enc('find', mode, *args)).collect!{|id| + TkcItem.id2obj(self, id) + } + end + def find_above(target) + find('above', tagid(target)) + end + def find_all + find('all') + end + def find_below(target) + find('below', tagid(target)) + end + def find_closest(x, y, halo=None, start=None) + find('closest', x, y, halo, start) + end + def find_enclosed(x1, y1, x2, y2) + find('enclosed', x1, y1, x2, y2) + end + def find_overlapping(x1, y1, x2, y2) + find('overlapping', x1, y1, x2, y2) + end + def find_withtag(tag) + find('withtag', tag) + end + + def itemfocus(tagOrId=nil) + if tagOrId + tk_send_without_enc('focus', tagid(tagOrId)) + self + else + ret = tk_send_without_enc('focus') + if ret == "" + nil + else + TkcItem.id2obj(self, ret) + end + end + end + + def gettags(tagOrId) + list(tk_send_without_enc('gettags', tagid(tagOrId))).collect{|tag| + TkcTag.id2obj(self, tag) + } + end + + def icursor(tagOrId, index) + tk_send_without_enc('icursor', tagid(tagOrId), index) + self + end + + def index(tagOrId, idx) + number(tk_send_without_enc('index', tagid(tagOrId), idx)) + end + + def insert(tagOrId, index, string) + tk_send_without_enc('insert', tagid(tagOrId), index, + _get_eval_enc_str(string)) + self + 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 + + def xview(*index) + if index.size == 0 + list(tk_send_without_enc('xview')) + else + tk_send_without_enc('xview', *index) + self + end + end + def xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + 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 yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb new file mode 100644 index 0000000000..8b47460357 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb @@ -0,0 +1,59 @@ +# +# tkextlib/iwidgets/scrolledframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scrolledframe < Tk::Iwidgets::Scrolledwidget + end + end +end + +class Tk::Iwidgets::Scrolledframe + TkCommandNames = ['::iwidgets::scrolledframe'.freeze].freeze + WidgetClassName = 'Scrolledframe'.freeze + WidgetClassNames[WidgetClassName] = self + + def child_site + window(tk_call(@path, 'childsite')) + end + + def justify(dir) + tk_call(@path, 'justify', dir) + self + 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 xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + 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 yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb new file mode 100644 index 0000000000..9b69ef07fe --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb @@ -0,0 +1,58 @@ +# +# tkextlib/iwidgets/scrolledhtml.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scrolledhtml < Tk::Iwidgets::Scrolledtext + end + end +end + +class Tk::Iwidgets::Scrolledhtml + TkCommandNames = ['::iwidgets::scrolledhtml'.freeze].freeze + WidgetClassName = 'Scrolledhtml'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'update' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'fontname' << 'link' << 'alink' << 'textbackground' + end + private :__strval_optkeys + + def __font_optkeys + super() << 'fixedfont' + end + private :__font_optkeys + + def import(href) + tk_call(@path, 'import', href) + self + end + + def import_link(href) + tk_call(@path, 'import', '-link', href) + self + end + + def pwd + tk_call(@path, 'pwd') + end + + def render(htmltext, workdir=None) + tk_call(@path, 'render', htmltext, workdir) + self + end + + def title + tk_call(@path, 'title') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb new file mode 100644 index 0000000000..cd1f6f0f79 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb @@ -0,0 +1,207 @@ +# +# tkextlib/iwidgets/scrolledlistbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/listbox' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scrolledlistbox < Tk::Iwidgets::Scrolledwidget + end + end +end + +class Tk::Iwidgets::Scrolledlistbox + TkCommandNames = ['::iwidgets::scrolledlistbox'.freeze].freeze + WidgetClassName = 'Scrolledlistbox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'textbackground' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'listvariable' + end + private :__tkvariable_optkeys + + def __font_optkeys + super() << 'textfont' + end + private :__font_optkeys + + ################################ + + def initialize(*args) + super(*args) + @listbox = component_widget('listbox') + end + + def method_missing(id, *args) + if @listbox.methods.include?(id.id2name) + @listbox.__send__(id, *args) + else + super(id, *args) + end + end + + ################################ + + def clear + tk_call(@path, 'clear') + self + end + + def get_curselection + tk_call(@path, 'getcurselection') + end + + def justify(dir) + tk_call(@path, 'justify', dir) + self + end + + def selected_item_count + number(tk_call(@path, 'selecteditemcount')) + end + + def sort(*params, &b) + # see 'lsort' man page about params + if b + tk_call(@path, 'sort', '-command', proc(&b), *params) + else + tk_call(@path, 'sort', *params) + end + self + end + def sort_ascending + tk_call(@path, 'sort', 'ascending') + self + end + def sort_descending + tk_call(@path, 'sort', 'descending') + self + end + + ##################################### + + def bbox(index) + list(tk_send_without_enc('bbox', index)) + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def get(*index) + _fromUTF8(tk_send_without_enc('get', *index)) + end + def insert(index, *args) + tk_send('insert', index, *args) + 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 see(index) + tk_send_without_enc('see', index) + self + end + + ##################################### + + include TkListItemConfig + + def tagid(tag) + if tag.kind_of?(Tk::Itk::Component) + tag.name + else + super(tag) + end + end + private :tagid + + ##################################### + + def activate(y) + tk_send_without_enc('activate', y) + self + end + def curselection + list(tk_send_without_enc('curselection')) + end + def get(first, last=nil) + if last + # tk_split_simplelist(_fromUTF8(tk_send_without_enc('get', first, last))) + tk_split_simplelist(tk_send_without_enc('get', first, last), + false, true) + else + _fromUTF8(tk_send_without_enc('get', first)) + end + end + def nearest(y) + tk_send_without_enc('nearest', y).to_i + end + def size + tk_send_without_enc('size').to_i + end + def selection_anchor(index) + tk_send_without_enc('selection', 'anchor', index) + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', first, last) + self + end + def selection_includes(index) + bool(tk_send_without_enc('selection', 'includes', index)) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', first, last) + self + end + + def index(idx) + tk_send_without_enc('index', idx).to_i + 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 xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + 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 yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb new file mode 100644 index 0000000000..fdafc8dc7f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb @@ -0,0 +1,538 @@ +# +# tkextlib/iwidgets/scrolledtext.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/text' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scrolledtext < Tk::Iwidgets::Scrolledwidget + end + end +end + +class Tk::Iwidgets::Scrolledtext + TkCommandNames = ['::iwidgets::scrolledtext'.freeze].freeze + WidgetClassName = 'Scrolledtext'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'textbackground' + end + private :__strval_optkeys + + def __font_optkeys + super() << 'textfont' + end + private :__font_optkeys + + ################################ + + def initialize(*args) + super(*args) + @text = component_widget('text') + end + + def method_missing(id, *args) + if @text.methods.include?(id.id2name) + @text.__send__(id, *args) + else + super(id, *args) + end + end + + ################################ + + def child_site + window(tk_call(@path, 'childsite')) + end + + def clear + tk_call(@path, 'clear') + self + end + + def import(file, idx=nil) + if idx + tk_call(@path, 'import', file, index(idx)) + else + tk_call(@path, 'import', file) + end + self + end + + def export(file) + tk_call(@path, 'export', file) + self + end + + ##################################### + + include TkTextTagConfig + + def tagid(tag) + if tag.kind_of?(Tk::Itk::Component) + tag.name + else + super(tag) + end + end + private :tagid + + def bbox(index) + list(tk_send('bbox', 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 debug + bool(tk_send_without_enc('debug')) + end + def debug=(boolean) + tk_send_without_enc('debug', boolean) + #self + boolean + end + + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + + def dlineinfo(index) + list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index))) + end + + def get(*index) + _fromUTF8(tk_send_without_enc('get', *index)) + end + def get_displaychars(*index) + # Tk8.5 feature + get('-displaychars', *index) + end + + def image_cget(index, slot) + case slot.to_s + when 'text', 'label', 'show', 'data', 'file' + _fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), "-#{slot}")) + else + tk_tcl2ruby(_fromUTF8(tk_send_without_enc('image', 'cget', + _get_eval_enc_str(index), + "-#{slot}"))) + end + end + + def image_configure(index, slot, value=None) + if slot.kind_of? Hash + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + *hash_kv(slot, true))) + else + _fromUTF8(tk_send_without_enc('image', 'configure', + _get_eval_enc_str(index), + "-#{slot}", + _get_eval_enc_str(value))) + end + self + end + + def image_configinfo(index, 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_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + conf[0] = conf[0][1..-1] + conf + else + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).collect{|conflist| + # conf = tk_split_simplelist(conflist) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).collect{|conflist| + conf = tk_split_simplelist(conflist, false, true) + 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_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), false, true) + else + #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"))) + conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), "-#{slot}"), 0, false, true) + end + key = conf.shift[1..-1] + { key => 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) + tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).each{|conflist| + conf = tk_split_simplelist(conflist, false, true) + 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| + tk_split_simplelist(tk_send_without_enc('image', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def index(idx) + tk_send_without_enc('index', _get_eval_enc_str(idx)) + end + + def insert(index, *args) + tk_send('insert', index, *args) + self + end + + def mark_names + #tk_split_simplelist(_fromUTF8(tk_send_without_enc('mark', 'names'))).collect{|elt| + tk_split_simplelist(tk_send_without_enc('mark', 'names'), false, true).collect{|elt| + tagid2obj(elt) + } + end + + def mark_gravity(mark, direction=nil) + if direction + tk_send_without_enc('mark', 'gravity', + _get_eval_enc_str(mark), direction) + self + else + tk_send_without_enc('mark', 'gravity', _get_eval_enc_str(mark)) + end + end + + def mark_set(mark, index) + tk_send_without_enc('mark', 'set', _get_eval_enc_str(mark), + _get_eval_enc_str(index)) + self + end + alias set_mark mark_set + + def mark_unset(*marks) + tk_send_without_enc('mark', 'unset', + *(marks.collect{|mark| _get_eval_enc_str(mark)})) + self + end + alias unset_mark mark_unset + + def mark_next(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'next', + _get_eval_enc_str(index)))) + end + alias next_mark mark_next + + def mark_previous(index) + tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'previous', + _get_eval_enc_str(index)))) + end + alias previous_mark mark_previous + + 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 _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 ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| '-' + opt.to_s } + else + opts = [] + end + + opts << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + ret + end + end + + def tksearch_with_count(*args) + # call 'search' subcommand of text widget + # args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>] + # If <pattern> is regexp, then it must be a regular expression of Tcl + if args[0].kind_of?(Array) + opts = args.shift.collect{|opt| '-' + opt.to_s } + else + opts = [] + end + + opts << '-count' << args.shift << '--' + + ret = tk_send('search', *(opts + args)) + if ret == "" + nil + else + ret + 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 see(index) + tk_send_without_enc('see', index) + self + 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 xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + 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 yview_moveto(*index) + yview('moveto', *index) + end + def yview_scroll(*index) + yview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb new file mode 100644 index 0000000000..eef093d314 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb @@ -0,0 +1,20 @@ +# +# tkextlib/iwidgets/scrolledwidget.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Scrolledwidget < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Scrolledwidget + TkCommandNames = ['::iwidgets::scrolledwidget'.freeze].freeze + WidgetClassName = 'Scrolledwidget'.freeze + WidgetClassNames[WidgetClassName] = self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb new file mode 100644 index 0000000000..bb81fcca5e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb @@ -0,0 +1,102 @@ +# +# tkextlib/iwidgets/selectionbox.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Selectionbox < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Selectionbox + TkCommandNames = ['::iwidgets::selectionbox'.freeze].freeze + WidgetClassName = 'Selectionbox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'itemson' << 'selectionon' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'itemslabel' << 'selectionlabel' + end + private :__strval_optkeys + + def child_site + window(tk_call(@path, 'childsite')) + end + + def clear_items + tk_call(@path, 'clear', 'items') + self + end + + def clear_selection + tk_call(@path, 'clear', 'selection') + self + end + + def get + tk_call(@path, 'get') + end + + def insert_items(idx, *args) + tk_call(@path, 'insert', 'items', idx, *args) + end + + def insert_selection(pos, text) + tk_call(@path, 'insert', 'selection', pos, text) + end + + def select_item + tk_call(@path, 'selectitem') + self + end + + # based on TkListbox ( and TkTextWin ) + def curselection + list(tk_send_without_enc('curselection')) + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def index(idx) + tk_send_without_enc('index', idx).to_i + end + def nearest(y) + tk_send_without_enc('nearest', y).to_i + 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 selection_anchor(index) + tk_send_without_enc('selection', 'anchor', index) + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', first, last) + self + end + def selection_includes(index) + bool(tk_send_without_enc('selection', 'includes', index)) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', first, last) + self + end + def size + tk_send_without_enc('size').to_i + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb new file mode 100644 index 0000000000..ab790e97a6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb @@ -0,0 +1,92 @@ +# +# tkextlib/iwidgets/selectiondialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Selectiondialog < Tk::Iwidgets::Dialog + end + end +end + +class Tk::Iwidgets::Selectiondialog + TkCommandNames = ['::iwidgets::selectiondialog'.freeze].freeze + WidgetClassName = 'Selectiondialog'.freeze + WidgetClassNames[WidgetClassName] = self + + def child_site + window(tk_call(@path, 'childsite')) + end + + def clear_items + tk_call(@path, 'clear', 'items') + self + end + + def clear_selection + tk_call(@path, 'clear', 'selection') + self + end + + def get + tk_call(@path, 'get') + end + + def insert_items(idx, *args) + tk_call(@path, 'insert', 'items', idx, *args) + end + + def insert_selection(pos, text) + tk_call(@path, 'insert', 'selection', pos, text) + end + + def select_item + tk_call(@path, 'selectitem') + self + end + + # based on TkListbox ( and TkTextWin ) + def curselection + list(tk_send_without_enc('curselection')) + end + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + def index(idx) + tk_send_without_enc('index', idx).to_i + end + def nearest(y) + tk_send_without_enc('nearest', y).to_i + 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 selection_anchor(index) + tk_send_without_enc('selection', 'anchor', index) + self + end + def selection_clear(first, last=None) + tk_send_without_enc('selection', 'clear', first, last) + self + end + def selection_includes(index) + bool(tk_send_without_enc('selection', 'includes', index)) + end + def selection_set(first, last=None) + tk_send_without_enc('selection', 'set', first, last) + self + end + def size + tk_send_without_enc('size').to_i + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/shell.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/shell.rb new file mode 100644 index 0000000000..dabf2e6f25 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/shell.rb @@ -0,0 +1,38 @@ +# +# tkextlib/iwidgets/shell.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Shell < Tk::Itk::Toplevel + end + end +end + +class Tk::Iwidgets::Shell + TkCommandNames = ['::iwidgets::shell'.freeze].freeze + WidgetClassName = 'Shell'.freeze + WidgetClassNames[WidgetClassName] = self + + def activate + tk_call(@path, 'activate') # may return val of deactibate method + end + + def center(win=None) + tk_call(@path, 'center', win) + self + end + + def child_site + window(tk_call(@path, 'childsite')) + end + + def deactivate(val=None) + tk_call(@path, 'deactivate', val) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spindate.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spindate.rb new file mode 100644 index 0000000000..2c98eb4629 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spindate.rb @@ -0,0 +1,48 @@ +# +# tkextlib/iwidgets/spindate.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Spindate < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Spindate + TkCommandNames = ['::iwidgets::spindate'.freeze].freeze + WidgetClassName = 'Spindate'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'dayon' << 'monthon' << 'yearon' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'daylabel' << 'monthformat' << 'monthlabel' << 'yearlabel' + end + private :__strval_optkeys + + def get_string + tk_call(@path, 'get', '-string') + end + alias get get_string + + def get_clicks + number(tk_call(@path, 'get', '-clicks')) + end + + def show(date=None) + tk_call(@path, 'show', date) + self + end + def show_now + tk_call(@path, 'show', 'now') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spinint.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spinint.rb new file mode 100644 index 0000000000..5eb944d081 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spinint.rb @@ -0,0 +1,30 @@ +# +# tkextlib/iwidgets/spinint.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Spinint < Tk::Iwidgets::Spinner + end + end +end + +class Tk::Iwidgets::Spinint + TkCommandNames = ['::iwidgets::spinint'.freeze].freeze + WidgetClassName = 'Spinint'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'wrap' + end + private :__boolval_optkeys + + def __numlistval_optkeys + super() << 'range' + end + private :__numlistval_optkeys +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spinner.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spinner.rb new file mode 100644 index 0000000000..174b9bd506 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spinner.rb @@ -0,0 +1,150 @@ +# +# tkextlib/iwidgets/spinner.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Spinner < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Spinner + TkCommandNames = ['::iwidgets::spinner'.freeze].freeze + WidgetClassName = 'Spinner'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include Tk::ValidateConfigure + + class EntryfieldValidate < TkValidateCommand + #class CalCmdArgs < TkUtil::CallbackSubst + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?c, ?s, :char ], + [ ?P, ?s, :post ], + [ ?S, ?s, :current ], + [ ?W, ?w, :widget ], + nil + ] + PROC_TBL = [ + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + nil + ] + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + def self._config_keys + ['validate', 'invalid'] + end + end + + def __validation_class_list + super() << EntryfieldValidate + end + + Tk::ValidateConfigure.__def_validcmd(binding, EntryfieldValidate) + + #################################### + + def up + tk_call_without_enc(@path, 'up') + self + end + + def down + tk_call_without_enc(@path, 'down') + self + end + + def clear + tk_call_without_enc(@path, 'clear') + self + end + + def delete(first, last=None) + tk_send_without_enc('delete', first, last) + self + end + + def value + _fromUTF8(tk_send_without_enc('get')) + end + def value= (val) + tk_send_without_enc('delete', 0, 'end') + tk_send_without_enc('insert', 0, _get_eval_enc_str(val)) + val + end + alias get value + alias set value= + + def cursor=(index) + tk_send_without_enc('icursor', index) + #self + index + end + alias icursor cursor= + + def index(idx) + number(tk_send_without_enc('index', idx)) + end + + def insert(pos,text) + tk_send_without_enc('insert', pos, _get_eval_enc_str(text)) + self + end + + def mark(pos) + tk_send_without_enc('scan', 'mark', pos) + self + end + def dragto(pos) + tk_send_without_enc('scan', 'dragto', pos) + self + end + def selection_adjust(index) + tk_send_without_enc('selection', 'adjust', index) + self + end + def selection_clear + tk_send_without_enc('selection', 'clear') + self + end + def selection_from(index) + tk_send_without_enc('selection', 'from', index) + self + end + def selection_present() + bool(tk_send_without_enc('selection', 'present')) + end + def selection_range(s, e) + tk_send_without_enc('selection', 'range', s, e) + self + end + def selection_to(index) + tk_send_without_enc('selection', 'to', index) + self + end + + # based on tk/scrollable.rb + def xview(*index) + if index.size == 0 + list(tk_send_without_enc('xview')) + else + tk_send_without_enc('xview', *index) + self + end + end + def xview_moveto(*index) + xview('moveto', *index) + end + def xview_scroll(*index) + xview('scroll', *index) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spintime.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spintime.rb new file mode 100644 index 0000000000..0ff683ab56 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/spintime.rb @@ -0,0 +1,48 @@ +# +# tkextlib/iwidgets/spintime.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Spintime < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Spintime + TkCommandNames = ['::iwidgets::spintime'.freeze].freeze + WidgetClassName = 'Spintime'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'houron' << 'militaryon' << 'minutelabel' << 'secondlabel' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'hourlabel' << 'minuteon' << 'secondon' + end + private :__strval_optkeys + + def get_string + tk_call(@path, 'get', '-string') + end + alias get get_string + + def get_clicks + number(tk_call(@path, 'get', '-clicks')) + end + + def show(date=None) + tk_call(@path, 'show', date) + self + end + def show_now + tk_call(@path, 'show', 'now') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb new file mode 100644 index 0000000000..0d9715f87b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb @@ -0,0 +1,169 @@ +# +# tkextlib/iwidgets/tabnotebook.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Tabnotebook < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Tabnotebook + TkCommandNames = ['::iwidgets::tabnotebook'.freeze].freeze + WidgetClassName = 'Tabnotebook'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'pagecget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'pageconfigure', id] + end + private :__item_config_cmd + + def __item_strval_optkeys(id) + super(id) << 'tabbackground' << 'tabforeground' + end + private :__item_strval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias pagecget itemcget + alias pageconfigure itemconfigure + alias pageconfiginfo itemconfiginfo + alias current_pageconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def __boolval_optkeys + super() << 'auto' << 'equaltabs' << 'raiseselect' << 'tabborders' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'backdrop' << 'tabbackground' << 'tabforeground' + end + private :__strval_optkeys + + def initialize(*args) + super(*args) + @tabset = self.component_widget('tabset') + end + + def add(keys={}) + window(tk_call(@path, 'add', *hash_kv(keys))) + end + + def child_site_list + list(tk_call(@path, 'childsite')) + end + + def child_site(idx) + window(tk_call(@path, 'childsite', index(idx))) + end + + def delete(idx1, idx2=nil) + if idx2 + tk_call(@path, 'delete', index(idx1), index(idx2)) + else + tk_call(@path, 'delete', index(idx1)) + end + self + end + + def index(idx) + #number(tk_call(@path, 'index', tagid(idx))) + @tabset.index(tagid(idx)) + end + + def insert(idx, keys={}) + window(tk_call(@path, 'insert', index(idx), *hash_kv(keys))) + end + + def next + tk_call(@path, 'next') + self + end + + def prev + tk_call(@path, 'prev') + self + end + + def select(idx) + tk_call(@path, 'select', index(idx)) + self + end + + def scrollcommand(cmd=Proc.new) + configure_cmd 'scrollcommand', cmd + self + end + alias xscrollcommand scrollcommand + alias yscrollcommand scrollcommand + + def xscrollbar(bar=nil) + if bar + @scrollbar = bar + @scrollbar.orient 'horizontal' + self.scrollcommand {|*arg| @scrollbar.set(*arg)} + @scrollbar.command {|*arg| self.xview(*arg)} + Tk.update # avoid scrollbar trouble + end + @scrollbar + end + def yscrollbar(bar=nil) + if bar + @scrollbar = bar + @scrollbar.orient 'vertical' + self.scrollcommand {|*arg| @scrollbar.set(*arg)} + @scrollbar.command {|*arg| self.yview(*arg)} + Tk.update # avoid scrollbar trouble + end + @scrollbar + end + alias scrollbar yscrollbar + + def view(*index) + if index.size == 0 + window(tk_send_without_enc('view')) + else + tk_send_without_enc('view', *index) + self + end + end + alias xview view + alias yview view + + def view_moveto(*index) + view('moveto', *index) + end + alias xview_moveto view_moveto + alias yview_moveto view_moveto + def view_scroll(*index) + view('scroll', *index) + end + alias xview_scroll view_scroll + alias yview_scroll view_scroll +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/tabset.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/tabset.rb new file mode 100644 index 0000000000..54e56d0514 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/tabset.rb @@ -0,0 +1,99 @@ +# +# tkextlib/iwidgets/tabset.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Tabset < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Tabset + TkCommandNames = ['::iwidgets::tabset'.freeze].freeze + WidgetClassName = 'Tabset'.freeze + WidgetClassNames[WidgetClassName] = self + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'tabcget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'tabconfigure', id] + end + private :__item_config_cmd + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + alias tabcget itemcget + alias tabconfigure itemconfigure + alias tabconfiginfo itemconfiginfo + alias current_tabconfiginfo current_itemconfiginfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo + + #################################### + + def __boolval_optkeys + super() << 'equaltabs' << 'raiseselect' << 'tabborders' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'backdrop' + end + private :__strval_optkeys + + def add(keys={}) + window(tk_call(@path, 'add', *hash_kv(keys))) + end + + def delete(idx1, idx2=nil) + if idx2 + tk_call(@path, 'delete', index(idx1), index(idx2)) + else + tk_call(@path, 'delete', index(idx1)) + end + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, keys={}) + window(tk_call(@path, 'insert', index(idx), *hash_kv(keys))) + end + + def next + tk_call(@path, 'next') + self + end + + def prev + tk_call(@path, 'prev') + self + end + + def select(idx) + tk_call(@path, 'select', index(idx)) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/timeentry.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/timeentry.rb new file mode 100644 index 0000000000..588da77dc8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/timeentry.rb @@ -0,0 +1,25 @@ +# +# tkextlib/iwidgets/timeentry.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Timeentry < Tk::Iwidgets::Timefield + end + end +end + +class Tk::Iwidgets::Timeentry + TkCommandNames = ['::iwidgets::timeentry'.freeze].freeze + WidgetClassName = 'Timeentry'.freeze + WidgetClassNames[WidgetClassName] = self + + def __strval_optkeys + super() << 'closetext' + end + private :__strval_optkeys +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/timefield.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/timefield.rb new file mode 100644 index 0000000000..28e1504797 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/timefield.rb @@ -0,0 +1,58 @@ +# +# tkextlib/iwidgets/timefield.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Timefield < Tk::Iwidgets::Labeledwidget + end + end +end + +class Tk::Iwidgets::Timefield + TkCommandNames = ['::iwidgets::timefield'.freeze].freeze + WidgetClassName = 'Timefield'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'gmt' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'textbackground' + end + private :__strval_optkeys + + def __font_optkeys + super() << 'textfont' + end + private :__font_optkeys + + def get_string + tk_call(@path, 'get', '-string') + end + alias get get_string + + def get_clicks + number(tk_call(@path, 'get', '-clicks')) + end + + def valid? + bool(tk_call(@path, 'isvalid')) + end + alias isvalid? valid? + + def show(time=None) + tk_call(@path, 'show', time) + self + end + def show_now + tk_call(@path, 'show', 'now') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/toolbar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/toolbar.rb new file mode 100644 index 0000000000..17cfa62156 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/toolbar.rb @@ -0,0 +1,112 @@ +# +# tkextlib/iwidgets/toolbar.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Toolbar < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Toolbar + TkCommandNames = ['::iwidgets::toolbar'.freeze].freeze + WidgetClassName = 'Toolbar'.freeze + WidgetClassNames[WidgetClassName] = self + + def __tkvariable_optkeys + super() << 'helpvariable' + end + private :__tkvariable_optkeys + + #################################### + + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'itemcget', self.index(id)] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'itemconfigure', self.index(id)] + end + private :__item_config_cmd + + def __item_strval_optkeys(id) + super(id) << 'helpstr' << 'balloonstr' + end + private :__item_strval_optkeys + + def tagid(tagOrId) + if tagOrId.kind_of?(Tk::Itk::Component) + tagOrId.name + else + #_get_eval_string(tagOrId) + tagOrId + end + end + + #################################### + + def __strval_optkeys + super() << 'balloonbackground' << 'balloonforeground' + end + private :__strval_optkeys + + def __tkvariable_optkeys + super() << 'helpvariable' + end + private :__tkvariable_optkeys + + def __font_optkeys + super() << 'balloonfont' + end + private :__font_optkeys + + def add(type, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + window(tk_call(@path, 'add', type, tagid(tag), *hash_kv(keys))) + tag + end + + def delete(idx1, idx2=nil) + if idx2 + tk_call(@path, 'delete', index(idx1), index(idx2)) + else + tk_call(@path, 'delete', index(idx1)) + end + self + end + + def index(idx) + number(tk_call(@path, 'index', tagid(idx))) + end + + def insert(idx, type, tag=nil, keys={}) + if tag.kind_of?(Hash) + keys = tag + tag = nil + end + if tag + tag = Tk::Itk::Component.new(self, tagid(tag)) + else + tag = Tk::Itk::Component.new(self) + end + window(tk_call(@path, 'insert', index(idx), type, + tagid(tag), *hash_kv(keys))) + tag + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/watch.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/watch.rb new file mode 100644 index 0000000000..ab2b687cf9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/iwidgets/watch.rb @@ -0,0 +1,56 @@ +# +# tkextlib/iwidgets/watch.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tkextlib/iwidgets.rb' + +module Tk + module Iwidgets + class Watch < Tk::Itk::Widget + end + end +end + +class Tk::Iwidgets::Watch + TkCommandNames = ['::iwidgets::watch'.freeze].freeze + WidgetClassName = 'Watch'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'showampm' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'clockcolor' << 'hourcolor' << 'minutecolor' << + 'pivotcolor' << 'secondcolor' << 'tickcolor' + end + private :__strval_optkeys + + def get_string + tk_call(@path, 'get', '-string') + end + alias get get_string + + def get_clicks + number(tk_call(@path, 'get', '-clicks')) + end + + def show(time=None) + tk_call(@path, 'show', time) + self + end + def show_now + tk_call(@path, 'show', 'now') + self + end + + def watch(*args) + unless args.empty? + tk_call(@path, 'watch', *args) + end + component_path('canvas') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/pkg_checker.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/pkg_checker.rb new file mode 100755 index 0000000000..5002ed7ff8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/pkg_checker.rb @@ -0,0 +1,184 @@ +#!/usr/bin/env ruby +# +# Ruby/Tk extension library checker +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +TkRoot.new.withdraw # hide root window + +name = File.basename(__FILE__) + +add_path = false +verbose = false + +def help_msg + print "Usage: #{$0} [-l] [-v] [-h] [--] [dir]\n" + print "\tIf dir is omitted, check the directry that this command exists.\n" + print "\tAvailable options are \n" + print "\t -l : Add dir to $LOAD_PATH\n" + print "\t (If dir == '<parent>/tkextlib', add <parent> also.)\n" + print "\t -v : Verbose mode (show reason of fail)\n" + print "\t -h : Show this message\n" + print "\t -- : End of options\n" +end + +while(ARGV[0] && ARGV[0][0] == ?-) + case ARGV[0] + when '--' + ARGV.shift + break; + when '-l' + ARGV.shift + add_path = true + when '-v' + ARGV.shift + verbose = true + when '-h' + help_msg + exit(0) + else + print "Argument Error!! : unknown option '#{ARGV[0]}'\n" + help_msg + exit(1) + end +end + +if ARGV[0] + dir = File.expand_path(ARGV[0]) +else + dir = File.dirname(File.expand_path(__FILE__)) +end + +if add_path + $LOAD_PATH.unshift(dir) + if File.basename(dir) == 'tkextlib' + $LOAD_PATH.unshift(File.dirname(dir)) + end +end + +print "\nRuby/Tk extension library checker\n" +print "( Note:: This check is very simple one. Shown status may be wrong. )\n" +print "\n check directory :: #{dir}" +print "\n $LOAD_PATH :: #{$LOAD_PATH.inspect}\n" + +def get_pkg_list(file) + pkg_list = [] + + File.foreach(file){|l| + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)TkPackage\s*\.\s*require\s*\(?\s*(["'])((\w|:)+)\1/ + pkg = [$2, :package] + pkg_list << pkg unless pkg_list.member?(pkg) + end + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)Tk\s*\.\s*load_tcllibrary\s*\(?\s*(["'])((\w|:)+)\1/ + pkg = [$2, :library] + pkg_list << pkg unless pkg_list.member?(pkg) + end + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)Tk\s*\.\s*load_tclscript\s*\(?\s*(["'])((\w|:)+)\1/ + pkg = [$2, :script] + pkg_list << pkg unless pkg_list.member?(pkg) + end + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)require\s*\(?\s*(["'])((\w|\/|:)+)\1/ + pkg = [$2, :require_ruby_lib] + pkg_list << pkg unless pkg_list.member?(pkg) + end + } + + pkg_list +end + +def check_pkg(file, verbose=false) + pkg_list = get_pkg_list(file) + + error_list = [] + success_list = {} + + pkg_list.each{|name, type| + next if success_list[name] + + begin + case type + when :package + ver = TkPackage.require(name) + success_list[name] = ver + error_list.delete_if{|n, t| n == name} + + when :library + Tk.load_tcllibrary(name) + success_list[name] = :library + error_list.delete_if{|n, t| n == name} + + when :script + Tk.load_tclscript(name) + success_list[name] = :script + error_list.delete_if{|n, t| n == name} + + when :require_ruby_lib + require name + + end + rescue => e + if verbose + error_list << [name, type, e.message] + else + error_list << [name, type] + end + end + } + + success_list.dup.each{|name, ver| + unless ver.kind_of?(String) + begin + ver = TkPackage.require(name) + sccess_list[name] = ver + rescue + end + end + } + + [success_list, error_list] +end + +def subdir_check(dir, verbose=false) + Dir.foreach(dir){|f| + next if f == '.' || f == '..' + if File.directory?(f) + subdir_check(File.join(dir, f)) + elsif File.extname(f) == '.rb' + path = File.join(dir, f) + suc, err = check_pkg(path, verbose) + if err.empty? + print 'Ready : ', path, ' : require->', suc.inspect, "\n" + else + print '*LACK : ', path, ' : require->', suc.inspect, + ' FAIL->', err.inspect, "\n" + end + end + } +end + +Dir.chdir(dir) + +(Dir['*.rb'] - ['setup.rb', name]).each{|f| + subdir = File.basename(f, '.*') +=begin + begin + # read 'setup.rb' as if the library has standard structure + require File.join(subdir, 'setup.rb') + rescue LoadError + # ignore error + end +=end + print "\n" + + suc, err = check_pkg(f, verbose) + if err.empty? + print 'Ready : ', f, ' : require->', suc.inspect, "\n" + else + print '*LACK : ', f, ' : require->', suc.inspect, + ' FAIL->', err.inspect, "\n" + end + + subdir_check(subdir, verbose) if File.directory?(subdir) +} diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/setup.rb new file mode 100644 index 0000000000..12867e8f9c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before using Tk extension libraries +# +# If you need some setup operations for Tk extensions (for example, +# modify the dynamic library path) required, please write the setup +# operations in this file. This file is required at the last of +# "require 'tk'". +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib.rb new file mode 100644 index 0000000000..c6138f4275 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib.rb @@ -0,0 +1,90 @@ +# +# tcllib extension support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tcllib/setup.rb' + +err = '' + +# package:: autoscroll +target = 'tkextlib/tcllib/autoscroll' +begin + require target +rescue => e + err << "\n ['" << target << "'] " << e.class.name << ' : ' << e.message +end + +# package:: cursor +target = 'tkextlib/tcllib/cursor' +begin + require target +rescue => e + err << "\n ['" << target << "'] " << e.class.name << ' : ' << e.message +end + +# package:: style +target = 'tkextlib/tcllib/style' +begin + require target +rescue => e + err << "\n ['" << target << "'] " << e.class.name << ' : ' << e.message +end + +# autoload +module Tk + module Tcllib + TkComm::TkExtlibAutoloadModule.unshift(self) + + # package:: ctext + autoload :CText, 'tkextlib/tcllib/ctext' + + # package:: getstring + autoload :GetString_Dialog, 'tkextlib/tcllib/getstring' + + # package:: history + autoload :History, 'tkextlib/tcllib/history' + + # package:: datefield + autoload :Datefield, 'tkextlib/tcllib/datefield' + autoload :DateField, 'tkextlib/tcllib/datefield' + + # package:: ico + autoload :ICO, 'tkextlib/tcllib/ico' + + # package:: ipentry + autoload :IP_Entry, 'tkextlib/tcllib/ip_entry' + autoload :IPEntry, 'tkextlib/tcllib/ip_entry' + + # package:: swaplist + autoload :Swaplist_Dialog, 'tkextlib/tcllib/swaplist' + + # package:: Plotchart + autoload :Plotchart, 'tkextlib/tcllib/plotchart' + + # package:: tablelist + autoload :Tablelist, 'tkextlib/tcllib/tablelist' + autoload :TableList, 'tkextlib/tcllib/tablelist' + autoload :Tablelist_Tile, 'tkextlib/tcllib/tablelist_tile' + autoload :TableList_Tile, 'tkextlib/tcllib/tablelist_tile' + + # package:: tkpiechart + autoload :Tkpiechart, 'tkextlib/tcllib/tkpiechart' + + # package:: tooltip + autoload :Tooltip, 'tkextlib/tcllib/tooltip' + + # package:: widget + autoload :Wdiget, 'tkextlib/tcllib/widget' + end +end + +if $VERBOSE && !err.empty? + warn("Warning: some sub-packages are failed to require : " + err) +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/README b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/README new file mode 100644 index 0000000000..953239befa --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/README @@ -0,0 +1,135 @@ + + [ tcllib extension support files ] + +Tcllib includes many utilities. But currently, supports TKLib part +only (see the following 'tcllib contents'). + +If you request to support others, please send your message to one of +ruby-talk/ruby-list/ruby-dev/ruby-ext mailing lists. + +-----<from "What is tcllib?">---------------------------- +Tcllib is a collection of utility modules for Tcl. These modules provide +a wide variety of functionality, from implementations of standard data +structures to implementations of common networking protocols. The intent +is to collect commonly used function into a single library, which users +can rely on to be available and stable. +--------------------------------------------------------- + +-----< tcllib contents (based on tcllib-1.6.1) >--------- +Programming tools + * cmdline - Procedures to process command lines and options. + * comm - A remote communications facility for Tcl (7.6, 8.0, and later) + * control - Procedures for control flow structures. + * fileutil - Procedures implementing some file utilities + * log - Procedures to log messages of libraries and applications. + * logger - System to control logging of events. + * multiplexer - One-to-many communication with sockets. + * snit - Snit's Not Incr Tcl + * snitfaq - Snit Frequently Asked Questions + * stooop - Object oriented extension. + * stoop - Simple Tcl Only Object Oriented Programming + * switched - stooop switched class + * profiler - Tcl source code profiler + +Mathematics + * math::statistics - Basic statistical functions and procedures + * math::calculus - Integration and ordinary differential equations + * math::optimize - Optimisation routines + * math::fuzzy - Fuzzy comparison of floating-point numbers + * counter - Procedures for counters and histograms + * combinatorics - Combinatorial functions in the Tcl Math Library + +Data structures + * struct::list - Procedures for manipulating lists + * struct::set - Procedures for manipulating sets + * struct::stack - Create and manipulate stack objects + * struct::queue - Create and manipulate queue objects + * struct::prioqueue - Create and manipulate prioqueue objects + * struct::skiplist - Create and manipulate skiplists + * struct::tree - Create and manipulate tree objects + * struct::graph - Create and manipulate directed graph objects + * struct::record - Define and create records (similar to 'C' structures) + * struct::matrix - Create and manipulate matrix objects + * struct::pool - Create and manipulate pool objects (of discrete items) + * report - Create and manipulate report objects + +Text processing + * expander - Procedures to process templates and expand text. + * base64 - Procedures to encode and decode base64 + * yencode - encode/decoding a binary file + * uuencode - encode/decoding a binary file + * csv - Procedures to handle CSV data. + * inifile - Parsing of Windows INI files + * htmlparse - Procedures to parse HTML strings + * mime - Manipulation of MIME body parts + * Tcl MIME - generates and parses MIME body parts + * textutil - Procedures to manipulate texts and strings. + * exif - Tcl EXIF extracts and parses EXIF fields from digital images + * EXIF - extract and parse EXIF fields from digital images + +Hashes, checksums, and encryption + * cksum - calculate a cksum(1) compatible checksum + * crc16 - Perform a 16bit Cyclic Redundancy Check + * crc32 - Perform a 32bit Cyclic Redundancy Check + * des - Perform DES encryption of Tcl data + * md4 - MD4 Message-Digest Algorithm + * md5 - MD5 Message-Digest Algorithm + * ripemd160 - RIPEMD-160 Message-Digest Algorithm + * ripemd128 - RIPEMD-128 Message-Digest Algorithm + * md5crypt - MD5-based password encryption + * sha1 - Perform sha1 hashing + * sum - calculate a sum(1) compatible checksum + * soundex - Soundex + +Documentation tools + * mpexpand - Markup processor + * doctools - Create and manipulate doctools converter object + * doctoc_fmt - Specification of simple tcl markup for table of contents + * doctools_api - Interface specification for formatter code + * doctools_fmt - Specification of simple tcl markup for manpages + * docidx - Create and manipulate docidx converter objects + * docidx_api - Interface specification for index formatting code + * docidx_fmt - Specification of simple tcl markup for an index + * doctoc - Create and manipulate doctoc converter objects + * doctoc_api - Interface specification for toc formatting code + * doctools::changelog - Handle text in Emacs ChangeLog format + * doctools::cvs - Handle text in 'cvs log' format + +Networking + * uri - URI utilities + * dns - Tcl Domain Name Service Client + * ntp_time - Tcl Time Service Client + * nntp - Tcl client for the NNTP protocol + * pop3 - Tcl client for POP3 email protocol + * pop3d - Tcl POP3 server implementation + * pop3d::udb - Simple user database for pop3d + * pop3d::dbox - Simple mailbox database for pop3d + * ftp - Client-side tcl implementation of the ftp protocol + * ftp - Client-side tcl implementation of the ftp protocol + * ftpd - Tcl FTP server implementation + * smtp - Client-side tcl implementation of the smtp protocol + * smtpd - Tcl SMTP server implementation + * irc - Create IRC connection and interface. + +CGI programming + * ncgi - Procedures to manipulate CGI values. + * html - Procedures to generate HTML structures + * javascript - Procedures to generate HTML and Java Script structures. + +Grammars and finite automata + * grammar::fa - Create and manipulate finite automatons + * grammar::fa::op - Operations on finite automatons + * grammar::dacceptor - Create and use deterministic acceptors + * grammar::dexec - Execute deterministic finite automatons + +TKLib + * Plotchart - Simple plotting and charting package + * autoscroll - Provides for a scrollbar to automatically mapped and + unmapped as needed + * ctext - An extended text widget with customizable Syntax highlighting + * cursor - Procedures to handle CURSOR data + * datefield - Tk datefield widget + * style - Changes default Tk look&feel + * ipentry - An IP address entry widget + * tkpiechart - Creates and dynamically updates 2D or 3D pie charts +--------------------------------------------------------- diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/autoscroll.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/autoscroll.rb new file mode 100644 index 0000000000..6940a9174c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/autoscroll.rb @@ -0,0 +1,158 @@ +# +# tkextlib/tcllib/autoscroll.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Provides for a scrollbar to automatically mapped and unmapped as needed +# +# (The following is the original description of the library.) +# +# This package allows scrollbars to be mapped and unmapped as needed +# depending on the size and content of the scrollbars scrolled widget. +# The scrollbar must be managed by either pack or grid, other geometry +# managers are not supported. +# +# When managed by pack, any geometry changes made in the scrollbars parent +# between the time a scrollbar is unmapped, and when it is mapped will be +# lost. It is an error to destroy any of the scrollbars siblings while the +# scrollbar is unmapped. When managed by grid, if anything becomes gridded +# in the same row and column the scrollbar occupied it will be replaced by +# the scrollbar when remapped. +# +# This package may be used on any scrollbar-like widget as long as it +# supports the set subcommand in the same style as scrollbar. If the set +# subcommand is not used then this package will have no effect. +# + +require 'tk' +require 'tk/scrollbar' +require 'tkextlib/tcllib.rb' + +module Tk + module Tcllib + module Autoscroll + PACKAGE_NAME = 'autoscroll'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('autoscroll') + rescue + '' + end + end + + def self.not_available + fail RuntimeError, "'tkextlib/tcllib/autoscroll' extension is not available on your current environment." + end + + def self.autoscroll(win) + Tk::Tcllib::Autoscroll.not_available + end + + def self.unautoscroll(win) + Tk::Tcllib::Autoscroll.not_available + end + end + end +end + +module Tk + module Scrollable + def autoscroll(mode = nil) + case mode + when :x, 'x' + if @xscrollbar + Tk::Tcllib::Autoscroll.autoscroll(@xscrollbar) + end + when :y, 'y' + if @yscrollbar + Tk::Tcllib::Autoscroll.autoscroll(@yscrollbar) + end + when nil, :both, 'both' + if @xscrollbar + Tk::Tcllib::Autoscroll.autoscroll(@xscrollbar) + end + if @yscrollbar + Tk::Tcllib::Autoscroll.autoscroll(@yscrollbar) + end + else + fail ArgumentError, "'x', 'y' or 'both' (String or Symbol) is expected" + end + self + end + def unautoscroll(mode = nil) + case mode + when :x, 'x' + if @xscrollbar + Tk::Tcllib::Autoscroll.unautoscroll(@xscrollbar) + end + when :y, 'y' + if @yscrollbar + Tk::Tcllib::Autoscroll.unautoscroll(@yscrollbar) + end + when nil, :both, 'both' + if @xscrollbar + Tk::Tcllib::Autoscroll.unautoscroll(@xscrollbar) + end + if @yscrollbar + Tk::Tcllib::Autoscroll.unautoscroll(@yscrollbar) + end + else + fail ArgumentError, "'x', 'y' or 'both' (String or Symbol) is expected" + end + self + end + end +end + +class TkScrollbar + def autoscroll + # Arranges for the already existing scrollbar to be mapped + # and unmapped as needed. + #tk_call_without_enc('::autoscroll::autoscroll', @path) + Tk::Tcllib::Autoscroll.autoscroll(self) + self + end + def unautoscroll + # Returns the scrollbar to its original static state. + #tk_call_without_enc('::autoscroll::unautoscroll', @path) + Tk::Tcllib::Autoscroll.unautoscroll(self) + self + end +end + +# TkPackage.require('autoscroll', '1.0') +# TkPackage.require('autoscroll', '1.1') +TkPackage.require('autoscroll') + +module Tk + module Tcllib + class << Autoscroll + undef not_available + end + + module Autoscroll + extend TkCore + def self.autoscroll(win) + tk_call_without_enc('::autoscroll::autoscroll', win.path) + end + + def self.unautoscroll(win) + tk_call_without_enc('::autoscroll::unautoscroll', win.path) + end + + def self.wrap + # v1.1 + tk_call_without_enc('::autoscroll::wrap') + end + + def self.unwrap + # v1.1 + tk_call_without_enc('::autoscroll::unwrap') + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ctext.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ctext.rb new file mode 100644 index 0000000000..70a45dd8e7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ctext.rb @@ -0,0 +1,160 @@ +# +# tkextlib/tcllib/ctext.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Overloads the text widget and provides new commands +# + +require 'tk' +require 'tk/text' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('ctext', '3.1') +TkPackage.require('ctext') + +module Tk + module Tcllib + class CText < TkText + PACKAGE_NAME = 'ctext'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('ctext') + rescue + '' + end + end + end + end +end + +class Tk::Tcllib::CText + TkCommandNames = ['ctext'.freeze].freeze + WidgetClassName = 'Ctext'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __strval_optkeys + super() << 'linemapfg' << 'linemapbg' << + 'linemap_select_fg' << 'linemap_select_bg' + end + private :__strval_optkeys + + def __boolval_optkeys + super() << 'highlight' << 'linemap_markable' + end + private :__boolval_optkeys + + def append(*args) + tk_send('append', *args) + end + + def copy + tk_send('copy') + end + + def cut + tk_send('cut') + end + + def fast_delete(*args) + tk_send('fastdelete', *args) + end + + def fast_insert(*args) + tk_send('fastinsert', *args) + end + + def highlight(*args) + tk_send('highlight', *args) + end + + def paste + tk_send('paste') + end + + def edit(*args) + tk_send('edit', *args) + end + + def add_highlight_class(klass, col, *keywords) + tk_call('ctext::addHighlightClass', @path, klass, col, keywords.flatten) + self + end + + def add_highlight_class_for_special_chars(klass, col, *chrs) + tk_call('ctext::addHighlightClassForSpecialChars', + @path, klass, col, chrs.join('')) + self + end + + def add_highlight_class_for_regexp(klass, col, tcl_regexp) + tk_call('ctext::addHighlightClassForRegexp', + @path, klass, col, tcl_regexp) + self + end + + def add_highlight_class_with_only_char_start(klass, col, chr) + tk_call('ctext::addHighlightClassWithOnlyCharStart', + @path, klass, col, chr) + self + end + + def clear_highlight_classes + tk_call('ctext::clearHighlightClasses', @path) + self + end + + def get_highlight_classes + tk_split_simplelist(tk_call('ctext::getHighlightClasses', @path)) + end + + def delete_highlight_class(klass) + tk_call('ctext::deleteHighlightClass', @path, klass) + self + end + + def enable_C_comments + tk_call('ctext::enableComments', @path) + self + end + + def disable_C_comments + tk_call('ctext::disableComments', @path) + self + end + + def find_next_char(idx, chr) + tk_call('ctext::findNextChar', @path, idx, chr) + end + + def find_next_space(idx) + tk_call('ctext::findNextSpace', @path, idx) + end + + def find_previous_space(idx) + tk_call('ctext::findPreviousSpace', @path, idx) + end + + def set_update_proc(cmd=Proc.new) + tk_call('proc', 'ctext::update', '', cmd) + self + end + + def modified?(mode) + bool(tk_call('ctext::modified', @path, mode)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/cursor.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/cursor.rb new file mode 100644 index 0000000000..9bb828e8dd --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/cursor.rb @@ -0,0 +1,97 @@ +# +# tkextlib/tcllib/cursor.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Procedures to handle CURSOR data +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +module Tk + module Tcllib + module Cursor + PACKAGE_NAME = 'cursor'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('cursor') + rescue + '' + end + end + + def self.not_available + fail RuntimeError, "'tkextlib/tcllib/cursor' extension is not available on your current environment." + end + + def self.cursor_display(win=None) + Tk::Tcllib::Cursor.not_available + end + + def self.cursor_propagate(win, cursor) + Tk::Tcllib::Cursor.not_available + end + + def self.cursor_restore(win, cursor = None) + Tk::Tcllib::Cursor.not_available + end + end + end + + def self.cursor_display(parent=None) + # Pops up a dialog with a listbox containing all the cursor names. + # Selecting a cursor name will display it in that dialog. + # This is simply for viewing any available cursors on the platform . + #tk_call_without_enc('::cursor::display', parent) + Tk::Tcllib::Cursor.cursor_display(parent) + end +end + +class TkWindow + def cursor_propagate(cursor) + # Sets the cursor for self and all its descendants to cursor. + #tk_call_without_enc('::cursor::propagate', @path, cursor) + Tk::Tcllib::Cursor.cursor_propagate(self, cursor) + end + def cursor_restore(cursor = None) + # Restore the original or previously set cursor for self and all its + # descendants. If cursor is specified, that will be used if on any + # widget that did not have a preset cursor (set by a previous call + # to TkWindow#cursor_propagate). + #tk_call_without_enc('::cursor::restore', @path, cursor) + Tk::Tcllib::Cursor.cursor_restore(self, cursor) + end +end + +# TkPackage.require('cursor', '0.1') +TkPackage.require('cursor') + +module Tk + module Tcllib + class << Cursor + undef not_available + end + + module Cursor + extend TkCore + def self.cursor_display(win=None) + tk_call_without_enc('::cursor::display', _epath(win)) + end + + def self.cursor_propagate(win, cursor) + #tk_call_without_enc('::cursor::propagate', win.path, cursor) + tk_call_without_enc('::cursor::propagate', _epath(win), cursor) + end + + def self.cursor_restore(win, cursor = None) + #tk_call_without_enc('::cursor::restore', win.path, cursor) + tk_call_without_enc('::cursor::restore', _epath(win), cursor) + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/datefield.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/datefield.rb new file mode 100644 index 0000000000..bd84488101 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/datefield.rb @@ -0,0 +1,57 @@ +# +# tkextlib/tcllib/datefield.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Tk datefield widget +# +# (The following is the original description of the library.) +# +# The datefield package provides the datefield widget which is an enhanced +# text entry widget for the purpose of date entry. Only valid dates of the +# form MM/DD/YYYY can be entered. +# +# The datefield widget is, in fact, just an entry widget with specialized +# bindings. This means all the command and options for an entry widget apply +# equally here. + +require 'tk' +require 'tk/entry' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('datefield', '0.1') +TkPackage.require('datefield') + +module Tk + module Tcllib + class Datefield < TkEntry + PACKAGE_NAME = 'datefield'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('datefield') + rescue + '' + end + end + end + DateField = Datefield + end +end + +class Tk::Tcllib::Datefield + TkCommandNames = ['::datefield::datefield'.freeze].freeze + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/dialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/dialog.rb new file mode 100644 index 0000000000..825621b5a1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/dialog.rb @@ -0,0 +1,84 @@ +# +# tkextlib/tcllib/dialog.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Generic dialog widget (themed) +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget::dialog', '1.2') +TkPackage.require('widget::dialog') + +module Tk::Tcllib + module Widget + class Dialog < TkWindow + PACKAGE_NAME = 'widget::dialog'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget::dialog') + rescue + '' + end + end + end + end +end + +class Tk::Tcllib::Widget::Dialog + TkCommandNames = ['::widget::dialog'.freeze].freeze + + def __boolval_optkeys + ['separator', 'synchronous', 'transient'] + end + private :__boolval_optkeys + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def add(what, *args) + window(tk_send('add', *args)) + end + + def get_frame + window(tk_send('getframe')) + end + + def set_widget(widget) + tk_send('setwidget', widget) + self + end + + def display + tk_send('display') + self + end + alias show display + + def cancel + tk_send('cancel') + self + end + + def close(reason = None) + tk_send('close', reason) + end + + def withdraw + tk_send('withdraw') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/getstring.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/getstring.rb new file mode 100644 index 0000000000..bf5e54e8cf --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/getstring.rb @@ -0,0 +1,131 @@ +# +# tkextlib/tcllib/getstring.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * A dialog which consists of an Entry, OK, and Cancel buttons. +# + +require 'tk' +require 'tk/entry' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('getstring', '0.1') +TkPackage.require('getstring') + +module Tk::Tcllib + class GetString_Dialog < TkWindow + PACKAGE_NAME = 'getstring'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('getstring') + rescue + '' + end + end + end +end + + +class Tk::Tcllib::GetString_Dialog + TkCommandNames = ['::getstring::tk_getString'.freeze].freeze + WidgetClassName = 'TkSDialog'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.show(*args) + dialog = self.new(*args) + dialog.show + [dialog.status, dialog.value] + end + def self.display(*args) + self.show(*args) + end + + def initialize(*args) # args = (parent=nil, text='', keys=nil) + keys = args.pop + if keys.kind_of?(Hash) + text = args.pop + @keys = _symbolkey2str(keys) + args.push(keys) + else + text = keys + @keys = {} + end + if text + @text = text.dup + else + @text = '' + end + + @variable = TkVariable.new + @status = nil + + super(*args) + end + + def create_self(keys) + # dummy + end + private :create_self + + def show + @variable.value = '' + @status = bool(tk_call(self.class::TkCommandNames[0], + @path, @variable, @text, *hash_kv(@keys))) + end + alias display show + + def status + @status + end + + def value + @variable.value + end + + def cget(slot) + slot = slot.to_s + if slot == 'text' + @text + else + @keys[slot] + end + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot.each{|k, v| configure(k, v)} + else + slot = slot.to_s + value = _symbolkey2str(value) if value.kind_of?(Hash) + if value && value != None + if slot == 'text' + @text = value.to_s + else + @keys[slot] = value + end + else + if slot == 'text' + @text = '' + else + @keys.delete(slot) + end + end + end + self + end + + def configinfo(slot = nil) + if slot + slot = slot.to_s + [ slot, nil, nil, nil, ( (slot == 'text')? @text: @keys[slot] ) ] + else + @keys.collect{|k, v| [ k, nil, nil, nil, v ] } \ + << [ 'text', nil, nil, nil, @text ] + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/history.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/history.rb new file mode 100644 index 0000000000..a01a4ebfcc --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/history.rb @@ -0,0 +1,73 @@ +# +# tkextlib/tcllib/history.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Provides a history for Entry widgets +# + +require 'tk' +require 'tk/entry' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('history', '0.1') +TkPackage.require('history') + +module Tk::Tcllib + module History + PACKAGE_NAME = 'history'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('history') + rescue + '' + end + end + end +end + +module Tk::Tcllib::History + extend TkCore + + def self.init(entry, length=None) + tk_call_without_enc('::history::init', entry.path, length) + entry.extend(self) # add methods to treat history to the entry widget + end + + def self.remove(entry) + tk_call_without_enc('::history::remove', entry.path) + entry + end + + def history_remove + tk_call_without_enc('::history::remove', @path) + self + end + + def history_add(text) + tk_call('::history::add', @path, text) + self + end + + def history_get + simplelist(tk_call_without_enc('::history::get', @path)) + end + + def history_clear + tk_call_without_enc('::history::clear', @path) + self + end + + def history_configure(opt, value) + tk_call('::history::configure', @path, opt, value) + self + end + + def history_configinfo(opt) + tk_call('::history::configure', @path, opt) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ico.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ico.rb new file mode 100644 index 0000000000..3beeb11a4d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ico.rb @@ -0,0 +1,114 @@ +# +# tkextlib/tcllib/ico.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Reading and writing windows icons +# + +require 'tk' +require 'tk/image' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('ico', '0.3') +TkPackage.require('ico') + +module Tk + module Tcllib + class ICO < TkImage + PACKAGE_NAME = 'ico'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('ico') + rescue + '' + end + end + end + end +end + +class Tk::Tcllib::ICO + def self.list(file, keys=nil) + tk_split_list(tk_call_without_enc('::ico::getIconList', file, + *hash_kv(keys, true))) + end + + def self.get(file, index, keys=nil) + tk_call_without_enc('::ico::getIcon', file, index, *hash_kv(keys, true)) + end + + def self.get_image(file, index, keys={}) + keys = _symbolkey2str(keys) + keys.delete('format') + self.new(file, index, keys) + end + + def self.get_data(file, index, keys={}) + keys['format'] = 'data' + tk_split_list(tk_call_without_enc('::ico::getIcon', file, index, + *hash_kv(keys, true))) + end + + def self.write(file, index, depth, data, keys=nil) + tk_call_without_enc('::ico::writeIcon', file, index, depth, data, + *hash_kv(keys, true)) + end + + def self.copy(from_file, from_index, to_file, to_index, keys=nil) + tk_call_without_enc('::ico::copyIcon', + from_file, from_index, to_file, to_index, + *hash_kv(keys, true)) + end + + def self.exe_to_ico(exe_file, ico_file, keys=nil) + tk_call_without_enc('::ico::copyIcon', exe_file, ico_file, + *hash_kv(keys, true)) + end + + def self.clear_cache(file=None) + tk_call_without_enc('::ico::clearCache', file) + end + + def self.transparent_color(image, color) + if image.kind_of?(Array) + tk_split_list(tk_call_without_enc('::ico::transparentColor', + image, color)) + else + tk_call_without_enc('::ico::transparentColor', image, color) + end + end + + def self.show(file, keys=nil) + tk_call_without_enc('::ico::Show', file, *hash_kv(keys, true)) + end + + ########################### + + def initialize(file, index, keys=nil) + keys = _symbolkey2str(keys) + if keys.key?('name') + @path = keys['name'].to_s + else + @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_) + Tk_Image_ID[1].succ! + end + tk_call_without_enc('::ico::getIcon', file, index, '-name', @path, + '-format', 'image', *hash_kv(keys, true)) + Tk_IMGTBL[@path] = self + end + + def write(file, index, depth, keys=nil) + Tk::Tcllib::ICO.write(file, index, depth, @path, keys=nil) + self + end + + def transparent_color(color) + tk_call_without_enc('::ico::transparentColor', @path, color) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ip_entry.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ip_entry.rb new file mode 100644 index 0000000000..8c9e0bd683 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ip_entry.rb @@ -0,0 +1,66 @@ +# +# tkextlib/tcllib/ip_entry.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * An IP address entry widget +# +# (The following is the original description of the library.) +# +# This package provides a widget for the entering of a IP address. +# It guarantees a valid address at all times. + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('ipentry', '0.1') +TkPackage.require('ipentry') + +module Tk + module Tcllib + class IP_Entry < TkEntry + PACKAGE_NAME = 'ipentry'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('ipentry') + rescue + '' + end + end + end + IPEntry = IP_Entry + end +end + +class Tk::Tcllib::IP_Entry + TkCommandNames = ['::ipentry::ipentry'.freeze].freeze + WidgetClassName = 'IPEntry'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __strval_optkeys + super() << 'fg' << 'bg' << 'insertbackground' + end + private :__strval_optkeys + + def complete? + bool(tk_send_without_enc('complete')) + end + + def insert(*ip) + tk_send_without_enc('insert', array2tk_list(ip.flatten)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/panelframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/panelframe.rb new file mode 100644 index 0000000000..2a4562e779 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/panelframe.rb @@ -0,0 +1,72 @@ +# +# tkextlib/tcllib/panelframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Create PanelFrame widgets. +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget::panelframe', '1.0') +TkPackage.require('widget::panelframe') + +module Tk::Tcllib + module Widget + class PanelFrame < TkWindow + PACKAGE_NAME = 'widget::panelframe'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget::panelframe') + rescue + '' + end + end + end + Panelframe = PanelFrame + end +end + +class Tk::Tcllib::Widget::PanelFrame + TkCommandNames = ['::widget::panelframe'.freeze].freeze + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def add(what, *args) + window(tk_send('add', *args)) + end + + #def get_frame + # window(tk_send('getframe')) + #end + + def set_widget(widget) + tk_send('setwidget', widget) + self + end + + def remove(*wins) + tk_send('remove', *wins) + end + def remove_destroy(*wins) + tk_send('remove', '-destroy', *wins) + end + alias delete remove_destroy + + def items + simplelist(tk_send('items')).collect!{|w| window(w)} + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/plotchart.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/plotchart.rb new file mode 100644 index 0000000000..f5f344ceb3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/plotchart.rb @@ -0,0 +1,865 @@ +# +# tkextlib/tcllib/plotchart.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Simple plotting and charting package +# +# (The following is the original description of the library.) +# +# Plotchart is a Tcl-only package that focuses on the easy creation of +# xy-plots, barcharts and other common types of graphical presentations. +# The emphasis is on ease of use, rather than flexibility. The procedures +# that create a plot use the entire canvas window, making the layout of the +# plot completely automatic. +# +# This results in the creation of an xy-plot in, say, ten lines of code: +# -------------------------------------------------------------------- +# package require Plotchart +# +# canvas .c -background white -width 400 -height 200 +# pack .c -fill both +# +# # +# # Create the plot with its x- and y-axes +# # +# set s [::Plotchart::createXYPlot .c {0.0 100.0 10.0} {0.0 100.0 20.0}] +# +# foreach {x y} {0.0 32.0 10.0 50.0 25.0 60.0 78.0 11.0 } { +# $s plot series1 $x $y +# } +# +# $s title "Data series" +# -------------------------------------------------------------------- +# +# A drawback of the package might be that it does not do any data management. +# So if the canvas that holds the plot is to be resized, the whole plot must +# be redrawn. The advantage, though, is that it offers a number of plot and +# chart types: +# +# * XY-plots like the one shown above with any number of data series. +# * Stripcharts, a kind of XY-plots where the horizontal axis is adjusted +# automatically. The result is a kind of sliding window on the data +# series. +# * Polar plots, where the coordinates are polar instead of cartesian. +# * Isometric plots, where the scale of the coordinates in the two +# directions is always the same, i.e. a circle in world coordinates +# appears as a circle on the screen. +# You can zoom in and out, as well as pan with these plots (Note: this +# works best if no axes are drawn, the zooming and panning routines do +# not distinguish the axes), using the mouse buttons with the control +# key and the arrow keys with the control key. +# * Piecharts, with automatic scaling to indicate the proportions. +# * Barcharts, with either vertical or horizontal bars, stacked bars or +# bars side by side. +# * Timecharts, where bars indicate a time period and milestones or other +# important moments in time are represented by triangles. +# * 3D plots (both for displaying surfaces and 3D bars) +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('Plotchart', '0.9') +# TkPackage.require('Plotchart', '1.1') +TkPackage.require('Plotchart') + +module Tk + module Tcllib + module Plotchart + PACKAGE_NAME = 'Plotchart'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Plotchart') + rescue + '' + end + end + end + end +end + +module Tk::Tcllib::Plotchart + extend TkCore + ############################ + def self.view_port(w, *args) # args := pxmin, pymin, pxmax, pymax + tk_call_without_enc('::Plotchart::viewPort', w.path, *(args.flatten)) + end + + def self.world_coordinates(w, *args) # args := xmin, ymin, xmax, ymax + tk_call_without_enc('::Plotchart::worldCoordinates', + w.path, *(args.flatten)) + end + + def self.world_3D_coordinates(w, *args) + # args := xmin, ymin, zmin, xmax, ymax, zmax + tk_call_without_enc('::Plotchart::world3DCoordinates', + w.path, *(args.flatten)) + end + + def self.coords_to_pixel(w, x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', w.path, x, y)) + end + + def self.coords_3D_to_pixel(w, x, y, z) + list(tk_call_without_enc('::Plotchart::coords3DToPixel', w.path, x, y, z)) + end + + def self.polar_coordinates(w, radmax) + tk_call_without_enc('::Plotchart::polarCoordinates', w.path, radmax) + end + + def self.polar_to_pixel(w, rad, phi) + list(tk_call_without_enc('::Plotchart::polarToPixel', w.path, rad, phi)) + end + + def self.pixel_to_coords(w, x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', w.path, x, y)) + end + + def self.determine_scale(w, xmax, ymax) + tk_call_without_enc('::Plotchart::determineScale', w.path, xmax, ymax) + end + + def self.set_zoom_pan(w) + tk_call_without_enc('::Plotchart::setZoomPan', w.path) + end + + ############################ + module ChartMethod + include TkCore + + def title(str) + tk_call_without_enc(@chart, 'title', _get_eval_enc_str(str)) + self + end + + def save_plot(filename) + tk_call_without_enc(@chart, 'saveplot', filename) + self + end + + def xtext(str) + tk_call_without_enc(@chart, 'xtext', _get_eval_enc_str(str)) + self + end + + def ytext(str) + tk_call_without_enc(@chart, 'ytext', _get_eval_enc_str(str)) + self + end + + def xconfig(key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'xconfig', *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'xconfig', + "-#{key}", _get_eval_enc_str(value)) + end + self + end + + def yconfig(key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'yconfig', *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'yconfig', + "-#{key}", _get_eval_enc_str(value)) + end + self + end + + ############################ + def view_port(*args) # args := pxmin, pymin, pxmax, pymax + tk_call_without_enc('::Plotchart::viewPort', @path, *(args.flatten)) + self + end + + def world_coordinates(*args) # args := xmin, ymin, xmax, ymax + tk_call_without_enc('::Plotchart::worldCoordinates', + @path, *(args.flatten)) + self + end + + def world_3D_coordinates(*args) + # args := xmin, ymin, zmin, xmax, ymax, zmax + tk_call_without_enc('::Plotchart::world3DCoordinates', + @path, *(args.flatten)) + self + end + + def coords_to_pixel(x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', @path, x, y)) + end + + def coords_3D_to_pixel(x, y, z) + list(tk_call_without_enc('::Plotchart::coords3DToPixel', @path, x, y, z)) + end + + def polar_coordinates(radmax) + tk_call_without_enc('::Plotchart::polarCoordinates', @path, radmax) + self + end + + def polar_to_pixel(rad, phi) + list(tk_call_without_enc('::Plotchart::polarToPixel', @path, rad, phi)) + end + + def pixel_to_coords(x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', @path, x, y)) + end + + def determine_scale(xmax, ymax) + tk_call_without_enc('::Plotchart::determineScale', @path, xmax, ymax) + self + end + + def set_zoom_pan() + tk_call_without_enc('::Plotchart::setZoomPan', @path) + self + end + end + + ############################ + class XYPlot < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createXYPlot'.freeze + ].freeze + + def initialize(*args) # args := ([parent,] xaxis, yaxis [, keys]) + # xaxis := Array of [minimum, maximum, stepsize] + # yaxis := Array of [minimum, maximum, stepsize] + if args[0].kind_of?(Array) + @xaxis = args.shift + @yaxis = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @xaxis = args.shift + @yaxis = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + array2tk_list(@xaxis), array2tk_list(@yaxis)) + end + private :_create_chart + + def __destroy_hook__ + Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path) + end + + def plot(series, x, y) + tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(series), x, y) + self + end + + def contourlines(xcrd, ycrd, vals, clss=None) + xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array) + ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array) + vals = array2tk_list(vals) if vals.kind_of?(Array) + clss = array2tk_list(clss) if clss.kind_of?(Array) + + tk_call_without_enc(@chart, 'contourlines', xcrd, ycrd, vals, clss) + self + end + + def contourfill(xcrd, ycrd, vals, klasses=None) + xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array) + ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array) + vals = array2tk_list(vals) if vals.kind_of?(Array) + clss = array2tk_list(clss) if clss.kind_of?(Array) + + tk_call_without_enc(@chart, 'contourfill', xcrd, ycrd, vals, clss) + self + end + + def contourbox(xcrd, ycrd, vals, klasses=None) + xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array) + ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array) + vals = array2tk_list(vals) if vals.kind_of?(Array) + clss = array2tk_list(clss) if clss.kind_of?(Array) + + tk_call_without_enc(@chart, 'contourbox', xcrd, ycrd, vals, clss) + self + end + + def color_map(colors) + colors = array2tk_list(colors) if colors.kind_of?(Array) + + tk_call_without_enc(@chart, 'colorMap', colors) + self + end + + def grid_cells(xcrd, ycrd) + xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array) + ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array) + + tk_call_without_enc(@chart, 'grid', xcrd, ycrd) + self + end + + def dataconfig(series, key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'dataconfig', series, + "-#{key}", _get_eval_enc_str(value)) + end + end + end + + ############################ + class Stripchart < XYPlot + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createStripchart'.freeze + ].freeze + end + + ############################ + class PolarPlot < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createPolarplot'.freeze + ].freeze + + def initialize(*args) # args := ([parent,] radius_data [, keys]) + # radius_data := Array of [maximum_radius, stepsize] + if args[0].kind_of?(Array) + @radius_data = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @radius_data = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + array2tk_list(@radius_data)) + end + private :_create_chart + + def __destroy_hook__ + Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path) + end + + def plot(series, radius, angle) + tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(series), + radius, angle) + self + end + + def dataconfig(series, key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'dataconfig', series, + "-#{key}", _get_eval_enc_str(value)) + end + end + end + Polarplot = PolarPlot + + ############################ + class IsometricPlot < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createIsometricPlot'.freeze + ].freeze + + def initialize(*args) # args := ([parent,] xaxis, yaxis, [, step] [, keys]) + # xaxis := Array of [minimum, maximum] + # yaxis := Array of [minimum, maximum] + # step := Float of stepsize | "noaxes" | :noaxes + if args[0].kind_of?(Array) + @xaxis = args.shift + @yaxis = args.shift + + if args[0].kind_of?(Hash) + @stepsize = :noaxes + else + @stepsize = args.shift + end + + super(*args) # create canvas widget + else + parent = args.shift + + @xaxis = args.shift + @yaxis = args.shift + + if args[0].kind_of?(Hash) + @stepsize = :noaxes + else + @stepsize = args.shift + end + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + array2tk_list(@xaxis), array2tk_list(@yaxis), + @stepsize) + end + private :_create_chart + + def plot(type, *args) + self.__send__("plot_#{type.to_s.tr('-', '_')}", *args) + end + + def plot_rectangle(*args) # args := x1, y1, x2, y2, color + tk_call_without_enc(@chart, 'plot', 'rectangle', *(args.flatten)) + self + end + + def plot_filled_rectangle(*args) # args := x1, y1, x2, y2, color + tk_call_without_enc(@chart, 'plot', 'filled-rectangle', *(args.flatten)) + self + end + + def plot_circle(*args) # args := xc, yc, radius, color + tk_call_without_enc(@chart, 'plot', 'circle', *(args.flatten)) + self + end + + def plot_filled_circle(*args) # args := xc, yc, radius, color + tk_call_without_enc(@chart, 'plot', 'filled-circle', *(args.flatten)) + self + end + end + Isometricplot = IsometricPlot + + ############################ + class Plot3D < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::create3DPlot'.freeze + ].freeze + + def initialize(*args) # args := ([parent,] xaxis, yaxis, zaxis [, keys]) + # xaxis := Array of [minimum, maximum, stepsize] + # yaxis := Array of [minimum, maximum, stepsize] + # zaxis := Array of [minimum, maximum, stepsize] + if args[0].kind_of?(Array) + @xaxis = args.shift + @yaxis = args.shift + @zaxis = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @xaxis = args.shift + @yaxis = args.shift + @zaxis = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + array2tk_list(@xaxis), + array2tk_list(@yaxis), + array2tk_list(@zaxis)) + end + private :_create_chart + + def plot_function(cmd=Proc.new) + Tk.ip_eval("proc #{@path}_#{@chart} {x y} {#{install_cmd(cmd)} $x $y}") + tk_call_without_enc(@chart, 'plotfunc', "#{@path}_#{@chart}") + self + end + + def plot_funcont(conts, cmd=Proc.new) + conts = array2tk_list(conts) if conts.kind_of?(Array) + Tk.ip_eval("proc #{@path}_#{@chart} {x y} {#{install_cmd(cmd)} $x $y}") + tk_call_without_enc(@chart, 'plotfuncont', "#{@path}_#{@chart}", conts) + self + end + + def grid_size(nxcells, nycells) + tk_call_without_enc(@chart, 'gridsize', nxcells, nycells) + self + end + + def plot_data(dat) + # dat has to be provided as a 2 level array. + # 1st level contains rows, drawn in y-direction, + # and each row is an array whose elements are drawn in x-direction, + # for the columns. + tk_call_without_enc(@chart, 'plotdata', dat) + self + end + + def colour(fill, border) + # configure the colours to use for polygon borders and inner area + tk_call_without_enc(@chart, 'colour', fill, border) + self + end + alias colours colour + alias colors colour + alias color colour + end + + ############################ + class Piechart < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createPiechart'.freeze + ].freeze + + def initialize(*args) # args := ([parent] [, keys]) + if args[0].kind_of?(TkCanvas) + parent = args.shift + @path = parent.path + else + super(*args) # create canvas widget + end + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path) + end + private :_create_chart + + def plot(*dat) # argument is a list of [label, value] + tk_call_without_enc(@chart, 'plot', dat.flatten) + self + end + end + + ############################ + class Barchart < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createBarchart'.freeze + ].freeze + + def initialize(*args) + # args := ([parent,] xlabels, ylabels [, series] [, keys]) + # xlabels, ylabels := labels | axis ( depend on normal or horizontal ) + # labels := Array of [label, label, ...] + # (It determines the number of bars that will be plotted per series.) + # axis := Array of [minimum, maximum, stepsize] + # series := Integer number of data series | 'stacked' | :stacked + if args[0].kind_of?(Array) + @xlabels = args.shift + @ylabels = args.shift + + if args[0].kind_of?(Hash) + @series_size = :stacked + else + @series_size = args.shift + end + + super(*args) # create canvas widget + else + parent = args.shift + + @xlabels = args.shift + @ylabels = args.shift + + if args[0].kind_of?(Hash) + @series_size = :stacked + else + @series_size = args.shift + end + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + array2tk_list(@xlabels), array2tk_list(@ylabels), + @series_size) + end + private :_create_chart + + def __destroy_hook__ + Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path) + end + + def plot(series, dat, col=None) + tk_call_without_enc(@chart, 'plot', series, dat, col) + self + end + + def colours(*cols) + # set the colours to be used + tk_call_without_enc(@chart, 'colours', *cols) + self + end + alias colour colours + alias colors colours + alias color colours + end + + ############################ + class HorizontalBarchart < Barchart + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createHorizontalBarchart'.freeze + ].freeze + end + + ############################ + class Timechart < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createTimechart'.freeze + ].freeze + + def initialize(*args) + # args := ([parent,] time_begin, time_end, items [, keys]) + # time_begin := String of time format (e.g. "1 january 2004") + # time_end := String of time format (e.g. "1 january 2004") + # items := Expected/maximum number of items + # ( This determines the vertical spacing. ) + if args[0].kind_of?(String) + @time_begin = args.shift + @time_end = args.shift + @items = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @time_begin = args.shift + @time_end = args.shift + @items = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + @time_begin, @time_end, @items) + end + private :_create_chart + + def period(txt, time_begin, time_end, col=None) + tk_call_without_enc(@chart, 'period', txt, time_begin, time_end, col) + self + end + + def milestone(txt, time, col=None) + tk_call_without_enc(@chart, 'milestone', txt, time, col) + self + end + + def vertline(txt, time) + tk_call_without_enc(@chart, 'vertline', txt, time) + self + end + end + + ############################ + class Gnattchart < TkCanvas + include ChartMethod + + TkCommandNames = [ + 'canvas'.freeze, + '::Plotchart::createGnattchart'.freeze + ].freeze + + def initialize(*args) + # args := ([parent,] time_begin, time_end, items [, text_width] [, keys]) + # time_begin := String of time format (e.g. "1 january 2004") + # time_end := String of time format (e.g. "1 january 2004") + # items := Expected/maximum number of items + # ( This determines the vertical spacing. ) + if args[0].kind_of?(String) + @time_begin = args.shift + @time_end = args.shift + @items = args.shift + + if args[0].kind_of?(Fixnum) + @text_width = args.shift + else + @text_width = None + end + + super(*args) # create canvas widget + else + parent = args.shift + + @time_begin = args.shift + @time_end = args.shift + @items = args.shift + + if args[0].kind_of?(Fixnum) + @text_width = args.shift + else + @text_width = None + end + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[1] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[1], @path, + @time_begin, @time_end, @items, @text_width) + end + private :_create_chart + + def task(txt, time_begin, time_end, completed=0.0) + list(tk_call_without_enc(@chart, 'task', txt, time_begin, time_end, + completed)).collect!{|id| + TkcItem.id2obj(self, id) + } + end + + def milestone(txt, time, col=None) + tk_call_without_enc(@chart, 'milestone', txt, time, col) + self + end + + def vertline(txt, time) + tk_call_without_enc(@chart, 'vertline', txt, time) + self + end + + def connect(from_task, to_task) + from_task = array2tk_list(from_task) if from_task.kind_of?(Array) + to_task = array2tk_list(to_task) if to_task.kind_of?(Array) + + tk_call_without_enc(@chart, 'connect', from_task, to_task) + self + end + + def summary(txt, tasks) + tasks = array2tk_list(tasks) if tasks.kind_of?(Array) + tk_call_without_enc(@chart, 'summary', tasks) + self + end + + def color_of_part(keyword, newcolor) + tk_call_without_enc(@chart, 'color', keyword, newcolor) + self + end + + def font_of_part(keyword, newfont) + tk_call_without_enc(@chart, 'font', keyword, newfont) + self + end + end + + ############################ + class PlotSeries < TkObject + SeriesID_TBL = TkCore::INTERP.create_table + Series_ID = ['series'.freeze, '00000'.taint].freeze + TkCore::INTERP.init_ip_env{ SeriesID_TBL.clear } + + def self.id2obj(chart, id) + path = chart.path + return id unless SeriesID_TBL[path] + SeriesID_TBL[path][id]? SeriesID_TBL[path][id]: id + end + + def initialize(chart, keys=nil) + @parent = @chart_obj = chart + @ppath = @chart_obj.path + @path = @series = @id = Series_ID.join(TkCore::INTERP._ip_id_) + # SeriesID_TBL[@id] = self + SeriesID_TBL[@ppath] = {} unless SeriesID_TBL[@ppath] + SeriesID_TBL[@ppath][@id] = self + Series_ID[1].succ! + dataconfig(keys) if keys.kind_of?(Hash) + end + + def plot(*args) + @chart_obj.plot(@series, *args) + end + + def dataconfig(key, value=None) + @chart_obj.dataconfig(@series, key, value) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ruler.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ruler.rb new file mode 100644 index 0000000000..88ffb2c912 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/ruler.rb @@ -0,0 +1,65 @@ +# +# tkextlib/tcllib/ruler.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * ruler widget +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget::ruler', '1.0') +TkPackage.require('widget::ruler') + +module Tk::Tcllib + module Widget + class Ruler < TkWindow + PACKAGE_NAME = 'widget::ruler'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget::ruler') + rescue + '' + end + end + end + end +end + +class Tk::Tcllib::Widget::Ruler + TkCommandNames = ['::widget::ruler'.freeze].freeze + + def __boolval_optkeys + ['showvalues', 'outline', 'grid'] + end + private :__boolval_optkeys + + def __numlistval_optkeys + ['interval', 'sizes'] + end + private :__numlistval_optkeys + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def redraw + tk_send('redraw') + self + end + + def shade(org, dest, frac) + tk_send('shade', org, dest, frac) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/screenruler.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/screenruler.rb new file mode 100644 index 0000000000..1b4067e2f0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/screenruler.rb @@ -0,0 +1,68 @@ +# +# tkextlib/tcllib/screenruler.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * screenruler dialog +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget::screenruler', '1.1') +TkPackage.require('widget::screenruler') + +module Tk::Tcllib + module Widget + class ScreenRuler < TkWindow + PACKAGE_NAME = 'widget::ruler'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget::screenruler') + rescue + '' + end + end + end + Screenruler = ScreenRuler + end +end + +class Tk::Tcllib::Widget::ScreenRuler + TkCommandNames = ['::widget::screenruler'.freeze].freeze + + def __boolval_optkeys + ['topmost', 'reflect'] + end + private :__boolval_optkeys + + def __numlistval_optkeys + ['alpha'] + end + private :__numlistval_optkeys + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def display + tk_send('display') + self + end + alias show display + + def hide + tk_send('hide') + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/scrollwin.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/scrollwin.rb new file mode 100644 index 0000000000..717728e34a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/scrollwin.rb @@ -0,0 +1,61 @@ +# +# tkextlib/tcllib/scrollwin.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Scrolled widget +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget::scrolledwindow', '1.0') +TkPackage.require('widget::scrolledwindow') + +module Tk::Tcllib + module Widget + class ScrolledWindow < TkWindow + PACKAGE_NAME = 'widget::scrolledwindow'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget::scrolledwindow') + rescue + '' + end + end + end + Scrolledwindow = ScrolledWindow + end +end + +class Tk::Tcllib::Widget::ScrolledWindow + TkCommandNames = ['::widget::scrolledwindow'.freeze].freeze + + def __numlistval_optkeys + ['ipad'] + end + private :__numlistval_optkeys + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def get_frame + window(tk_send('getframe')) + end + + def set_widget(widget) + tk_send('setwidget', widget) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/style.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/style.rb new file mode 100644 index 0000000000..dac6916e46 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/style.rb @@ -0,0 +1,61 @@ +# +# tkextlib/tcllib/style.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * select and use some 'style' of option (resource) DB +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +module Tk::Tcllib + module Style + PACKAGE_NAME = 'style'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('style') + rescue + '' + end + end + + def self.not_available + fail RuntimeError, "'tkextlib/tcllib/style' extension is not available on your current environment." + end + + def self.names + Tk::Tcllib::Style.not_available + end + + def self.use(style) + Tk::Tcllib::Style.not_available + end + end +end + +# TkPackage.require('style', '0.1') +# TkPackage.require('style', '0.3') +TkPackage.require('style') + +module Tk::Tcllib + class << Style + undef not_available + end + + module Style + extend TkCore + + def self.names + tk_split_simplelist(tk_call('style::names')) + end + + def self.use(style) + tk_call('style::use', style) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/superframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/superframe.rb new file mode 100644 index 0000000000..35da37efbf --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/superframe.rb @@ -0,0 +1,51 @@ +# +# tkextlib/tcllib/superframe.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Superframe widget - enhanced labelframe widget +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget::superframe', '1.0') +TkPackage.require('widget::superframe') + +module Tk::Tcllib + module Widget + class SuperFrame < TkWindow + PACKAGE_NAME = 'widget::superframe'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget::superframe') + rescue + '' + end + end + end + Superframe = SuperlFrame + end +end + +class Tk::Tcllib::Widget::SuperFrame + TkCommandNames = ['::widget::superframe'.freeze].freeze + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def labelwidget + window(tk_send('labelwidget')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/swaplist.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/swaplist.rb new file mode 100644 index 0000000000..97de0a27c1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/swaplist.rb @@ -0,0 +1,147 @@ +# +# tkextlib/tcllib/swaplist.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * A dialog which allows a user to move options between two lists +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('swaplist', '0.1') +TkPackage.require('swaplist') + +module Tk::Tcllib + class Swaplist_Dialog < TkWindow + PACKAGE_NAME = 'swaplist'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('swaplist') + rescue + '' + end + end + end +end + + +class Tk::Tcllib::Swaplist_Dialog + TkCommandNames = ['::swaplist::swaplist'.freeze].freeze + WidgetClassName = 'Swaplist'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.show(*args) + dialog = self.new(*args) + dialog.show + [dialog.status, dialog.value] + end + def self.display(*args) + self.show(*args) + end + + def initialize(*args) + # args = (parent=nil, complete_list=[], selected_list=[], keys=nil) + keys = args.pop + if keys.kind_of?(Hash) + @selected_list = args.pop + @complete_list = args.pop + @keys = _symbolkey2str(keys) + args.push(keys) + else + @selected_list = keys + @complete_list = args.pop + @keys = {} + end + + @selected_list = [] unless @selected_list + @complete_list = [] unless @complete_list + + @variable = TkVariable.new + @status = nil + + super(*args) + end + + def create_self(keys) + # dummy + end + private :create_self + + def show + @variable.value = '' + @status = bool(tk_call(self.class::TkCommandNames[0], + @path, @variable, + @complete_list, @selected_list, + *hash_kv(@keys))) + end + alias display show + + def status + @status + end + + def value + @variable.list + end + alias selected value + + def cget(slot) + slot = slot.to_s + if slot == 'complete_list' + @complete_list + elsif slot == 'selected_list' + @selected_list + else + @keys[slot] + end + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot.each{|k, v| configure(k, v)} + else + slot = slot.to_s + value = _symbolkey2str(value) if value.kind_of?(Hash) + if value && value != None + if slot == 'complete_list' + @complete_list = value + elsif slot == 'selected_list' + @selected_list = value + else + @keys[slot] = value + end + else + if slot == 'complete_list' + @complete_list = [] + elsif slot == 'selected_list' + @selected_list = [] + else + @keys.delete(slot) + end + end + end + self + end + + def configinfo(slot = nil) + if slot + slot = slot.to_s + if slot == 'complete_list' + [ slot, nil, nil, nil, @complete_list ] + elsif slot == 'selected_list' + [ slot, nil, nil, nil, @selected_list ] + else + [ slot, nil, nil, nil, @keys[slot] ] + end + else + @keys.collect{|k, v| [ k, nil, nil, nil, v ] } \ + << [ 'complete_list', nil, nil, nil, @complete_list ] \ + << [ 'selected_list', nil, nil, nil, @selected_list ] + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist.rb new file mode 100644 index 0000000000..efeb8fbbac --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist.rb @@ -0,0 +1,27 @@ +# +# tkextlib/tcllib/tablelist.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * A multi-column listbox + +require 'tk' +require 'tkextlib/tcllib.rb' + +# check Tile extension :: If already loaded, use tablelist_tile. +unless defined? Tk::Tcllib::Tablelist_usingTile + Tk::Tcllib::Tablelist_usingTile = TkPackage.provide('tile') +end + +if Tk::Tcllib::Tablelist_usingTile + # with Tile + require 'tkextlib/tcllib/tablelist_tile' + +else + # without Tile + + # TkPackage.require('Tablelist', '4.2') + TkPackage.require('Tablelist') + + require 'tkextlib/tcllib/tablelist_core' +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb new file mode 100644 index 0000000000..a939a58331 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb @@ -0,0 +1,770 @@ +# +# tkextlib/tcllib/tablelist_core.rb +# +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * This file is required by 'tkextlib/tcllib/tablelist.rb' or +# 'tkextlib/tcllib/tablelist_tile.rb'. +# + +module Tk + module Tcllib + class Tablelist < TkWindow + if Tk::Tcllib::Tablelist_usingTile + PACKAGE_NAME = 'Tablelist_tile'.freeze + else + PACKAGE_NAME = 'Tablelist'.freeze + end + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require(self.package_name) + rescue + '' + end + end + + def self.use_Tile? + (Tk::Tcllib::Tablelist_usingTile)? true: false + end + end + TableList = Tablelist + end +end + +module Tk::Tcllib::TablelistItemConfig + include TkItemConfigMethod + + def _to_idx(idx) + if idx.kind_of?(Array) + idx.collect{|elem| _get_eval_string(elem)}.join(',') + else + idx + end + end + def _from_idx(idx) + return idx unless idx.kind_of?(String) + + if idx[0] == ?@ # '@x,y' + idx + elsif idx =~ /([^,]+),([^,]+)/ + row = $1, column = $2 + [num_or_str(row), num_or_str(column)] + else + num_or_str(idx) + end + end + private :_to_idx, :_from_idx + + def __item_cget_cmd(mixed_id) + [self.path, mixed_id[0] + 'cget', _to_idx(mixed_id[1])] + end + def __item_config_cmd(mixed_id) + [self.path, mixed_id[0] + 'configure', _to_idx(mixed_id[1])] + end + + def cell_cget(tagOrId, option) + itemcget(['cell', tagOrId], option) + end + def cell_configure(tagOrId, slot, value=None) + itemconfigure(['cell', tagOrId], slot, value) + end + def cell_configinfo(tagOrId, slot=nil) + itemconfiginfo(['cell', tagOrId], slot) + end + def current_cell_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['cell', tagOrId], slot) + end + alias cellcget cell_cget + alias cellconfigure cell_configure + alias cellconfiginfo cell_configinfo + alias current_cellconfiginfo current_cell_configinfo + + def column_cget(tagOrId, option) + itemcget(['column', tagOrId], option) + end + def column_configure(tagOrId, slot, value=None) + itemconfigure(['column', tagOrId], slot, value) + end + def column_configinfo(tagOrId, slot=nil) + itemconfiginfo(['column', tagOrId], slot) + end + def current_column_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['column', tagOrId], slot) + end + alias columncget column_cget + alias columnconfigure column_configure + alias columnconfiginfo column_configinfo + alias current_columnconfiginfo current_column_configinfo + + def row_cget(tagOrId, option) + itemcget(['row', tagOrId], option) + end + def row_configure(tagOrId, slot, value=None) + itemconfigure(['row', tagOrId], slot, value) + end + def row_configinfo(tagOrId, slot=nil) + itemconfiginfo(['row', tagOrId], slot) + end + def current_row_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['row', tagOrId], slot) + end + alias rowcget row_cget + alias rowconfigure row_configure + alias rowconfiginfo row_configinfo + alias current_rowconfiginfo current_row_configinfo + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +class Tk::Tcllib::Tablelist + include Tk::Tcllib::TablelistItemConfig + include Scrollable + + TkCommandNames = ['::tablelist::tablelist'.freeze].freeze + WidgetClassName = 'Tablelist'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + ########################## + + def __numval_optkeys + super() + ['titlecolumns'] + end + private :__numval_optkeys + + def __strval_optkeys + super() + ['snipstring'] + end + private :__strval_optkeys + + def __boolval_optkeys + super() + [ + 'forceeditendcommand', 'movablecolumns', 'movablerows', + 'protecttitlecolumns', 'resizablecolumns', + 'showarrow', 'showlabels', 'showseparators' + ] + end + private :__boolval_optkeys + + def __listval_optkeys + super() + ['columns'] + end + private :__listval_optkeys + + def __tkvariable_optkeys + super() + ['listvariable'] + end + private :__tkvariable_optkeys + + def __val2ruby_optkeys # { key=>proc, ... } + # The method is used to convert a opt-value to a ruby's object. + # When get the value of the option "key", "proc.call(value)" is called. + super().update('stretch'=>proc{|v| (v == 'all')? v: simplelist(v)}) + end + private :__val2ruby_optkeys + + def __ruby2val_optkeys # { key=>proc, ... } + # The method is used to convert a ruby's object to a opt-value. + # When set the value of the option "key", "proc.call(value)" is called. + # That is, "-#{key} #{proc.call(value)}". + super().update('stretch'=>proc{|v| + (v.kind_of?(Array))? v.collect{|e| _to_idx(e)}: v + }) + end + private :__ruby2val_optkeys + + def __font_optkeys + super() + ['labelfont'] + end + private :__font_optkeys + + ########################## + + def __item_strval_optkeys(id) + if id[0] == 'cell' + super(id) + ['title'] + else + super(id) - ['text'] + ['title'] + end + end + private :__item_strval_optkeys + + def __item_boolval_optkeys(id) + super(id) + [ + 'editable', 'hide', 'resizable', 'showarrow', 'stretchable', + ] + end + private :__item_boolval_optkeys + + def __item_listval_optkeys(id) + if id[0] == 'cell' + super(id) + else + super(id) + ['text'] + end + end + private :__item_listval_optkeys + + def __item_font_optkeys(id) + # maybe need to override + super(id) + ['labelfont'] + end + private :__item_font_optkeys + + ########################## + + def activate(index) + tk_send('activate', _to_idx(index)) + self + end + + def activate_cell(index) + tk_send('activatecell', _to_idx(index)) + self + end + alias activatecell activate_cell + + def get_attrib(name=nil) + if name && name != None + tk_send('attrib', name) + else + ret = [] + lst = simplelist(tk_send('attrib')) + until lst.empty? + ret << ( [lst.shift] << lst.shift ) + end + ret + end + end + def set_attrib(*args) + tk_send('attrib', *(args.flatten)) + self + end + + def bbox(index) + list(tk_send('bbox', _to_idx(index))) + end + + def bodypath + window(tk_send('bodypath')) + end + + def bodytag + TkBindTag.new_by_name(tk_send('bodytag')) + end + + def cancel_editing + tk_send('cancelediting') + self + end + alias cancelediting cancel_editing + + def cellindex(idx) + _from_idx(tk_send('cellindex', _to_idx(idx))) + end + + def cellselection_anchor(idx) + tk_send('cellselection', 'anchor', _to_idx(idx)) + self + end + + def cellselection_clear(first, last=nil) + if first.kind_of?(Array) + tk_send('cellselection', 'clear', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('cellselection', 'clear', first, last) + end + self + end + + def cellselection_includes(idx) + bool(tk_send('cellselection', 'includes', _to_idx(idx))) + end + + def cellselection_set(first, last=nil) + if first.kind_of?(Array) + tk_send('cellselection', 'set', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('cellselection', 'set', first, last) + end + self + end + + def columncount + number(tk_send('columncount')) + end + + def columnindex(idx) + number(tk_send('columnindex', _to_idx(idx))) + end + + def containing(y) + idx = num_or_str(tk_send('containing', y)) + (idx.kind_of?(Fixnum) && idx < 0)? nil: idx + end + + def containing_cell(x, y) + idx = _from_idx(tk_send('containingcell', x, y)) + if idx.kind_of?(Array) + [ + ((idx[0].kind_of?(Fixnum) && idx[0] < 0)? nil: idx[0]), + ((idx[1].kind_of?(Fixnum) && idx[1] < 0)? nil: idx[1]) + ] + else + idx + end + end + alias containingcell containing_cell + + def containing_column(x) + idx = num_or_str(tk_send('containingcolumn', x)) + (idx.kind_of?(Fixnum) && idx < 0)? nil: idx + end + alias containingcolumn containing_column + + def curcellselection + simplelist(tk_send('curcellselection')).collect!{|idx| _from_idx(idx)} + end + + def curselection + list(tk_send('curselection')) + end + + def delete_items(first, last=nil) + if first.kind_of?(Array) + tk_send('delete', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('delete', first, last) + end + self + end + alias delete delete_items + alias deleteitems delete_items + + def delete_columns(first, last=nil) + if first.kind_of?(Array) + tk_send('deletecolumns', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('deletecolumns', first, last) + end + self + end + alias deletecolumns delete_columns + + def edit_cell(idx) + tk_send('editcell', _to_idx(idx)) + self + end + alias editcell edit_cell + + def editwinpath + window(tk_send('editwinpath')) + end + + def entrypath + window(tk_send('entrypath')) + end + + def fill_column(idx, txt) + tk_send('fillcolumn', _to_idx(idx), txt) + self + end + alias fillcolumn fill_column + + def finish_editing + tk_send('finishediting') + self + end + alias finishediting finish_editing + + def get(first, last=nil) + if first.kind_of?(Array) + simplelist(tk_send('get', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) } + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + simplelist(tk_send('get', first, last)) + end + end + + def get_cells(first, last=nil) + if first.kind_of?(Array) + simplelist(tk_send('getcells', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) } + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + simplelist(tk_send('getcells', first, last)) + end + end + alias getcells get_cells + + def get_columns(first, last=nil) + if first.kind_of?(Array) + simplelist(tk_send('getcolumns', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) } + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + simplelist(tk_send('getcolumns', first, last)) + end + end + alias getcolumns get_columns + + def get_keys(first, last=nil) + if first.kind_of?(Array) + simplelist(tk_send('getkeys', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) } + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + simplelist(tk_send('getkeys', first, last)) + end + end + alias getkeys get_keys + + def imagelabelpath(idx) + window(tk_send('imagelabelpath', _to_idx(idx))) + end + + def index(idx) + number(tk_send('index', _to_idx(idx))) + end + + def insert(idx, *items) + tk_send('insert', _to_idx(idx), *items) + self + end + + def insert_columnlist(idx, columnlist) + tk_send('insertcolumnlist', _to_idx(idx), columnlist) + self + end + alias insertcolumnlist insert_columnlist + + def insert_columns(idx, *args) + tk_send('insertcolums', _to_idx(idx), *args) + self + end + alias insertcolumns insert_columns + + def insert_list(idx, list) + tk_send('insertlist', _to_idx(idx), list) + self + end + alias insertlist insert_list + + def itemlistvar + TkVarAccess.new(tk_send('itemlistvar')) + end + + def labelpath(idx) + window(tk_send('labelpath', _to_idx(idx))) + end + + def labels + simplelist(tk_send('labels')) + end + + def move(src, target) + tk_send('move', _to_idx(src), _to_idx(target)) + self + end + + def move_column(src, target) + tk_send('movecolumn', _to_idx(src), _to_idx(target)) + self + end + alias movecolumn move_column + + def nearest(y) + _from_idx(tk_send('nearest', y)) + end + + def nearest_cell(x, y) + _from_idx(tk_send('nearestcell', x, y)) + end + alias nearestcell nearest_cell + + def nearest_column(x) + _from_idx(tk_send('nearestcolumn', x)) + end + alias nearestcolumn nearest_column + + def reject_input + tk_send('rejectinput') + self + end + alias rejectinput reject_input + + def reset_sortinfo + tk_send('resetsortinfo') + self + end + alias resetsortinfo reset_sortinfo + + 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 see(idx) + tk_send('see', _to_idx(idx)) + self + end + + def see_cell(idx) + tk_send('seecell', _to_idx(idx)) + self + end + alias seecell see_cell + + def see_column(idx) + tk_send('seecolumn', _to_idx(idx)) + self + end + alias seecolumn see_column + + def selection_anchor(idx) + tk_send('selection', 'anchor', _to_idx(idx)) + self + end + + def selection_clear(first, last=nil) + if first.kind_of?(Array) + tk_send('selection', 'clear', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('selection', 'clear', first, last) + end + self + end + + def selection_includes(idx) + bool(tk_send('selection', 'includes', _to_idx(idx))) + end + + def selection_set(first, last=nil) + if first.kind_of?(Array) + tk_send('selection', 'set', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('selection', 'set', first, last) + end + self + end + + def separatorpath(idx=nil) + if idx + window(tk_send('separatorpath', _to_idx(idx))) + else + window(tk_send('separatorpath')) + end + end + + def separators + simplelist(tk_send('separators')).collect!{|w| window(w)} + end + + def size + number(tk_send('size')) + end + + def sort(order=nil) + if order + order = order.to_s + order = '-' << order if order[0] != ?- + if order.length < 2 + order = nil + end + end + if order + tk_send('sort', order) + else + tk_send('sort') + end + self + end + def sort_increasing + tk_send('sort', '-increasing') + self + end + def sort_decreasing + tk_send('sort', '-decreasing') + self + end + + DEFAULT_sortByColumn_cmd = '::tablelist::sortByColumn' + + def sort_by_column(idx, order=nil) + if order + order = order.to_s + order = '-' << order if order[0] != ?- + if order.length < 2 + order = nil + end + end + if order + tk_send('sortbycolumn', _to_idx(idx), order) + else + tk_send('sortbycolumn', _to_idx(idx)) + end + self + end + def sort_by_column_increasing(idx) + tk_send('sortbycolumn', _to_idx(idx), '-increasing') + self + end + def sort_by_column_decreasing(idx) + tk_send('sortbycolumn', _to_idx(idx), '-decreasing') + self + end + + def sortcolumn + idx = num_or_str(tk_send('sortcolum')) + (idx.kind_of?(Fixnum) && idx < 0)? nil: idx + end + + def sortorder + tk_send('sortorder') + end + + def toggle_visibility(first, last=nil) + if first.kind_of?(Array) + tk_send('togglevisibility', first.collect{|idx| _to_idx(idx)}) + else + first = _to_idx(first) + last = (last)? _to_idx(last): first + tk_send('togglevisibility', first, last) + end + self + end + alias togglevisibility toggle_visibility + + def windowpath(idx) + window(tk_send('windowpath', _to_idx(idx))) + end +end + +class << Tk::Tcllib::Tablelist + ############################################################ + # helper commands + def getTablelistPath(descendant) + window(Tk.tk_call('::tablelist::getTablelistPath', descendant)) + end + + def convEventFields(descendant, x, y) + window(Tk.tk_call('::tablelist::convEventFields', descendant, x, y)) + end + + + ############################################################ + # with the BWidget package + def addBWidgetEntry(name=None) + Tk.tk_call('::tablelist::addBWidgetEntry', name) + end + + def addBWidgetSpinBox(name=None) + Tk.tk_call('::tablelist::addBWidgetSpinBox', name) + end + + def addBWidgetComboBox(name=None) + Tk.tk_call('::tablelist::addBWidgetComboBox', name) + end + + + ############################################################ + # with the Iwidgets ([incr Widgets]) package + def addIncrEntryfield(name=None) + Tk.tk_call('::tablelist::addIncrEntry', name) + end + + def addIncrDateTimeWidget(type, seconds=false, name=None) + # type := 'datefield'|'dateentry'|timefield'|'timeentry' + if seconds && seconds != None + seconds = '-seconds' + else + seconds = None + end + Tk.tk_call('::tablelist::addDateTimeWidget', type, seconds, name) + end + + def addIncrSpinner(name=None) + Tk.tk_call('::tablelist::addIncrSpinner', name) + end + + def addIncrSpinint(name=None) + Tk.tk_call('::tablelist::addIncrSpinint', name) + end + + def addIncrCombobox(name=None) + Tk.tk_call('::tablelist::addIncrCombobox', name) + end + + + ############################################################ + # with Bryan Oakley's combobox package + def addOakleyCombobox(name=None) + Tk.tk_call('::tablelist::addOakleyCombobox', name) + end + + ############################################################ + # with the multi-entry package Mentry is a library extension + def addDateMentry(format, separator, gmt=false, name=None) + if gmt && gmt != None + gmt = '-gmt' + else + gmt = None + end + Tk.tk_call('::tablelist::addDateMentry', format, separator, gmt, name) + end + + def addTimeMentry(format, separator, gmt=false, name=None) + if gmt && gmt != None + gmt = '-gmt' + else + gmt = None + end + Tk.tk_call('::tablelist::addTimeMentry', format, separator, gmt, name) + end + + def addFixedPointMentry(count1, count2, comma=false, name=None) + if comma && comma != None + comma = '-comma' + else + comma = None + end + Tk.tk_call('::tablelist::addFixedPoingMentry', count1, count2, comma, name) + end + + def addIPAddrMentry(name=None) + Tk.tk_call('::tablelist::addIPAddrMentry', name) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb new file mode 100644 index 0000000000..0cb4eb735d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb @@ -0,0 +1,25 @@ +# +# tkextlib/tcllib/tablelist_tlie.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * A multi-column listbox + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('tablelist_tile', '4.2') +TkPackage.require('Tablelist_tile') + +unless defined? Tk::Tcllib::Tablelist_usingTile + Tk::Tcllib::Tablelist_usingTile = true +end + +requrie 'tkextlib/tcllib/tablelist_core' + +module Tk + module Tcllib + Tablelist_Tile = Tablelist + TableList_Tile = Tablelist + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tkpiechart.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tkpiechart.rb new file mode 100644 index 0000000000..92dde65ce7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tkpiechart.rb @@ -0,0 +1,308 @@ +# +# tkextlib/tcllib/tkpiechart.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Create 2D or 3D pies with labels in Tcl canvases +# + +require 'tk' +require 'tk/canvas' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('tkpiechart', '6.6') +TkPackage.require('tkpiechart') + +module Tk + module Tcllib + module Tkpiechart + end + end +end + +module Tk::Tcllib::Tkpiechart + PACKAGE_NAME = 'tkpiechart'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('tkpiechart') + rescue + '' + end + end + + module ConfigMethod + include TkConfigMethod + + def __pathname + self.path + ';' + self.tag + end + private :__pathname + + def __cget_cmd + ['::switched::cget', self.tag] + end + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + def __configinfo_struct + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>1, :current_value=>2} + end + private :__configinfo_struct + + def __boolval_optkeys + super() << 'select' << 'autoupdate' << 'selectable' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'bordercolor' << 'textbackground' << + 'widestvaluetext' << 'title' + end + private :__strval_optkeys + + def __listval_optkeys + super() << 'colors' + end + private :__listval_optkeys + end + + #################################### + class PieChartObj < TkcItem + include ConfigMethod + + def __font_optkeys + ['titlefont'] + end + private :__font_optkeys + end + + #################################### + class Pie < TkcItem + include ConfigMethod + + def create_self(x, y, width, height, keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', 'pie', + @c, x, y, *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'pie', @c, x, y) + end + + @slice_tbl = {} + + id = "pie(#{@tag_key})" + + @tag = @tag_pie = TkcNamedTag(@c, id) + @tag_slices = TkcNamedTag(@c, "pieSlices(#{@tag_key})") + + id + end + private :create_self + + def tag_key + @tag_key + end + def tag + @tag + end + def canvas + @c + end + def _entry_slice(slice) + @slice_tbl[slice.to_eval] = slice + end + def _delete_slice(slice) + @slice_tbl.delete(slice.to_eval) + end + + def delete + tk_call_without_enc('::stooop::delete', @tag_key) + CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + self + end + + def new_slice(text=None) + Slice.new(self, text) + end + + def delete_slice(slice) + unless slice.kind_of?(Slice) + unless (slice = @slice_tbl[slice]) + return tk_call_without_enc('pie::deleteSlice', @tag_key, slice) + end + end + unless slice.kind_of?(Slice) && slice.pie == self + fail ArgumentError, "argument is not a slice of self" + end + slice.delete + end + + def selected_slices + tk_split_simplelist(tk_call_without_enc('pie::selectedSlices', + @tag_key)).collect{|slice| + @slice_tbl[slice] || Slice.new(:no_create, self, slice) + } + end + end + + #################################### + class Slice < TkcItem + include ConfigMethod + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def initialize(pie, *args) + unless pie.kind_of?(Pie) && pie != :no_create + fail ArgumentError, "expects TkPiechart::Pie for 1st argument" + end + + if pie == :no_create + @pie, @tag_key = args + else + text = args[0] || None + @pie = pie + @tag_key = tk_call_without_enc('pie::newSlice', @pie.tag_key, text) + end + @parent = @c = @pie.canvas + @path = @parent.path + + @pie._entry_slice(self) + + @id = "slices(#{@tag_key})" + @tag = TkcNamedTag.new(@pie.canvas, @id) + + CItemID_TBL[@path] = {} unless CItemID_TBL[@path] + CItemID_TBL[@path][@id] = self + end + + def tag_key + @tag_key + end + def tag + @tag + end + def pie + @pie + end + + def delete + tk_call_without_enc('pie::deleteSlice', @pie.tag_key, @tag_key) + CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + @pie._delete_slice(self) + self + end + + def size(share, disp=None) + tk_call_without_enc('pie::sizeSlice', + @pie.tag_key, @tag_key, share, disp) + self + end + + def label(text) + tk_call_without_enc('pie::labelSlice', @pie.tag_key, @tag_key, text) + self + end + end + + #################################### + class BoxLabeler < TkcItem + include ConfigMethod + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def create_self(keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler', + *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler') + end + + id = "pieBoxLabeler(#{@tag_key})" + @tag = TkcNamedTag(@c, id) + + id + end + private :create_self + end + + #################################### + class PeripheralLabeler < TkcItem + include ConfigMethod + + def __font_optkeys + ['font', 'smallfont'] + end + private :__font_optkeys + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def create_self(keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', + 'piePeripheralLabeler', + *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'piePeripheralLabeler') + end + + id = "piePeripheralLabeler(#{@tag_key})" + @tag = TkcNamedTag(@c, id) + + id + end + private :create_self + end + + #################################### + class Label < TkcItem + include ConfigMethod + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def create_self(x, y, keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel', + @c, x, y, width, height, + *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel', + @c, x, y, width, height) + end + + id = "canvasLabel(#{@tag_key})" + @tag = TkcNamedTag(@c, id) + + id + end + private :create_self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tooltip.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tooltip.rb new file mode 100644 index 0000000000..4301b39fd3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/tooltip.rb @@ -0,0 +1,95 @@ +# +# tkextlib/tcllib/tooltip.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * Provides tooltips, a small text message that is displayed when the +# mouse hovers over a widget. +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('tooltip', '1.1') +TkPackage.require('tooltip') + +module Tk::Tcllib + module Tooltip + PACKAGE_NAME = 'tooltip'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('tooltip') + rescue + '' + end + end + end +end + +module Tk::Tcllib::Tooltip + extend TkCore + + WidgetClassName = 'Tooltip'.freeze + def self.database_classname + self::WidgetClassName + end + def self.database_class + WidgetClassNames[self::WidgetClassName] + end + + def self.clear(glob_path_pat = None) + self.clear_glob(glob_path_pat) + end + + def self.clear_glob(glob_path_pat) + tk_call_without_enc('::tooltip::tooltip', 'clear', glob_path_pat) + end + + def self.clear_widgets(*args) + self.clear_glob("{#{args.collect{|w| _get_eval_string(w)}.join(',')}}") + end + + def self.clear_children(*args) + self.clear_glob("{#{args.collect{|w| s = _get_eval_string(w); "#{s},#{s}.*"}.join(',')}}") + end + + def self.delay(millisecs=None) + number(tk_call_without_enc('::tooltip::tooltip', 'delay', millisecs)) + end + def self.delay=(millisecs) + self.delay(millisecs) + end + + def self.disable + tk_call_without_enc('::tooltip::tooltip', 'disable') + false + end + def self.off + self.disable + end + + def self.enable + tk_call_without_enc('::tooltip::tooltip', 'enable') + true + end + def self.on + self.enable + end + + def self.register(widget, msg, keys=nil) + if keys.kind_of?(Hash) + args = hash_kv(keys) << msg + else + args = msg + end + tk_call_without_enc('::tooltip::tooltip', widget.path, *args) + end + + def self.erase(widget) + tk_call_without_enc('::tooltip::tooltip', widget.path, '') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/widget.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/widget.rb new file mode 100644 index 0000000000..ed69f67ce6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tcllib/widget.rb @@ -0,0 +1,48 @@ +# +# tkextlib/tcllib/widget.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# * Part of tcllib extension +# * megawidget package that uses snit as the object system (snidgets) +# + +require 'tk' +require 'tkextlib/tcllib.rb' + +# TkPackage.require('widget', '3.0') +TkPackage.require('widget') + +module Tk::Tcllib + module Widget + PACKAGE_NAME = 'widget'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('widget') + rescue + '' + end + end + end +end + +module Tk::Tcllib::Widget + autoload :Dialog, 'tkextlib/tcllib/dialog' + + autoload :Panelframe, 'tkextlib/tcllib/panelframe' + autoload :PanelFrame, 'tkextlib/tcllib/panelframe' + + autoload :Ruler, 'tkextlib/tcllib/ruler' + + autoload :Screenruler, 'tkextlib/tcllib/screenruler' + autoload :ScreenRuler, 'tkextlib/tcllib/screenruler' + + autoload :Scrolledwindow, 'tkextlib/tcllib/scrollwin' + autoload :ScrolledWindow, 'tkextlib/tcllib/scrollwin' + + autoload :Superframe, 'tkextlib/tcllib/superframe' + autoload :SuperFrame, 'tkextlib/tcllib/superframe' +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tclx.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tclx.rb new file mode 100644 index 0000000000..3a4ff27644 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tclx.rb @@ -0,0 +1,13 @@ +# +# TclX support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tclx/setup.rb' + +# load library +require 'tkextlib/tclx/tclx' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tclx/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tclx/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tclx/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tclx/tclx.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tclx/tclx.rb new file mode 100644 index 0000000000..5a908fcd0b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tclx/tclx.rb @@ -0,0 +1,74 @@ +# +# tclx/tclx.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tclx/setup.rb' + +# TkPackage.require('Tclx', '8.0') +TkPackage.require('Tclx') + +module Tk + module TclX + PACKAGE_NAME = 'Tclx'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Tclx') + rescue + '' + end + end + + def self.infox(*args) + Tk.tk_call('infox', *args) + end + + def self.signal(*args) + warn("Warning: Don't recommend to use TclX's 'signal' command. Please use Ruby's 'Signal.trap' method") + Tk.tk_call('signal', *args) + end + + def self.signal_restart(*args) + warn("Warning: Don't recommend to use TclX's 'signal' command. Please use Ruby's 'Signal.trap' method") + Tk.tk_call('signal', '-restart', *args) + end + + ############################## + + class XPG3_MsgCat + class << self + alias open new + end + + def initialize(catname, fail_mode=false) + if fail_mode + @msgcat_id = Tk.tk_call('catopen', '-fail', catname) + else + @msgcat_id = Tk.tk_call('catopen', '-nofail', catname) + end + end + + def close(fail_mode=false) + if fail_mode + Tk.tk_call('catclose', '-fail', @msgcat_id) + else + Tk.tk_call('catclose', '-nofail', @msgcat_id) + end + self + end + + def get(setnum, msgnum, defaultstr) + Tk.tk_call('catgets', @msgcat_id, setnum, msgnum, defaultstr) + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile.rb new file mode 100644 index 0000000000..acc7bebe4e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile.rb @@ -0,0 +1,230 @@ +# +# Tile theme engin (tile widget set) support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +require 'tkextlib/tile/setup.rb' + +# load package +# TkPackage.require('tile', '0.4') +# TkPackage.require('tile', '0.6') +# TkPackage.require('tile', '0.7') +verstr = TkPackage.require('tile') +ver = verstr.split('.') +if ver[0].to_i == 0 && ver[1].to_i <= 4 + # version 0.4 or former + module Tk + module Tile + USE_TILE_NAMESPACE = true + USE_TTK_NAMESPACE = false + TILE_SPEC_VERSION_ID = 0 + end + end +elsif ver[0].to_i == 0 && ver[1].to_i <= 6 + # version 0.5 -- version 0.6 + module Tk + module Tile + USE_TILE_NAMESPACE = true + USE_TTK_NAMESPACE = true + TILE_SPEC_VERSION_ID = 5 + end + end +else + # version 0.7 or later + module Tk + module Tile + USE_TILE_NAMESPACE = false + USE_TTK_NAMESPACE = true + TILE_SPEC_VERSION_ID = 7 + end + end +end + +# autoload +module Tk + module Tile + TkComm::TkExtlibAutoloadModule.unshift(self) + + PACKAGE_NAME = 'tile'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('tile') + rescue + '' + end + end + + def self.__Import_Tile_Widgets__! + Tk.tk_call('namespace', 'import', '-force', 'ttk::*') + end + + def self.load_images(imgdir, pat=TkComm::None) + images = Hash[*TkComm.simplelist(Tk.tk_call('::tile::LoadImages', + imgdir, pat))] + images.keys.each{|k| + images[k] = TkPhotoImage.new(:imagename=>images[k], + :without_creating=>true) + } + + images + end + + def self.style(*args) + args.map!{|arg| TkComm._get_eval_string(arg)}.join('.') + end + + module KeyNav + def self.enableMnemonics(w) + Tk.tk_call('::keynav::enableMnemonics', w) + end + def self.defaultButton(w) + Tk.tk_call('::keynav::defaultButton', w) + end + end + + module Font + Default = 'TkDefaultFont' + Text = 'TkTextFont' + Heading = 'TkHeadingFont' + Caption = 'TkCaptionFont' + Tooltip = 'TkTooltipFont' + + Fixed = 'TkFixedFont' + Menu = 'TkMenuFont' + SmallCaption = 'TkSmallCaptionFont' + Icon = 'TkIconFont' + end + + module ParseStyleLayout + def _style_layout(lst) + ret = [] + until lst.empty? + sub = [lst.shift] + keys = {} + + until lst.empty? + if lst[0][0] == ?- + k = lst.shift[1..-1] + children = lst.shift + children = _style_layout(children) if children.kind_of?(Array) + keys[k] = children + else + break + end + end + + sub << keys unless keys.empty? + ret << sub + end + ret + end + private :_style_layout + end + + module TileWidget + include Tk::Tile::ParseStyleLayout + + def __val2ruby_optkeys # { key=>proc, ... } + # The method is used to convert a opt-value to a ruby's object. + # When get the value of the option "key", "proc.call(value)" is called. + super().update('style'=>proc{|v| _style_layout(list(v))}) + end + private :__val2ruby_optkeys + + def instate(state, script=nil, &b) + if script + tk_send('instate', state, script) + elsif b + tk_send('instate', state, Proc.new(&b)) + else + bool(tk_send('instate', state)) + end + end + + def state(state=nil) + if state + tk_send('state', state) + else + list(tk_send('state')) + end + end + + def identify(x, y) + ret = tk_send_without_enc('identify', x, y) + (ret.empty?)? nil: ret + end + end + + ###################################### + + autoload :TButton, 'tkextlib/tile/tbutton' + autoload :Button, 'tkextlib/tile/tbutton' + + autoload :TCheckButton, 'tkextlib/tile/tcheckbutton' + autoload :CheckButton, 'tkextlib/tile/tcheckbutton' + autoload :TCheckbutton, 'tkextlib/tile/tcheckbutton' + autoload :Checkbutton, 'tkextlib/tile/tcheckbutton' + + autoload :Dialog, 'tkextlib/tile/dialog' + + autoload :TEntry, 'tkextlib/tile/tentry' + autoload :Entry, 'tkextlib/tile/tentry' + + autoload :TCombobox, 'tkextlib/tile/tcombobox' + autoload :Combobox, 'tkextlib/tile/tcombobox' + + autoload :TFrame, 'tkextlib/tile/tframe' + autoload :Frame, 'tkextlib/tile/tframe' + + autoload :TLabelframe, 'tkextlib/tile/tlabelframe' + autoload :Labelframe, 'tkextlib/tile/tlabelframe' + + autoload :TLabel, 'tkextlib/tile/tlabel' + autoload :Label, 'tkextlib/tile/tlabel' + + autoload :TMenubutton, 'tkextlib/tile/tmenubutton' + autoload :Menubutton, 'tkextlib/tile/tmenubutton' + + autoload :TNotebook, 'tkextlib/tile/tnotebook' + autoload :Notebook, 'tkextlib/tile/tnotebook' + + autoload :TPaned, 'tkextlib/tile/tpaned' + autoload :Paned, 'tkextlib/tile/tpaned' + + autoload :TProgressbar, 'tkextlib/tile/tprogressbar' + autoload :Progressbar, 'tkextlib/tile/tprogressbar' + + autoload :TRadioButton, 'tkextlib/tile/tradiobutton' + autoload :RadioButton, 'tkextlib/tile/tradiobutton' + autoload :TRadiobutton, 'tkextlib/tile/tradiobutton' + autoload :Radiobutton, 'tkextlib/tile/tradiobutton' + + autoload :TScale, 'tkextlib/tile/tscale' + autoload :Scale, 'tkextlib/tile/tscale' + autoload :TProgress, 'tkextlib/tile/tscale' + autoload :Progress, 'tkextlib/tile/tscale' + + autoload :TScrollbar, 'tkextlib/tile/tscrollbar' + autoload :Scrollbar, 'tkextlib/tile/tscrollbar' + + autoload :TSeparator, 'tkextlib/tile/tseparator' + autoload :Separator, 'tkextlib/tile/tseparator' + + autoload :TSquare, 'tkextlib/tile/tsquare' + autoload :Square, 'tkextlib/tile/tsquare' + + autoload :Treeview, 'tkextlib/tile/treeview' + + autoload :Style, 'tkextlib/tile/style' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/dialog.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/dialog.rb new file mode 100644 index 0000000000..b10378d7de --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/dialog.rb @@ -0,0 +1,84 @@ +# +# ttk::dialog (tile-0.7+) +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class Dialog < TkWindow + end + end +end + +class Tk::Tile::Dialog + TkCommandNames = ['::ttk::dialog'.freeze].freeze + + def self.show(*args) + dialog = self.new(*args) + dialog.show + [dialog.status, dialog.value] + end + def self.display(*args) + self.show(*args) + end + + def self.define_dialog_type(name, keys) + Tk.tk_call('::ttk::dialog::define', name, keys) + name + end + + def self.style(*args) + ['Dialog', *(args.map!{|a| _get_eval_string(a)})].join('.') + end + + ######################### + + def initialize(keys={}) + @keys = _symbolkey2str(keys) + super(*args) + end + + def create_self(keys) + # dummy + end + private :create_self + + def show + tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys)) + end + alias display show + + def client_frame + window(tk_call_without_enc('::ttk::dialog::clientframe', @path)) + end + + def cget(slot) + @keys[slot] + end + + def configure(slot, value=None) + if slot.kind_of?(Hash) + slot.each{|k, v| configure(k, v)} + else + slot = slot.to_s + value = _symbolkey2str(value) if value.kind_of?(Hash) + if value && value != None + @keys[slot] = value + else + @keys.delete(slot) + end + end + self + end + + def configinfo(slot = nil) + if slot + slot = slot.to_s + [ slot, nil, nil, nil, @keys[slot] ] + else + @keys.collect{|k, v| [ k, nil, nil, nil, v ] } + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/sizegrip.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/sizegrip.rb new file mode 100644 index 0000000000..ea796583b0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/sizegrip.rb @@ -0,0 +1,25 @@ +# +# ttk::sizegrip widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class SizeGrip < TkWindow + end + end +end + +class Tk::Tile::SizeGrip < TkWindow + include Tk::Tile::TileWidget + + TkCommandNames = ['::ttk::sizegrip'.freeze].freeze + WidgetClassName = 'TSizegrip'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/style.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/style.rb new file mode 100644 index 0000000000..59bc4b0d78 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/style.rb @@ -0,0 +1,107 @@ +# +# style commands +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + module Style + end + end +end + +module Tk::Tile::Style + extend TkCore +end + +class << Tk::Tile::Style + def configure(style=nil, keys=nil) + if style.kind_of?(Hash) + keys = style + style = nil + end + style = '.' unless style + + if Tk::Tile::TILE_SPEC_VERSION_ID < 7 + sub_cmd = 'default' + else + sub_cmd = 'configure' + end + + if keys && keys != None + tk_call('style', sub_cmd, style, *hash_kv(keys)) + else + tk_call('style', sub_cmd, style) + end + end + alias default configure + + def map(style=nil, keys=nil) + if style.kind_of?(Hash) + keys = style + style = nil + end + style = '.' unless style + + if keys && keys != None + tk_call('style', 'map', style, *hash_kv(keys)) + else + tk_call('style', 'map', style) + end + end + + def lookup(style, opt, state=None, fallback_value=None) + tk_call('style', 'lookup', style, '-' << opt.to_s, state, fallback_value) + end + + include Tk::Tile::ParseStyleLayout + + def layout(style=nil, spec=nil) + if style.kind_of?(Hash) + spec = style + style = nil + end + style = '.' unless style + + if spec + tk_call('style', 'layout', style, spec) + else + _style_layout(list(tk_call('style', 'layout', style))) + end + end + + def element_create(name, type, *args) + tk_call('style', 'element', 'create', name, type, *args) + end + + def element_names() + list(tk_call('style', 'element', 'names')) + end + + def element_options(elem) + simplelist(tk_call('style', 'element', 'options', elem)) + end + + def theme_create(name, keys=nil) + if keys && keys != None + tk_call('style', 'theme', 'create', name, *hash_kv(keys)) + else + tk_call('style', 'theme', 'create', name) + end + end + + def theme_settings(name, cmd=nil, &b) + cmd = Proc.new(&b) if !cmd && b + tk_call('style', 'theme', 'settings', name, cmd) + end + + def theme_names() + list(tk_call('style', 'theme', 'names')) + end + + def theme_use(name) + tk_call('style', 'theme', 'use', name) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tbutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tbutton.rb new file mode 100644 index 0000000000..1142a27100 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tbutton.rb @@ -0,0 +1,30 @@ +# +# tbutton widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TButton < TkButton + end + Button = TButton + end +end + +class Tk::Tile::TButton < TkButton + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::button'.freeze].freeze + else + TkCommandNames = ['::tbutton'.freeze].freeze + end + WidgetClassName = 'TButton'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tcheckbutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tcheckbutton.rb new file mode 100644 index 0000000000..fce799683d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tcheckbutton.rb @@ -0,0 +1,32 @@ +# +# tcheckbutton widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TCheckButton < TkCheckButton + end + TCheckbutton = TCheckButton + CheckButton = TCheckButton + Checkbutton = TCheckButton + end +end + +class Tk::Tile::TCheckButton < TkCheckButton + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::checkbutton'.freeze].freeze + else + TkCommandNames = ['::tcheckbutton'.freeze].freeze + end + WidgetClassName = 'TCheckbutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tcombobox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tcombobox.rb new file mode 100644 index 0000000000..e8e042fbd9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tcombobox.rb @@ -0,0 +1,51 @@ +# +# tcombobox widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TCombobox < Tk::Tile::TEntry + end + Combobox = TCombobox + end +end + +class Tk::Tile::TCombobox < Tk::Tile::TEntry + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::combobox'.freeze].freeze + else + TkCommandNames = ['::tcombobox'.freeze].freeze + end + WidgetClassName = 'TCombobox'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'exportselection' + end + private :__boolval_optkeys + + def __listval_optkeys + super() << 'values' + end + private :__listval_optkeys + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end + + def current + number(tk_send_without_enc('current')) + end + def current=(idx) + tk_send_without_enc('current', idx) + end + + def set(val) + tk_send('set', val) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tentry.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tentry.rb new file mode 100644 index 0000000000..4d57ce7756 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tentry.rb @@ -0,0 +1,40 @@ +# +# tentry widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TEntry < TkEntry + end + Entry = TEntry + end +end + +class Tk::Tile::TEntry < TkEntry + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::entry'.freeze].freeze + else + TkCommandNames = ['::tentry'.freeze].freeze + end + WidgetClassName = 'TEntry'.freeze + WidgetClassNames[WidgetClassName] = self + + def __boolval_optkeys + super() << 'exportselection' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'show' + end + private :__strval_optkeys + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tframe.rb new file mode 100644 index 0000000000..691c9c42af --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tframe.rb @@ -0,0 +1,30 @@ +# +# tframe widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TFrame < TkFrame + end + Frame = TFrame + end +end + +class Tk::Tile::TFrame < TkFrame + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::frame'.freeze].freeze + else + TkCommandNames = ['::tframe'.freeze].freeze + end + WidgetClassName = 'TFrame'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tlabel.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tlabel.rb new file mode 100644 index 0000000000..4111d1906a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tlabel.rb @@ -0,0 +1,30 @@ +# +# tlabel widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TLabel < TkLabel + end + Label = TLabel + end +end + +class Tk::Tile::TLabel < TkLabel + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::label'.freeze].freeze + else + TkCommandNames = ['::tlabel'.freeze].freeze + end + WidgetClassName = 'TLabel'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tlabelframe.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tlabelframe.rb new file mode 100644 index 0000000000..8981232b25 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tlabelframe.rb @@ -0,0 +1,30 @@ +# +# tlabelframe widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TLabelframe < Tk::Tile::TFrame + end + Labelframe = TLabelframe + end +end + +class Tk::Tile::TLabelframe < Tk::Tile::TFrame + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::labelframe'.freeze].freeze + else + TkCommandNames = ['::tlabelframe'.freeze].freeze + end + WidgetClassName = 'TLabelframe'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tmenubutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tmenubutton.rb new file mode 100644 index 0000000000..4b81fa1c81 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tmenubutton.rb @@ -0,0 +1,30 @@ +# +# tmenubutton widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TMenubutton < TkMenubutton + end + Menubutton = TMenubutton + end +end + +class Tk::Tile::TMenubutton < TkMenubutton + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::menubutton'.freeze].freeze + else + TkCommandNames = ['::tmenubutton'.freeze].freeze + end + WidgetClassName = 'TMenubutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tnotebook.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tnotebook.rb new file mode 100644 index 0000000000..a928e64b61 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tnotebook.rb @@ -0,0 +1,114 @@ +# +# tnotebook widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TNotebook < TkWindow + end + Notebook = TNotebook + end +end + +class Tk::Tile::TNotebook < TkWindow + ################################ + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'tab', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'tab', id] + end + private :__item_config_cmd + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys + + def __item_methodcall_optkeys(id) # { key=>method, ... } + {} + end + private :__item_methodcall_optkeys + + #alias tabcget itemcget + alias tabconfigure itemconfigure + alias tabconfiginfo itemconfiginfo + alias current_tabconfiginfo current_itemconfiginfo + + def tabcget(tagOrId, option) + tabconfigure(tagOrId, option)[-1] + end + ################################ + + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::notebook'.freeze].freeze + else + TkCommandNames = ['::tnotebook'.freeze].freeze + end + WidgetClassName = 'TNotebook'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end + + def enable_traversal() + if Tk::Tile::TILE_SPEC_VERSION_ID < 5 + tk_call_without_enc('::tile::enableNotebookTraversal', @path) + elsif Tk::Tile::TILE_SPEC_VERSION_ID < 7 + tk_call_without_enc('::tile::notebook::enableTraversal', @path) + else + tk_call_without_enc('::ttk::notebook::enableTraversal', @path) + end + self + end + + def add(child, keys=nil) + if keys && keys != None + tk_send_without_enc('add', _epath(child), *hash_kv(keys)) + else + tk_send_without_enc('add', _epath(child)) + end + self + end + + def forget(idx) + tk_send('forget', idx) + self + end + + def index(idx) + number(tk_send('index', idx)) + end + + def insert(idx, subwin, keys=nil) + if keys && keys != None + tk_send('insert', idx, subwin, *hash_kv(keys)) + else + tk_send('insert', idx, subwin) + end + self + end + + def select(idx) + tk_send('select', idx) + self + end + + def selected + window(tk_send_without_enc('select')) + end + + def tabs + list(tk_send('tabs')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tpaned.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tpaned.rb new file mode 100644 index 0000000000..11178b19d3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tpaned.rb @@ -0,0 +1,188 @@ +# +# tpaned widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TPaned < TkWindow + end + Paned = TPaned + end +end + +class Tk::Tile::TPaned < TkWindow + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::paned'.freeze].freeze + else + TkCommandNames = ['::tpaned'.freeze].freeze + end + WidgetClassName = 'TPaned'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end + + def add(win, keys) + win = _epath(win) + tk_send_without_enc('add', win, *hash_kv(keys)) + self + end + + def forget(pane) + pane = _epath(pane) + tk_send_without_enc('forget', pane) + self + end + + def insert(pos, win, keys) + win = _epath(win) + tk_send_without_enc('insert', pos, win, *hash_kv(keys)) + self + end + + def panecget(pane, slot) + pane = _epath(pane) + tk_tcl2ruby(tk_send_without_enc('pane', pane, "-#{slot}")) + end + alias pane_cget panecget + + def paneconfigure(pane, key, value=nil) + pane = _epath(pane) + if key.kind_of? Hash + params = [] + key.each{|k, v| + params.push("-#{k}") + # params.push((v.kind_of?(TkObject))? v.epath: v) + params.push(_epath(v)) + } + tk_send_without_enc('pane', pane, *params) + else + # value = value.epath if value.kind_of?(TkObject) + value = _epath(value) + tk_send_without_enc('pane', pane, "-#{key}", value) + end + self + end + alias pane_config paneconfigure + alias pane_configure paneconfigure + + def paneconfiginfo(win) + if TkComm::GET_CONFIGINFO_AS_ARRAY + win = _epath(win) + if key + conf = tk_split_list(tk_send_without_enc('pane', win, "-#{key}")) + conf[0] = conf[0][1..-1] + if conf[0] == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + conf[4] = bool(conf[4]) unless conf[4].empty? + end + conf + else + tk_split_simplelist(tk_send_without_enc('pane', + win)).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + if conf[3] + if conf[0] == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + elsif conf[3].index('{') + conf[3] = tk_split_list(conf[3]) + else + conf[3] = tk_tcl2ruby(conf[3]) + end + end + if conf[4] + if conf[0] == 'hide' + conf[4] = bool(conf[4]) unless conf[4].empty? + elsif conf[4].index('{') + conf[4] = tk_split_list(conf[4]) + else + conf[4] = tk_tcl2ruby(conf[4]) + end + end + conf[1] = conf[1][1..-1] if conf.size == 2 # alias info + conf + } + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + win = _epath(win) + if key + conf = tk_split_list(tk_send_without_enc('pane', win, "-#{key}")) + key = conf.shift[1..-1] + if key == 'hide' + conf[2] = bool(conf[2]) unless conf[2].empty? + conf[3] = bool(conf[3]) unless conf[3].empty? + end + { key => conf } + else + ret = {} + tk_split_simplelist(tk_send_without_enc('pane', + win)).each{|conflist| + conf = tk_split_simplelist(conflist) + key = conf.shift[1..-1] + if key + if key == 'hide' + conf[2] = bool(conf[2]) unless conf[2].empty? + elsif conf[2].index('{') + conf[2] = tk_split_list(conf[2]) + else + conf[2] = tk_tcl2ruby(conf[2]) + end + end + if conf[3] + if key == 'hide' + conf[3] = bool(conf[3]) unless conf[3].empty? + elsif 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 identify(x, y) + list(tk_send_without_enc('identify', x, y)) + end + + def sashpos(idx, newpos=None) + num_or_str(tk_send_without_enc('sashpos', idx, newpos)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tprogressbar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tprogressbar.rb new file mode 100644 index 0000000000..36c1c75c23 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tprogressbar.rb @@ -0,0 +1,53 @@ +# +# tprogressbar widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TProgressbar < TkWindow + end + Progressbar = TProgressbar + end +end + +class Tk::Tile::TProgressbar + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::progressbar'.freeze].freeze + else + TkCommandNames = ['::tprogressbar'.freeze].freeze + end + WidgetClassName = 'TProgressbar'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end + + def step(amount=None) + tk_send_without_enc('step', amount).to_f + end + #def step=(amount) + # tk_send_without_enc('step', amount) + #end + + def start(interval=None) + if Tk::Tile::TILE_SPEC_VERSION_ID < 5 + tk_call_without_enc('::tile::progressbar::start', @path, interval) + else + tk_send_without_enc('start', interval) + end + end + + def stop(amount=None) + if Tk::Tile::TILE_SPEC_VERSION_ID < 5 + tk_call_without_enc('::tile::progressbar::stop', @path) + else + tk_send_without_enc('stop', amount) + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tradiobutton.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tradiobutton.rb new file mode 100644 index 0000000000..e2f614cb97 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tradiobutton.rb @@ -0,0 +1,32 @@ +# +# tradiobutton widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TRadioButton < TkRadioButton + end + TRadiobutton = TRadioButton + RadioButton = TRadioButton + Radiobutton = TRadioButton + end +end + +class Tk::Tile::TRadioButton < TkRadioButton + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::radiobutton'.freeze].freeze + else + TkCommandNames = ['::tradiobutton'.freeze].freeze + end + WidgetClassName = 'TRadiobutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/treeview.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/treeview.rb new file mode 100644 index 0000000000..68e478896c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/treeview.rb @@ -0,0 +1,1133 @@ +# +# treeview widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class Treeview < TkWindow + end + end +end + +module Tk::Tile::TreeviewConfig + include TkItemConfigMethod + + def __item_configinfo_struct(id) + # maybe need to override + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>nil, :current_value=>1} + end + private :__item_configinfo_struct + + def __itemconfiginfo_core(tagOrId, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + fontkey = $2 + return [slot.to_s, tagfontobj(tagid(tagOrId), fontkey)] + else + if slot + slot = slot.to_s + case slot + when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/ + begin + # On tile-0.7.{2-8}, 'state' options has no '-' at its head. + val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot)) + rescue + # Maybe, 'state' option has '-' in future. + val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + end + return [slot, val] + + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] + optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + return [slot, val] + + when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] + return [slot, self.__send__(method, tagOrId)] + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + rescue + val = nil + end + return [slot, val] + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + return [slot, val] + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + rescue + val = nil + end + return [slot, val] + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + return [slot, val] + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + if val =~ /^[0-9]/ + return [slot, list(val)] + else + return [slot, val] + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + return [slot, val] + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + if val.empty? + return [slot, nil] + else + return [slot, TkVarAccess.new(val)] + end + + else + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + if val.index('{') + return [slot, tk_split_list(val)] + else + return [slot, tk_tcl2ruby(val)] + end + end + + else # ! slot + ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf| + conf[0] = conf[0][1..-1] if conf[0][0] == ?- + case conf[0] + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[conf[0]] + optval = conf[1] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[1] = val + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # do nothing + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + conf[1] = number(conf[1]) + rescue + conf[1] = nil + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + conf[1] = num_or_str(conf[1]) + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + conf[1] = bool(conf[1]) + rescue + conf[1] = nil + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + conf[1] = simplelist(conf[1]) + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + if conf[1] =~ /^[0-9]/ + conf[1] = list(conf[1]) + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + if conf[1].empty? + conf[1] = nil + else + conf[1] = TkVarAccess.new(conf[1]) + end + + else + if conf[1].index('{') + conf[1] = tk_split_list(conf[1]) + else + conf[1] = tk_tcl2ruby(conf[1]) + end + end + + conf + } + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + fontconf = ret.assoc(optkey) + if fontconf + ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} + fontconf[1] = tagfontobj(tagid(tagOrId), optkey) + ret.push(fontconf) + end + } + + __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| + ret << [optkey.to_s, self.__send__(method, tagOrId)] + } + + ret + end + end + + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + fontkey = $2 + return {slot.to_s => tagfontobj(tagid(tagOrId), fontkey)} + else + if slot + slot = slot.to_s + case slot + when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/ + begin + # On tile-0.7.{2-8}, 'state' option has no '-' at its head. + val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot)) + rescue + # Maybe, 'state' option has '-' in future. + val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + end + return {slot => val} + + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] + optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + return {slot => val} + + when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] + return {slot => self.__send__(method, tagOrId)} + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + rescue + val = nil + end + return {slot => val} + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + return {slot => val} + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + rescue + val = nil + end + return {slot => val} + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) + return {slot => val} + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + if val =~ /^[0-9]/ + return {slot => list(val)} + else + return {slot => val} + end + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + return {slot => val} + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + if val.empty? + return {slot => nil} + else + return {slot => TkVarAccess.new(val)} + end + + else + val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) + if val.index('{') + return {slot => tk_split_list(val)} + else + return {slot => tk_tcl2ruby(val)} + end + end + + else # ! slot + ret = {} + ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf| + conf[0] = conf[0][1..-1] if conf[0][0] == ?- + + optkey = conf[0] + case optkey + when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ + method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey] + optval = conf[1] + begin + val = method.call(tagOrId, optval) + rescue => e + warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG + val = optval + end + conf[1] = val + + when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ + # do nothing + + when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + conf[1] = number(conf[1]) + rescue + conf[1] = nil + end + + when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ + conf[1] = num_or_str(conf[1]) + + when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ + begin + conf[1] = bool(conf[1]) + rescue + conf[1] = nil + end + + when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ + conf[1] = simplelist(conf[1]) + + when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ + if conf[1] =~ /^[0-9]/ + conf[1] = list(conf[1]) + end + + when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ + if conf[1].empty? + conf[1] = nil + else + conf[1] = TkVarAccess.new(conf[1]) + end + + else + if conf[1].index('{') + return [slot, tk_split_list(conf[1])] + else + return [slot, tk_tcl2ruby(conf[1])] + end + end + + ret[conf[0]] = conf[1] + } + + __item_font_optkeys(tagid(tagOrId)).each{|optkey| + optkey = optkey.to_s + fontconf = ret[optkey] + if fontconf.kind_of?(Array) + ret.delete(optkey) + ret.delete('latin' << optkey) + ret.delete('ascii' << optkey) + ret.delete('kanji' << optkey) + fontconf[1] = tagfontobj(tagid(tagOrId), optkey) + ret[optkey] = fontconf + end + } + + __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| + ret[optkey.to_s] = self.__send__(method, tagOrId) + } + + ret + end + end + end + end + + ################### + + def __item_cget_cmd(id) + [self.path, id[0], id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, id[0], id[1]] + end + private :__item_config_cmd + + def __item_numstrval_optkeys(id) + case id[0] + when :item, 'item' + ['width'] + when :column, 'column' + super(id[1]) + when :tag, 'tag' + super(id[1]) + when :heading, 'heading' + super(id[1]) + else + super(id[1]) + end + end + private :__item_numstrval_optkeys + + def __item_strval_optkeys(id) + case id[0] + when :item, 'item' + super(id) + ['id'] + when :column, 'column' + super(id[1]) + when :tag, 'tag' + super(id[1]) + when :heading, 'heading' + super(id[1]) + else + super(id[1]) + end + end + private :__item_strval_optkeys + + def __item_boolval_optkeys(id) + case id[0] + when :item, 'item' + ['open'] + when :column, 'column' + super(id[1]) + when :tag, 'tag' + super(id[1]) + when :heading, 'heading' + super(id[1]) + end + end + private :__item_boolval_optkeys + + def __item_listval_optkeys(id) + case id[0] + when :item, 'item' + ['values'] + when :column, 'column' + [] + when :heading, 'heading' + [] + else + [] + end + end + private :__item_listval_optkeys + + def __item_val2ruby_optkeys(id) + case id[0] + when :item, 'item' + { + 'tags'=>proc{|arg_id, val| + simplelist(val).collect{|tag| + Tk::Tile::Treeview::Tag.id2obj(self, tag) + } + } + } + when :column, 'column' + {} + when :heading, 'heading' + {} + else + {} + end + end + private :__item_val2ruby_optkeys + + def __tile_specific_item_optkeys(id) + case id[0] + when :item, 'item' + [] + when :column, 'column' + [] + when :heading, 'heading' + ['state'] # On tile-0.7.{2-8}, 'state' options has no '-' at its head. + else + [] + end + end + private :__item_val2ruby_optkeys + + def itemconfiginfo(tagOrId, slot = nil) + __itemconfiginfo_core(tagOrId, slot) + end + + def current_itemconfiginfo(tagOrId, slot = nil) + if TkComm::GET_CONFIGINFO_AS_ARRAY + if slot + org_slot = slot + begin + conf = __itemconfiginfo_core(tagOrId, slot) + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + return {conf[0] => conf[-1]} + end + slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] + end while(org_slot != slot) + fail RuntimeError, + "there is a configure alias loop about '#{org_slot}'" + else + ret = {} + __itemconfiginfo_core(tagOrId).each{|conf| + if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ + || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) + ret[conf[0]] = conf[-1] + end + } + ret + end + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + ret = {} + __itemconfiginfo_core(tagOrId, slot).each{|key, conf| + ret[key] = conf[-1] if conf.kind_of?(Array) + } + ret + end + end + + alias __itemcget itemcget + alias __itemconfigure itemconfigure + alias __itemconfiginfo itemconfiginfo + alias __current_itemconfiginfo current_itemconfiginfo + + private :__itemcget, :__itemconfigure + private :__itemconfiginfo, :__current_itemconfiginfo + + # Treeview Item + def itemcget(tagOrId, option) + __itemcget([:item, tagOrId], option) + end + def itemconfigure(tagOrId, slot, value=None) + __itemconfigure([:item, tagOrId], slot, value) + end + def itemconfiginfo(tagOrId, slot=nil) + __itemconfiginfo([:item, tagOrId], slot) + end + def current_itemconfiginfo(tagOrId, slot=nil) + __current_itemconfiginfo([:item, tagOrId], slot) + end + + # Treeview Column + def columncget(tagOrId, option) + __itemcget([:column, tagOrId], option) + end + def columnconfigure(tagOrId, slot, value=None) + __itemconfigure([:column, tagOrId], slot, value) + end + def columnconfiginfo(tagOrId, slot=nil) + __itemconfiginfo([:column, tagOrId], slot) + end + def current_columnconfiginfo(tagOrId, slot=nil) + __current_itemconfiginfo([:column, tagOrId], slot) + end + alias column_cget columncget + alias column_configure columnconfigure + alias column_configinfo columnconfiginfo + alias current_column_configinfo current_columnconfiginfo + + # Treeview Heading + def headingcget(tagOrId, option) + if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s) + begin + # On tile-0.7.{2-8}, 'state' options has no '-' at its head. + tk_call(*(__item_cget_cmd([:heading, tagOrId]) << option.to_s)) + rescue + # Maybe, 'state' option has '-' in future. + tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{option}")) + end + else + __itemcget([:heading, tagOrId], option) + end + end + def headingconfigure(tagOrId, slot, value=None) + if slot.kind_of?(Hash) + slot = _symbolkey2str(slot) + sp_kv = [] + __tile_specific_item_optkeys([:heading, tagOrId]).each{|k| + sp_kv << k << _get_eval_string(slot.delete(k)) if slot.has_key?(k) + } + tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(sp_kv))) + tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(hash_kv(slot)))) + elsif __tile_specific_item_optkeys([:heading, tagOrId]).index(slot.to_s) + begin + # On tile-0.7.{2-8}, 'state' options has no '-' at its head. + tk_call(*(__item_cget_cmd([:heading, tagOrId]) << slot.to_s << value)) + rescue + # Maybe, 'state' option has '-' in future. + tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{slot}" << value)) + end + else + __itemconfigure([:heading, tagOrId], slot, value) + end + self + end + def headingconfiginfo(tagOrId, slot=nil) + __itemconfiginfo([:heading, tagOrId], slot) + end + def current_headingconfiginfo(tagOrId, slot=nil) + __current_itemconfiginfo([:heading, tagOrId], slot) + end + alias heading_cget headingcget + alias heading_configure headingconfigure + alias heading_configinfo headingconfiginfo + alias current_heading_configinfo current_headingconfiginfo + + # Treeview Tag + def tagcget(tagOrId, option) + __itemcget([:tag, tagOrId], option) + end + def tagconfigure(tagOrId, slot, value=None) + __itemconfigure([:tag, tagOrId], slot, value) + end + def tagconfiginfo(tagOrId, slot=nil) + __itemconfiginfo([:tag, tagOrId], slot) + end + def current_tagconfiginfo(tagOrId, slot=nil) + __current_itemconfiginfo([:tag, tagOrId], slot) + end + alias tag_cget tagcget + alias tag_configure tagconfigure + alias tag_configinfo tagconfiginfo + alias current_tag_configinfo current_tagconfiginfo +end + +######################## + +class Tk::Tile::Treeview::Item < TkObject + ItemID_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ Tk::Tile::Treeview::Item::ItemID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless Tk::Tile::Treeview::Item::ItemID_TBL[tpath] + (Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id])? \ + Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]: id + end + + def self.assign(tree, id) + tpath = tree.path + if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] && + Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] + return Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] + end + + obj = self.allocate + obj.instance_eval{ + @parent = @t = tree + @tpath = tpath + @path = @id = id + } + ItemID_TBL[tpath] = {} unless ItemID_TBL[tpath] + Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] = obj + obj + end + + def _insert_item(tree, parent_item, idx, keys={}) + keys = _symbolkey2str(keys) + id = keys.delete('id') + if id + num_or_str(tk_call(tree, 'insert', + parent_item, idx, '-id', id, *hash_kv(keys))) + else + num_or_str(tk_call(tree, 'insert', parent_item, idx, *hash_kv(keys))) + end + end + private :_insert_item + + def initialize(tree, parent_item = '', idx = 'end', keys = {}) + if parent_item.kind_of?(Hash) + keys = parent_item + idx = 'end' + parent_item = '' + elsif idx.kind_of?(Hash) + keys = idx + idx = 'end' + end + + @parent = @t = tree + @tpath = tree.path + @path = @id = _insert_item(@t, parent_item, idx, keys) + ItemID_TBL[@tpath] = {} unless ItemID_TBL[@tpath] + ItemID_TBL[@tpath][@id] = self + end + def id + @id + end + + def cget(option) + @t.itemcget(@id, option) + end + + def configure(key, value=None) + @t.itemconfigure(@id, key, value) + self + end + + def configinfo(key=nil) + @t.itemconfiginfo(@id, key) + end + + def current_configinfo(key=nil) + @t.current_itemconfiginfo(@id, key) + end + + def open? + cget('open') + end + def open + configure('open', true) + self + end + def close + configure('open', false) + self + end + + def bbox(column=None) + @t.bbox(@id, column) + end + + def children + @t.children(@id) + end + def set_children(*items) + @t.set_children(@id, *items) + self + end + + def delete + @t.delete(@id) + self + end + + def detach + @t.detach(@id) + self + end + + def exist? + @t.exist?(@id) + end + + def focus + @t.focus_item(@id) + end + + def index + @t.index(@id) + end + + def insert(idx='end', keys={}) + @t.insert(@id, idx, keys) + end + + def move(parent, idx) + @t.move(@id, parent, idx) + self + end + + def next_item + @t.next_item(@id) + end + + def parent_item + @t.parent_item(@id) + end + + def prev_item + @t.prev_item(@id) + end + + def see + @t.see(@id) + self + end + + def selection_add + @t.selection_add(@id) + self + end + + def selection_remove + @t.selection_remove(@id) + self + end + + def selection_set + @t.selection_set(@id) + self + end + + def selection_toggle + @t.selection_toggle(@id) + self + end + + def get_directory + @t.get_directory(@id) + end + alias get_dictionary get_directory + + def get(col) + @t.get(@id, col) + end + + def set(col, value) + @t.set(@id, col, value) + end +end + +######################## + +class Tk::Tile::Treeview::Root < Tk::Tile::Treeview::Item + def self.new(tree, keys = {}) + tpath = tree.path + if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] && + Tk::Tile::Treeview::Item::ItemID_TBL[tpath][''] + Tk::Tile::Treeview::Item::ItemID_TBL[tpath][''] + else + super(tree, keys) + end + end + + def initialize(tree, keys = {}) + @parent = @t = tree + @tpath = tree.path + @path = @id = '' + unless Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] + Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] = {} + end + Tk::Tile::Treeview::Item::ItemID_TBL[@tpath][@id] = self + end +end + +######################## + +class Tk::Tile::Treeview::Tag < TkObject + include TkTreatTagFont + + TagID_TBL = TkCore::INTERP.create_table + Tag_ID = ['tile_treeview_tag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ Tk::Tile::Treeview::Tag::TagID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless Tk::Tile::Treeview::Tag::TagID_TBL[tpath] + (Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id])? \ + Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id]: id + end + + def initialize(tree, keys=nil) + @parent = @t = tree + @tpath = tree.path + @path = @id = Tag_ID.join(TkCore::INTERP._ip_id_) + TagID_TBL[@tpath] = {} unless TagID_TBL[@tpath] + TagID_TBL[@tpath][@id] = self + Tag_ID[1].succ! + if keys && keys != None + tk_call_without_enc(@tpath, 'tag', 'configure', *hash_kv(keys, true)) + end + end + def id + @id + end + + def bind(seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @t.tag_bind(@id, seq, cmd, *args) + self + end + + def bind_append(seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + @t.tag_bind_append(@id, seq, cmd, *args) + self + end + + def bind_remove(seq) + @t.tag_bind_remove(@id, seq) + self + end + + def bindinfo(seq=nil) + @t.tag_bindinfo(@id, seq) + end + + def cget(option) + @t.tagcget(@id, option) + end + + def configure(key, value=None) + @t.tagconfigure(@id, key, value) + self + end + + def configinfo(key=nil) + @t.tagconfiginfo(@id, key) + end + + def current_configinfo(key=nil) + @t.current_tagconfiginfo(@id, key) + end +end + +######################## + +class Tk::Tile::Treeview < TkWindow + include Tk::Tile::TileWidget + include Scrollable + + include Tk::Tile::TreeviewConfig + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::treeview'.freeze].freeze + else + TkCommandNames = ['::treeview'.freeze].freeze + end + WidgetClassName = 'Treeview'.freeze + WidgetClassNames[WidgetClassName] = self + + def __destroy_hook__ + Tk::Tile::Treeview::Item::ItemID_TBL.delete(@path) + Tk::Tile::Treeview::Tag::ItemID_TBL.delete(@path) + end + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end + + def tagid(id) + if id.kind_of?(Tk::Tile::Treeview::Item) || + id.kind_of?(Tk::Tile::Treeview::Tag) + id.id + elsif id.kind_of?(Array) + [id[0], _get_eval_string(id[1])] + else + _get_eval_string(id) + end + end + + def root + Tk::Tile::Treeview::Root.new(self) + end + + def bbox(item, column=None) + list(tk_send('item', 'bbox', item, column)) + end + + def children(item) + simplelist(tk_send_without_enc('children', item)).collect{|id| + Tk::Tile::Treeview::Item.id2obj(self, id) + } + end + def set_children(item, *items) + tk_send_without_enc('children', item, + array2tk_list(items.flatten, true)) + self + end + + def delete(*items) + tk_send_without_enc('delete', array2tk_list(items.flatten, true)) + self + end + + def detach(*items) + tk_send_without_enc('detach', array2tk_list(items.flatten, true)) + self + end + + def exist?(item) + bool(tk_send_without_enc('exists', _get_eval_enc_str(item))) + end + + def focus_item(item = nil) + if item + tk_send('focus', item) + item + else + id = tk_send('focus') + (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) + end + end + + def identify(x, y) + # tile-0.7.2 or previous + ret = simplelist(tk_send('identify', x, y)) + case ret[0] + when 'heading', 'separator' + ret[-1] = num_or_str(ret[-1]) + when 'cell' + ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1]) + ret[-1] = num_or_str(ret[-1]) + when 'item', 'row' + ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1]) + end + end + + def row_identify(x, y) + id = tk_send('identify', 'row', x, y) + (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) + end + + def column_identify(x, y) + tk_send('identify', 'column', x, y) + end + + def index(item) + number(tk_send('index', item)) + end + + # def insert(parent, idx='end', keys={}) + # keys = _symbolkey2str(keys) + # id = keys.delete('id') + # if id + # num_or_str(tk_send('insert', parent, idx, '-id', id, *hash_kv(keys))) + # else + # num_or_str(tk_send('insert', parent, idx, *hash_kv(keys))) + # end + # end + def insert(parent, idx='end', keys={}) + Tk::Tile::Treeview::Item.new(self, parent, idx, keys) + end + + # def instate(spec, cmd=Proc.new) + # tk_send('instate', spec, cmd) + # end + # def state(spec=None) + # tk_send('state', spec) + # end + + def move(item, parent, idx) + tk_send('move', item, parent, idx) + self + end + + def next_item(item) + id = tk_send('next', item) + (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) + end + + def parent_item(item) + if (id = tk_send('parent', item)).empty? + Tk::Tile::Treeview::Root.new(self) + else + Tk::Tile::Treeview::Item.id2obj(self, id) + end + end + + def prev_item(item) + id = tk_send('prev', item) + (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) + end + + def see(item) + tk_send('see', item) + self + end + + def selection + simplelist(tk_send('selection')).collect{|id| + Tk::Tile::Treeview::Item.id2obj(self, id) + } + end + alias selection_get selection + + def selection_add(*items) + tk_send('selection', 'add', array2tk_list(items.flatten, true)) + self + end + def selection_remove(*items) + tk_send('selection', 'remove', array2tk_list(items.flatten, true)) + self + end + def selection_set(*items) + tk_send('selection', 'set', array2tk_list(items.flatten, true)) + self + end + def selection_toggle(*items) + tk_send('selection', 'toggle', array2tk_list(items.flatten, true)) + self + end + + def get_directory(item) + # tile-0.7+ + ret = [] + lst = simplelist(tk_send('set', item)) + until lst.empty? + col = lst.shift + val = lst.shift + ret << [col, val] + end + ret + end + alias get_dictionary get_directory + + def get(item, col) + tk_send('set', item, col) + end + def set(item, col, value) + tk_send('set', item, col, value) + self + end + + def tag_bind(tag, seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + alias tagbind tag_bind + + def tag_bind_append(tag, seq, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) + self + end + alias tagbind_append tag_bind_append + + def tag_bind_remove(tag, seq) + _bind_remove([@path, 'tag', 'bind', tag], seq) + self + end + alias tagbind_remove tag_bind_remove + + def tag_bindinfo(tag, context=nil) + _bindinfo([@path, 'tag', 'bind', tag], context) + end + alias tagbindinfo tag_bindinfo +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tscale.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tscale.rb new file mode 100644 index 0000000000..7ec72e3515 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tscale.rb @@ -0,0 +1,50 @@ +# +# tscale & tprogress widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TScale < TkScale + end + Scale = TScale + + class TProgress < TScale + end + Progress = TProgress + end +end + +class Tk::Tile::TScale < TkScale + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::scale'.freeze].freeze + else + TkCommandNames = ['::tscale'.freeze].freeze + end + WidgetClassName = 'TScale'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end + +class Tk::Tile::TProgress < Tk::Tile::TScale + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::progress'.freeze].freeze + else + TkCommandNames = ['::tprogress'.freeze].freeze + end + WidgetClassName = 'TProgress'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tscrollbar.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tscrollbar.rb new file mode 100644 index 0000000000..bd49ae18e3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tscrollbar.rb @@ -0,0 +1,30 @@ +# +# tscrollbar widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TScrollbar < TkScrollbar + end + Scrollbar = TScrollbar + end +end + +class Tk::Tile::TScrollbar < TkScrollbar + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::scrollbar'.freeze].freeze + else + TkCommandNames = ['::tscrollbar'.freeze].freeze + end + WidgetClassName = 'TScrollbar'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tseparator.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tseparator.rb new file mode 100644 index 0000000000..ca731d4e5b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tseparator.rb @@ -0,0 +1,30 @@ +# +# tseparator widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TSeparator < TkWindow + end + Separator = TSeparator + end +end + +class Tk::Tile::TSeparator < TkWindow + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::separator'.freeze].freeze + else + TkCommandNames = ['::tseparator'.freeze].freeze + end + WidgetClassName = 'TSeparator'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tsquare.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tsquare.rb new file mode 100644 index 0000000000..600b55e4e7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tile/tsquare.rb @@ -0,0 +1,30 @@ +# +# tsquare widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tkextlib/tile.rb' + +module Tk + module Tile + class TSquare < TkWindow + end + Square = TSquare + end +end + +class Tk::Tile::TSquare < TkWindow + include Tk::Tile::TileWidget + + if Tk::Tile::USE_TTK_NAMESPACE + TkCommandNames = ['::ttk::square'.freeze].freeze + else + TkCommandNames = ['::tsquare'.freeze].freeze + end + WidgetClassName = 'TSquare'.freeze + WidgetClassNames[WidgetClassName] = self + + def self.style(*args) + [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND.rb new file mode 100644 index 0000000000..5d52e34418 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND.rb @@ -0,0 +1,18 @@ +# +# TkDND (Tk Drag & Drop Extension) support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkDND/setup.rb' + +module Tk + module TkDND + autoload :DND, 'tkextlib/tkDND/tkdnd' + autoload :Shape, 'tkextlib/tkDND/shape' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/shape.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/shape.rb new file mode 100644 index 0000000000..570c93b0d9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/shape.rb @@ -0,0 +1,123 @@ +# +# tkextlib/tkDND/shape.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkDND/setup.rb' + +# TkPackage.require('shape', '0.3') +TkPackage.require('shape') + +module Tk + module TkDND + module Shape + extend TkCore + + PACKAGE_NAME = 'shape'.freeze + def self.package_name + PACKAGE_NAME + end + +=begin + def self.package_version + begin + TkPackage.require('shape') + rescue + '' + end + end +=end + def self.package_version + Tk.tk_call('set', 'shape_version') + end + alias shape_version package_version + + def self.package_patchlevel + Tk.tk_call('set', 'shape_patchlevel') + end + alias shape_patchlevel package_patchlevel + + def self.version + tk_call('shape', 'version') + end + alias xshape_version version + + ############################ + + def shape_bounds(kind=nil) + if kind + ret = tk_call('shape', 'bounds', @path, "-#{kind}") + else + ret = tk_call('shape', 'bounds', @path) + end + if ret == "" + nil + else + list(ret) + end + end + + def shape_get(kind=nil) + if kind + list(tk_call('shape', 'get', @path, "-#{kind}")) + else + list(tk_call('shape', 'get', @path)) + end + end + + def shape_offset(x, y, kind=nil) + if kind + tk_call('shape', 'get', @path, "-#{kind}", x, y) + else + tk_call('shape', 'get', @path, x, y) + end + self + end + + def _parse_shapespec_param(args) + cmd = [] + + kind_keys = ['bounding', 'clip', 'both'] + offset_keys = ['offset'] + srckind_keys = ['bitmap', 'rectangles', 'reset', 'test', 'window'] + + cmd << "-#{args.shift}" if kind_keys.member?(args[0].to_s) + + if offset_keys.member?(args[0].to_s) + cmd << "-#{args.shift}" + cmd << args.shift # xOffset + cmd << args.shift # yOffset + end + + if srckind_keys.member?(args[0].to_s) + cmd << "-#{args.shift}" + end + + cmd.concat(args) + + cmd + end + private :_parse_shapespec_param + + def shape_set(*args) # ?kind? ?offset <x> <y>? srckind ?arg ...? + tk_call('shape', 'set', @path, *(_parse_shapespec_param(args))) + self + end + + def shape_update(op, *args) # ?kind? ?offset <x> <y>? srckind ?arg ...? + tk_call('shape', 'update', @path, op, *(_parse_shapespec_param(args))) + self + end + end + end +end + +class TkWindow + include Tk::TkDND::Shape +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/tkdnd.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/tkdnd.rb new file mode 100644 index 0000000000..a040532eb6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkDND/tkdnd.rb @@ -0,0 +1,164 @@ +# +# tkextlib/tkDND/tkdnd.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkDND/setup.rb' + +TkPackage.require('tkdnd') + +module Tk + module TkDND + PACKAGE_NAME = 'tkdnd'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('tkdnd') + rescue + '' + end + end + + class DND_Subst < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?a, ?l, :actions ], + [ ?A, ?s, :action ], + [ ?b, ?L, :codes ], + [ ?c, ?s, :code ], + [ ?d, ?l, :descriptions ], + [ ?D, ?l, :data ], + [ ?L, ?l, :source_types ], + [ ?m, ?l, :modifiers ], + [ ?t, ?l, :types ], + [ ?T, ?s, :type ], + [ ?W, ?w, :widget ], + [ ?x, ?n, :x ], + [ ?X, ?n, :x_root ], + [ ?y, ?n, :y ], + [ ?Y, ?n, :y_root ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?l, TkComm.method(:list) ], + [ ?L, TkComm.method(:simplelist) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + # setup tables + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + module DND + def self.version + begin + TkPackage.require('tkdnd') + rescue + '' + end + end + + def dnd_bindtarget_info(type=nil, event=nil) + if event + procedure(tk_call('dnd', 'bindtarget', @path, type, event)) + elsif type + procedure(tk_call('dnd', 'bindtarget', @path, type)) + else + simplelist(tk_call('dnd', 'bindtarget', @path)) + end + end + + #def dnd_bindtarget(type, event, cmd=Proc.new, prior=50, *args) + # event = tk_event_sequence(event) + # if prior.kind_of?(Numeric) + # tk_call('dnd', 'bindtarget', @path, type, event, + # install_bind_for_event_class(DND_Subst, cmd, *args), + # prior) + # else + # tk_call('dnd', 'bindtarget', @path, type, event, + # install_bind_for_event_class(DND_Subst, cmd, prior, *args)) + # end + # self + #end + def dnd_bindtarget(type, event, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + + prior = 50 + prior = args.shift unless args.empty? + + event = tk_event_sequence(event) + if prior.kind_of?(Numeric) + tk_call('dnd', 'bindtarget', @path, type, event, + install_bind_for_event_class(DND_Subst, cmd, *args), + prior) + else + tk_call('dnd', 'bindtarget', @path, type, event, + install_bind_for_event_class(DND_Subst, cmd, prior, *args)) + end + self + end + + def dnd_cleartarget + tk_call('dnd', 'cleartarget', @path) + self + end + + def dnd_bindsource_info(type=nil) + if type + procedure(tk_call('dnd', 'bindsource', @path, type)) + else + simplelist(tk_call('dnd', 'bindsource', @path)) + end + end + + #def dnd_bindsource(type, cmd=Proc.new, prior=None) + # tk_call('dnd', 'bindsource', @path, type, cmd, prior) + # self + #end + def dnd_bindsource(type, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + + args = [None] if args.empty + + tk_call('dnd', 'bindsource', @path, type, cmd, *args) + self + end + + def dnd_clearsource() + tk_call('dnd', 'clearsource', @path) + self + end + + def dnd_drag(keys=nil) + tk_call('dnd', 'drag', @path, *hash_kv(keys)) + self + end + end + end +end + +class TkWindow + include Tk::TkDND::DND +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML.rb new file mode 100644 index 0000000000..5fddde72ff --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML.rb @@ -0,0 +1,13 @@ +# +# TkHtml support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkHTML/setup.rb' + +# load library +require 'tkextlib/tkHTML/htmlwidget' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb new file mode 100644 index 0000000000..8527f61df1 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb @@ -0,0 +1,444 @@ +# +# tkextlib/tkHTML/htmlwidget.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkHTML/setup.rb' + +# TkPackage.require('Tkhtml', '2.0') +TkPackage.require('Tkhtml') + +module Tk + class HTML_Widget < TkWindow + PACKAGE_NAME = 'Tkhtml'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Tkhtml') + rescue + '' + end + end + + class ClippingWindow < TkWindow + end + end +end + +class Tk::HTML_Widget::ClippingWindow + WidgetClassName = 'HtmlClip'.freeze + WidgetClassNames[WidgetClassName] = self + + HtmlClip_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ HtmlClip_TBL.clear } + + def self.new(parent, keys={}) + if parent.kind_of?(Hash) + keys = TkComm._symbolkey2str(parent) + parent = keys.delete('parent') + end + + if parent.kind_of?(String) + ppath = parent.path + elsif parent + ppath = parent + else + ppath = '' + end + return HtmlClip_TBL[ppath] if HtmlClip_TBL[ppath] + + widgetname = keys.delete('widgetname') + if widgetname =~ /^(.*)\.[^.]+$/ + ppath2 = $1 + if ppath2[0] != ?. + ppath2 = ppath + '.' + ppath2 + end + return HtmlClip_TBL[ppath2] if HtmlClip_TBL[ppath2] + + ppath = ppath2 + end + + parent = TkComm._genobj_for_tkwidget(ppath) + unless parent.kind_of?(Tk::HTML_Widget) + fail ArgumentError, "parent must be a Tk::HTML_Widget instance" + end + + super(parent) + end + + def initialize(parent) + @parent = parent + @ppath = parent.path + @path = @id = @ppath + '.x' + HtmlClip_TBL[@ppath] = self + end + + def method_missing(m, *args, &b) + @parent.__send__(m, *args, &b) + end +end + +class Tk::HTML_Widget + include Scrollable + + TkCommandNames = ['html'.freeze].freeze + WidgetClassName = 'Html'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + def __strval_optkeys + super() << 'base' << 'selectioncolor' << 'unvisitedcolor' << 'visitedcolor' + end + private :__strval_optkeys + + ################################### + # class methods + ################################### + def self.reformat(src, dst, txt) + tk_call('html', 'reformat', src, dst, txt) + end + + def self.url_join(*args) # args := sheme authority path query fragment + tk_call('html', 'urljoin', *args) + end + + def self.url_split(uri) + tk_call('html', 'urlsplit', uri) + end + + def self.lockcopy(src, dst) + tk_call('html', 'lockcopy', src, dst) + end + + def self.gzip_file(file, dat) + tk_call('html', 'gzip', 'file', file, dat) + end + + def self.gunzip_file(file, dat) + tk_call('html', 'gunzip', 'file', filet) + end + + def self.gzip_data(dat) + tk_call('html', 'gzip', 'data', file, dat) + end + + def self.gunzip_data(dat) + tk_call('html', 'gunzip', 'data', filet) + end + + def self.base64_encode(dat) + tk_call('html', 'base64', 'encode', dat) + end + + def self.base64_decode(dat) + tk_call('html', 'base64', 'encode', dat) + end + + def self.text_format(dat, len) + tk_call('html', 'text', 'format', dat, len) + end + + def self.xor(cmd, *args) + tk_call('html', 'xor', cmd, *args) + end + + def self.stdchan(cmd, channel) + tk_call('html', 'stdchan', cmd, channel) + end + + def self.crc32(data) + tk_call('html', 'crc32', data) + end + + ################################### + # instance methods + ################################### + def clipping_window + ClippingWindow.new(self) + end + alias clipwin clipping_window + alias htmlclip clipping_window + + def bgimage(image, tid=None) + tk_send('bgimage', image, tid) + self + end + + def clear() + tk_send('clear') + self + end + + def coords(index=None, percent=None) + tk_send('coords', index, percent) + end + + def forminfo(*args) + tk_send('forminfo', *args) + end + alias form_info forminfo + + def href(x, y) + simplelist(tk_send('href', x, y)) + end + + def image_add(id, img) + tk_send('imageadd', id, img) + self + end + + def image_at(x, y) + tk_send('imageat', x, y) + end + + def images() + list(tk_send('images')) + end + + def image_set(id, num) + tk_send('imageset', id, num) + self + end + + def image_update(id, imgs) + tk_send('imageupdate', id, imgs) + self + end + + def index(idx, count=None, unit=None) + tk_send('index', idx, count, unit) + end + + def insert_cursor(idx) + tk_send('insert', idx) + end + + def names() + simple_list(tk_send('names')) + end + + def on_screen(id, x, y) + bool(tk_send('onscreen', id, x, y)) + end + + def over(x, y) + list(tk_send('over', x, y)) + end + + def over_markup(x, y) + list(tk_send('over', x, y, '-muponly')) + end + + def over_attr(x, y, attrs) + list(tk_send('overattr', x, y, attrs)) + end + + def parse(txt) + tk_send('parse', txt) + self + end + + def resolver(*uri_args) + tk_send('resolver', *uri_args) + end + + def selection_clear() + tk_send('selection', 'clear') + self + end + + def selection_set(first, last) + tk_send('selection', 'set', first, last) + self + end + + def refresh(*opts) + tk_send('refresh', *opts) + end + + def layout() + tk_send('layout') + end + + def sizewindow(*args) + tk_send('sizewindow', *args) + end + + def postscript(*args) + tk_send('postscript', *args) + end + + def source() + tk_send('source') + end + + def plain_text(first, last) + tk_send('text', 'ascii', first, last) + end + alias ascii_text plain_text + alias text_ascii plain_text + + def text_delete(first, last) + tk_send('text', 'delete', first, last) + self + end + + def html_text(first, last) + tk_send('text', 'html', first, last) + end + alias text_html html_text + + def text_insert(idx, txt) + tk_send('text', 'insert', idx, txt) + self + end + + def break_text(idx) + tk_send('text', 'break', idx) + end + alias text_break break_text + + def text_find(txt, *args) + tk_send('text', 'find', txt, *args) + end + + def text_table(idx, imgs=None, attrs=None) + tk_send('text', 'table', idx, imgs, attrs) + end + + def token_append(tag, *args) + tk_send('token', 'append', tag, *args) + self + end + + def token_delete(first, last=None) + tk_send('token', 'delete', first, last) + self + end + + def token_define(*args) + tk_send('token', 'defile', *args) + self + end + + def token_find(tag, *args) + list(tk_send('token', 'find', tag, *args)) + end + + def token_get(first, last=None) + list(tk_send('token', 'get', first, last)) + end + + def token_list(first, last=None) + list(tk_send('token', 'list', first, last)) + end + + def token_markup(first, last=None) + list(tk_send('token', 'markup', first, last)) + end + + def token_DOM(first, last=None) + list(tk_send('token', 'domtokens', first, last)) + end + alias token_dom token_DOM + alias token_domtokens token_DOM + alias token_dom_tokens token_DOM + + def token_get_end(idx) + tk_send('token', 'getend', idx) + end + alias token_getend token_get_end + + def token_offset(start, num1, num2) + list(tk_send('token', 'offset', start, num1, num2)) + end + + def token_get_attr(idx, name=None) + list(tk_send('token', 'attr', idx, name)) + end + + def token_set_attr(idx, name=None, val=None) + tk_send('token', 'attr', idx, name, val) + self + end + + def token_handler(tag, cmd=nil, &b) + cmd = Proc.new(&b) if !cmd && b + if cmd + tk_send('token', 'handler', tag, cmd) + return self + else + return tk_send('token', 'handler', tag) + end + end + + def token_insert(idx, tag, *args) + tk_send('token', 'insert', idx, tag, *args) + self + end + + def token_attrs(*args) + list(tk_send('token', 'attrs', *args)) + end + + def token_unique(*args) + list(tk_send('token', 'unique', *args)) + end + + def token_on_events(*args) + list(tk_send('token', 'onEvents', *args)) + end + + def dom_nameidx(tag, name) + number(tk_send('dom', 'nameidx', tag, name)) + end + alias dom_name_index dom_nameidx + + def dom_radioidx(tag, name) + number(tk_send('dom', 'radioidx', tag, name)) + end + alias dom_radio_index dom_radioidx + + def dom_id(*spec) + tk_send('dom', 'id', *spec) + end + + def dom_ids(*spec) + list(tk_send('dom', 'ids', *spec)) + end + + def dom_value(*spec) + list(tk_send('dom', 'value', *spec)) + end + + def dom_attr(idx) + tk_send('dom', 'attr', idx) + end + + def dom_formel(name) + tk_send('dom', 'formel', name) + end + alias dom_form_element dom_formel + + def dom_tree(idx, val) + list(tk_send('dom', 'tree', idx, val)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkHTML/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg.rb new file mode 100644 index 0000000000..c01359d3ef --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg.rb @@ -0,0 +1,36 @@ +# +# TkImg extension support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# load all image format handlers +#TkPackage.require('Img', '1.3') +TkPackage.require('Img') + +module Tk + module Img + PACKAGE_NAME = 'Img'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Img') + rescue + '' + end + end + end +end + +# autoload +autoload :TkPixmapImage, 'tkextlib/tkimg/pixmap' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/README b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/README new file mode 100644 index 0000000000..65d36365d0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/README @@ -0,0 +1,26 @@ + + [ Tcl/Tk Image formats (TkImg) support ] + +TkImg contains a collection of format handlers for the Tk photo +image type, and a new image type, pixmaps. + +Supported formats of TkImg version 1.3 are +------------------------------------------------------- + bmp : Windows Bitmap Format + gif : Graphics Interchange Format + ico : Windows Icon Format + jpeg : Joint Picture Expert Group format + pcx : Paintbrush Format + pixmap : Pixmap Image type + png : Portable Network Graphics format + ppm : Portable Pixmap format + ps : Adobe PostScript Format + sgi : SGI Native Format + sun : Sun Raster Format + tga : Truevision Targa Format + tiff : Tagged Image File Format + window : Tk Windows + xbm : X Window Bitmap Format + xpm : X Window Pixmap Format +------------------------------------------------------- + diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/bmp.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/bmp.rb new file mode 100644 index 0000000000..ea90181aa3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/bmp.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'bmp' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +#TkPackage.require('img::bmp', '1.3') +TkPackage.require('img::bmp') + +module Tk + module Img + module BMP + PACKAGE_NAME = 'img::bmp'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::bmp') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/gif.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/gif.rb new file mode 100644 index 0000000000..d542d47561 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/gif.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'gif' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::gif', '1.3') +TkPackage.require('img::gif') + +module Tk + module Img + module GIF + PACKAGE_NAME = 'img::gif'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::gif') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ico.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ico.rb new file mode 100644 index 0000000000..e79bdf45e9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ico.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'ico' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::ico', '1.3') +TkPackage.require('img::ico') + +module Tk + module Img + module ICO + PACKAGE_NAME = 'img::ico'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::ico') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/jpeg.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/jpeg.rb new file mode 100644 index 0000000000..2126120161 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/jpeg.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'jpeg' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::jpeg', '1.3') +TkPackage.require('img::jpeg') + +module Tk + module Img + module JPEG + PACKAGE_NAME = 'img::jpeg'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::jpeg') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/pcx.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/pcx.rb new file mode 100644 index 0000000000..6831f4d35b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/pcx.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'pcx' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::pcx', '1.3') +TkPackage.require('img::pcx') + +module Tk + module Img + module PCX + PACKAGE_NAME = 'img::pcx'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::pcx') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/pixmap.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/pixmap.rb new file mode 100644 index 0000000000..bd1b870af7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/pixmap.rb @@ -0,0 +1,44 @@ +# +# TkImg - format 'pixmap' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::pixmap', '1.3') +TkPackage.require('img::pixmap') + +module Tk + module Img + module PIXMAP + PACKAGE_NAME = 'img::pixmap'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::pixmap') + rescue + '' + end + end + end + end +end + +class TkPixmapImage<TkImage + def self.version + Tk::Img::PIXMAP.version + end + + def initialize(*args) + @type = 'pixmap' + super(*args) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/png.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/png.rb new file mode 100644 index 0000000000..5c829f48d2 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/png.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'png' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::png', '1.3') +TkPackage.require('img::png') + +module Tk + module Img + module PNG + PACKAGE_NAME = 'img::png'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::png') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ppm.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ppm.rb new file mode 100644 index 0000000000..eacfae467d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ppm.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'ppm' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::ppm', '1.3') +TkPackage.require('img::ppm') + +module Tk + module Img + module PPM + PACKAGE_NAME = 'img::ppm'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::ppm') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ps.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ps.rb new file mode 100644 index 0000000000..68e9178ac0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/ps.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'ps' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::ps', '1.3') +TkPackage.require('img::ps') + +module Tk + module Img + module PS + PACKAGE_NAME = 'img::ps'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::ps') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/sgi.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/sgi.rb new file mode 100644 index 0000000000..ec7038bf0e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/sgi.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'sgi' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::sgi', '1.3') +TkPackage.require('img::sgi') + +module Tk + module Img + module SGI + PACKAGE_NAME = 'img::sgi'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::sgi') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/sun.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/sun.rb new file mode 100644 index 0000000000..651f946497 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/sun.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'sun' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::sun', '1.3') +TkPackage.require('img::sun') + +module Tk + module Img + module SUN + PACKAGE_NAME = 'img::sun'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::sun') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/tga.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/tga.rb new file mode 100644 index 0000000000..1eae407c0a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/tga.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'tga' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::tga', '1.3') +TkPackage.require('img::tga') + +module Tk + module Img + module TGA + PACKAGE_NAME = 'img::tga'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::tga') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/tiff.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/tiff.rb new file mode 100644 index 0000000000..ed271c2600 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/tiff.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'tiff' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::tiff', '1.3') +TkPackage.require('img::tiff') + +module Tk + module Img + module TIFF + PACKAGE_NAME = 'img::tiff'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::tiff') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/window.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/window.rb new file mode 100644 index 0000000000..3b5906fab6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/window.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'window' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::window', '1.3') +TkPackage.require('img::window') + +module Tk + module Img + module WINDOW + PACKAGE_NAME = 'img::window'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::window') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/xbm.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/xbm.rb new file mode 100644 index 0000000000..f4bea030be --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/xbm.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'xbm' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::xbm', '1.3') +TkPackage.require('img::xbm') + +module Tk + module Img + module XBM + PACKAGE_NAME = 'img::xbm'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::xbm') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/xpm.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/xpm.rb new file mode 100644 index 0000000000..5119c8710b --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tkimg/xpm.rb @@ -0,0 +1,33 @@ +# +# TkImg - format 'xpm' +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tkimg/setup.rb' + +# TkPackage.require('img::xpm', '1.3') +TkPackage.require('img::xpm') + +module Tk + module Img + module XPM + PACKAGE_NAME = 'img::xpm'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('img::xpm') + rescue + '' + end + end + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tktable.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tktable.rb new file mode 100644 index 0000000000..385eb13497 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tktable.rb @@ -0,0 +1,14 @@ +# +# TkTable support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tktable/setup.rb' + +# load library +require 'tkextlib/tktable/tktable' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tktable/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tktable/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tktable/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tktable/tktable.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tktable/tktable.rb new file mode 100644 index 0000000000..4edaabc847 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tktable/tktable.rb @@ -0,0 +1,839 @@ +# +# tkextlib/tktable/tktable.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' +require 'tk/validation' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tktable/setup.rb' + +# TkPackage.require('Tktable', '2.8') +TkPackage.require('Tktable') + +module Tk + class TkTable < TkWindow + PACKAGE_NAME = 'Tktable'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('Tktable') + rescue + '' + end + end + + class CellTag < TkObject + end + + module ConfigMethod + end + end +end + +module Tk::TkTable::ConfigMethod + include TkItemConfigMethod + + def __item_cget_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'cget', id[1]] + end + private :__item_cget_cmd + + def __item_config_cmd(id) # id := [ type, tagOrId ] + [self.path, id[0], 'configure', id[1]] + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + id = tagid(id[1]) + end + [self.path, id].join(';') + end + private :__item_pathname + + def __item_boolval_optkeys(id) + super(id) << 'multiline' << 'showtext' << 'wrap' + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + super(id) << 'ellipsis' + end + private :__item_strval_optkeys + + def __item_val2ruby_optkeys(id) # { key=>method, ... } + super(id).update('window'=>proc{|v| window(v)}) + end + private :__item_val2ruby_optkeys + + def tag_cget(tagOrId, option) + itemcget(['tag', tagid(tagOrId)], option) + end + def tag_configure(tagOrId, slot, value=None) + itemconfigure(['tag', tagid(tagOrId)], slot, value) + end + def tag_configinfo(tagOrId, slot=nil) + itemconfiginfo(['tag', tagid(tagOrId)], slot) + end + def current_tag_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['tag', tagid(tagOrId)], slot) + end + + def window_cget(tagOrId, option) + itemcget(['window', tagid(tagOrId)], option) + end + def window_configure(tagOrId, slot, value=None) + if slot == :window || slot == 'window' + value = _epath(value) + elsif slot.kind_of?(Hash) + if slot.key?(:window) || slot.key?('window') + slot = _symbolkey2str(slot) + slot['window'] = _epath(slot['window']) + end + end + itemconfigure(['window', tagid(tagOrId)], slot, value) + end + def window_configinfo(tagOrId, slot=nil) + itemconfiginfo(['window', tagid(tagOrId)], slot) + end + def current_window_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['window', tagid(tagOrId)], slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +##################################################### + +class Tk::TkTable::CellTag + include TkTreatTagFont + + CellTagID_TBL = TkCore::INTERP.create_table + CellTag_ID = ['tktbl:celltag'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ CellTagID_TBL.clear } + + def self.id2obj(table, id) + tpath = table.path + return id unless CellTagID_TBL[tpath] + CellTagID_TBL[tpath][id]? CellTagID_TBL[tpath][id] : id + end + + def initialize(parent, keys=nil) + @parent = @t = parent + @tpath - parent.path + @path = @id = CellTag_ID.join(TkCore::INTERP._ip_id_) + CellTagID_TBL[@tpath] = {} unless CellTagID_TBL[@tpath] + CellTagID_TBL[@tpath][@id] = self + CellTag_ID[1].succ! + configure(keys) if keys + end + + def id + @id + end + + def destroy + tk_call(@tpath, 'tag', 'delete', @id) + CellTagID_TBL[@tpath].delete(@id) if CellTagID_TBL[@tpath] + self + end + alias delete destroy + + def exist? + @t.tag_exist?(@id) + end + def include?(idx) + @t.tag_include?(@id, idx) + end + + def add_cell(*args) + @t.tag_cell(@id, *args) + end + def add_col(*args) + @t.tag_col(@id, *args) + end + def add_row(*args) + @t.tag_row(@id, *args) + end + + def raise(target=None) + @t.tag_raise(@id, target) + end + def lower(target=None) + @t.tag_lower(@id, target) + end + + def cget(key) + @t.tag_cget(@id, key) + end + def configure(key, val=None) + @t.tag_configure(@id, key, val) + end + def configinfo(key=nil) + @t.tag_configinfo(@id, key) + end + def current_configinfo(key=nil) + @t.current_tag_configinfo(@id, key) + end +end + +class Tk::TkTable::NamedCellTag < Tk::TkTable::CellTag + def self.new(parent, name, keys=nil) + if CellTagID_TBL[parent.path] && CellTagID_TBL[parent.path][name] + cell = CellTagID_TBL[parent.path][name] + cell.configure(keys) if keys + return cell + else + super(parent, name, keys) + end + end + + def initialize(parent, name, keys=nil) + @parent = @t = parent + @tpath - parent.path + @path = @id = name + CellTagID_TBL[@tpath] = {} unless CellTagID_TBL[@tpath] + CellTagID_TBL[@tpath][@id] = self + configure(keys) if keys + end +end + +##################################################### + +class Tk::TkTable + TkCommandNames = ['table'.freeze].freeze + WidgetClassName = 'Table'.freeze + WidgetClassNames[WidgetClassName] = self + + include Scrollable + include Tk::TkTable::ConfigMethod + include Tk::ValidateConfigure + + def __destroy_hook__ + Tk::TkTable::CelTag::CellTagID_TBL.delete(@path) + end + + def __boolval_optkeys + super() << 'autoclear' << 'flashmode' << 'invertselected' << + 'multiline' << 'selecttitle' << 'wrap' + end + private :__boolval_optkeys + + def __strval_optkeys + super() << 'colseparator' << 'ellipsis' << 'rowseparator' << 'sparsearray' + end + private :__strval_optkeys + + + ################################# + + class BrowseCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?c, ?n, :column ], + [ ?C, ?s, :index ], + [ ?i, ?x, :cursor ], + [ ?r, ?n, :row ], + [ ?s, ?s, :last_index ], + [ ?S, ?s, :new_index ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?x, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + ['browsecommand', 'browsecmd'] + end + end + #-------------------------------- + class CellCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?c, ?n, :column ], + [ ?C, ?s, :index ], + [ ?i, ?m, :rw_mode ], + [ ?r, ?n, :row ], + [ ?s, ?v, :value ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + [ ?m, proc{|val| (val == '0')? (:r) : (:w)} ], + [ ?v, proc{|val| TkComm.tk_tcl2ruby(val, true, false)} ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + TkComm._get_eval_string(val) + end + end + + def self._config_keys + ['command'] + end + end + #-------------------------------- + class SelectionCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?c, ?n, :sel_columns ], + [ ?C, ?s, :sel_area ], + [ ?i, ?n, :total ], + [ ?r, ?n, :sel_rows ], + [ ?s, ?s, :value ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val.to_s + end + end + + def self._config_keys + ['selectioncommand', 'selcmd'] + end + end + #-------------------------------- + class ValidateCommand < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?c, ?n, :column ], + [ ?C, ?s, :index ], + [ ?i, ?x, :cursor ], + [ ?r, ?n, :row ], + [ ?s, ?v, :current_value ], + [ ?S, ?v, :new_value ], + [ ?W, ?w, :widget ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?x, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?w, TkComm.method(:window) ], + [ ?v, proc{|val| TkComm.tk_tcl2ruby(val, true, false)} ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + def self._config_keys + ['vcmd', 'validatecommand'] + end + end + + ################################# + + def __validation_class_list + super() << + BrowseCommand << CellCommand << SelectionCommand << ValidateCommand + end + + Tk::ValidateConfigure.__def_validcmd(binding, BrowseCommand) + Tk::ValidateConfigure.__def_validcmd(binding, CellCommand) + Tk::ValidateConfigure.__def_validcmd(binding, SelectionCommand) + Tk::ValidateConfigure.__def_validcmd(binding, ValidateCommand) + + ################################# + + def activate(idx) + tk_send('activate', tagid(idx)) + end + + def bbox(idx) + list(tk_send('bbox', tagid(idx))) + end + + def border_mark(x, y) + simplelist(tk_send('border', 'mark', x, y)) + end + def border_mark_row(x, y) + tk_send('border', 'mark', x, y, 'row') + end + def border_mark_col(x, y) + tk_send('border', 'mark', x, y, 'col') + end + def border_dragto(x, y) + tk_send('border', 'dragto', x, y) + end + + def clear_cache(first=None, last=None) + tk_send('clear', 'cache', tagid(first), tagid(last)) + self + end + def clear_sizes(first=None, last=None) + tk_send('clear', 'sizes', tagid(first), tagid(last)) + self + end + def clear_tags(first=None, last=None) + tk_send('clear', 'tags', tagid(first), tagid(last)) + self + end + def clear_all(first=None, last=None) + tk_send('clear', 'all', tagid(first), tagid(last)) + self + end + + def curselection + simplelist(tk_send('curselection')) + end + def curselection=(val) + tk_send('curselection', val) + val + end + + def curvalue + tk_tcl2ruby(tk_send('curvalue'), true, false) + end + def curvalue=(val) + tk_send('curvalue', val) + val + end + + def delete_active(idx1, idx2=None) + tk_send('delete', 'active', tagid(idx1), tagid(idx2)) + self + end + def delete_cols(*args) # ?switches_array?, index, ?count? + params = [] + if args[0].kind_of?(Array) + switches = args.shift + switches.each{|k| params << "-#{k}"} + end + params << '--' + params << tagid(args.shift) + params.concat(args) + tk_send('delete', 'cols', *params) + self + end + def delete_rows(*args) # ?switches_array?, index, ?count? + params = [] + if args[0].kind_of?(Array) + switches = args.shift + switches.each{|k| params << "-#{k}"} + end + params << '--' + params << tagid(args.shift) + params.concat(args) + tk_send('delete', 'rows', *params) + self + end + + def get(idx) + tk_tcl2ruby(tk_send('get', tagid(idx)), true, false) + end + def get_area(idx1, idx2) + simplelist(tk_send('get', tagid(idx1), tagid(idx2))).collect{|v| + tk_tcl2ruby(v, true, false) + } + end + + def height_list + list(tk_send('height')) + end + def height(row) + number(tk_send('height', row)) + end + def set_height(*pairs) + tk_send('height', *(pairs.flatten)) + self + end + + def hidden_list + simplelist(tk_send('hidden')) + end + def hidden?(idx, *args) + if args.empty? + if (ret = tk_send('hidden', tagid(idx))) == '' + false + else + ret + end + else + bool(tk_send('hidden', tagid(idx), *(args.collect{|i| tagid(i)}))) + end + end + + def icursor + number(tk_send('icursor')) + end + def icursor_set(idx) + number(tk_send('icursor', tagid(idx))) + end + + def index(idx) + tk_send('index', tagid(idx)) + end + def row_index(idx) + number(tk_send('index', tagid(idx), 'row')) + end + def col_index(idx) + number(tk_send('index', tagid(idx), 'col')) + end + + def insert_active(idx, val) + tk_send('insert', 'active', tagid(idx), val) + self + end + def insert_cols(*args) # ?switches_array?, index, ?count? + params = [] + if args[0].kind_of?(Array) + switches = args.shift + switches.each{|k| params << "-#{k}"} + end + params << '--' + params.concat(args) + params << tagid(args.shift) + tk_send('insert', 'cols', *params) + self + end + def insert_rows(*args) # ?switches_array?, index, ?count? + params = [] + if args[0].kind_of?(Array) + switches = args.shift + switches.each{|k| params << "-#{k}"} + end + params << '--' + params << tagid(args.shift) + params.concat(args) + tk_send('insert', 'rows', *params) + self + end + + # def postscript(*args) + # tk_send('postscript', *args) + # end + + def reread + tk_send('reread') + 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 see(idx) + tk_send('see', tagid(idx)) + self + end + + def selection_anchor(idx) + tk_send('selection', 'anchor', tagid(idx)) + self + end + def selection_clear(first, last=None) + tk_send('selection', 'clear', tagid(first), tagid(last)) + self + end + def selection_clear_all + selection_clear('all') + end + def selection_include?(idx) + bool(tk_send('selection', 'includes', tagid(idx))) + end + def selection_present + bool(tk_send('selection', 'present')) + end + def selection_set(first, last=None) + tk_send('selection', 'set', tagid(first), tagid(last)) + self + end + + def set(*pairs) # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + args << pairs[i+1] + } + tk_send('set', *args) + self + end + def set_row(*pairs) # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + args << pairs[i+1] + } + tk_send('set', 'row', *args) + self + end + def set_col(*pairs) # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + args << pairs[i+1] + } + tk_send('set', 'col', *args) + self + end +=begin + def set(*pairs) # idx, val, idx, val, ... OR [idx, val], [idx, val], ... + if pairs[0].kind_of?(Array) + # [idx, val], [idx, val], ... + args = [] + pairs.each{|idx, val| args << tagid(idx) << val } + tk_send('set', *args) + else + # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + args << pairs[i+1] + } + tk_send('set', *args) + end + self + end + def set_row(*pairs) + if pairs[0].kind_of?(Array) + # [idx, val], [idx, val], ... + args = [] + pairs.each{|idx, val| args << tagid(idx) << val } + tk_send('set', 'row', *args) + else + # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + args << pairs[i+1] + } + tk_send('set', 'row', *args) + end + self + end + def set_col(*pairs) + if pairs[0].kind_of?(Array) + # [idx, val], [idx, val], ... + args = [] + pairs.each{|idx, val| args << idx << val } + tk_send('set', 'col', *args) + else + # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + args << pairs[i+1] + } + tk_send('set', 'col', *args) + end + self + end +=end + + def spans + simplelist(tk_send('spans')).collect{|inf| + lst = simplelist(inf) + idx = lst[0] + rows, cols = lst[1].split(',').map!{|n| Integer(n)} + [idx [rows, cols]] + } + end + alias span_list spans + def span(idx) + lst = simplelist(tk_send('spans', tagid(idx))) + idx = lst[0] + rows, cols = lst[1].split(',').map!{|n| Integer(n)} + [idx [rows, cols]] + end + def set_spans(*pairs) + # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + val = pairs[i+1] + if val.kind_of?(Array) + args << val.join(',') + else + args << val + end + } + tk_send('spans', *args) + self + end +=begin + def set_spans(*pairs) + if pairs[0].kind_of?(Array) + # [idx, val], [idx, val], ... + args = [] + pairs.each{|idx, val| + args << tagid(idx) + if val.kind_of?(Array) + args << val.join(',') + else + args << val + end + } + tk_send('spans', *args) + else + # idx, val, idx, val, ... + args = [] + 0.step(pairs.size-1, 2){|i| + args << tagid(pairs[i]) + val = pairs[i+1] + if val.kind_of?(Array) + args << val.join(',') + else + args << val + end + } + tk_send('spans', *args) + end + self + end +=end + + def tagid(tag) + if tag.kind_of?(Tk::TkTable::CellTag) + tag.id + elsif tag.kind_of?(Array) + if tag[0].kind_of?(Integer) && tag[1].kind_of?(Integer) + # [row, col] + tag.join(',') + else + tag + end + else + tag + end + end + + def tagid2obj(tagid) + if Tk::TkTable::CellTag::CellTagID_TBL.key?(@path) + if Tk::TkTable::CellTag::CellTagID_TBL[@path].key?(tagid) + Tk::TkTable::CellTag::CellTagID_TBL[@path][tagid] + else + tagid + end + else + tagid + end + end + + def tag_cell(tag, *cells) + tk_send('tag', 'cell', tagid(tag), *(cells.collect{|idx| tagid(idx)})) + self + end + def tag_reset(*cells) + tk_send('tag', 'cell', '', *(cells.collect{|idx| tagid(idx)})) + self + end + def tag_col(tag, *cols) + tk_send('tag', 'col', tagid(tag), *cols) + self + end + def tag_col_reset(*cols) + tk_send('tag', 'col', '', *cols) + self + end + def tag_delete(tag) + tk_send('tag', 'delete', tagid(tag)) + if Tk::TkTable::CellTag::CellTagID_TBL[@path] + if tag.kind_of? Tk::TkTable::CellTag + Tk::TkTable::CellTag::CellTagID_TBL[@path].delete(tag.id) + else + Tk::TkTable::CellTag::CellTagID_TBL[@path].delete(tag) + end + end + self + end + def tag_exist?(tag) + bool(tk_send('tag', 'exists', tagid(tag))) + end + def tag_include?(tag, idx) + bool(tk_send('tag', 'includes', tagid(tag), tagid(idx))) + end + def tag_lower(tag, target=None) + tk_send('tag', 'lower', tagid(tag), tagid(target)) + self + end + def tag_names(pat=None) + simplelist(tk_send('tag', 'names', pat)).collect{|tag| tagid2obj(tag)} + end + def tag_raise(tag, target=None) + tk_send('tag', 'raise', tagid(tag), tagid(target)) + self + end + def tag_row(tag, *rows) + tk_send('tag', 'row', tagid(tag), *rows) + self + end + def tag_row_reset(*rows) + tk_send('tag', 'row', '', *rows) + self + end + + def validate(idx) + bool(tk_send('validate', tagid(idx))) + end + + def width_list + list(tk_send('width')) + end + def width(row) + number(tk_send('width', row)) + end + def set_width(*pairs) + tk_send('width', *(pairs.flatten)) + self + end + + def window_delete(*args) + tk_send('window', 'delete', *(args.collect{|idx| tagid(idx)})) + self + end + def window_move(from_idx, to_idx) + tk_send('window', 'move', tagid(from_idx), tagid(to_idx)) + self + end + def window_names(pat=None) + simplelist(tk_send('window', 'names', pat)) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans.rb new file mode 100644 index 0000000000..c5de5be5e6 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans.rb @@ -0,0 +1,14 @@ +# +# TkTrans support (win32 only) +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tktrans/setup.rb' + +# load library +require 'tkextlib/tktrans/tktrans' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans/tktrans.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans/tktrans.rb new file mode 100644 index 0000000000..665c57af0c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/tktrans/tktrans.rb @@ -0,0 +1,64 @@ +# +# TkTrans support (win32 only) +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tktrans/setup.rb' + +TkPackage.require('tktrans') rescue Tk.load_tcllibrary('tktrans') + +module Tk + module TkTrans + PACKAGE_NAME = 'tktrans'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('tktrans') + rescue + '' + end + end + end +end + +class TkWindow + def tktrans_set_image(img) + tk_send('tktrans::setwidget', @path, img) + self + end + def tktrans_get_image() + tk_send('tktrans::setwidget', @path) + end +end + +class TkRoot + undef tktrans_set_image, tktrans_get_image + + def tktrans_set_image(img) + tk_send('tktrans::settoplevel', @path, img) + self + end + def tktrans_get_image() + tk_send('tktrans::settoplevel', @path) + end +end + +class TkToplevel + undef tktrans_set_image, tktrans_get_image + + def tktrans_set_image(img) + tk_send('tktrans::settoplevel', @path, img) + self + end + def tktrans_get_image() + tk_send('tktrans::settoplevel', @path) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl.rb new file mode 100644 index 0000000000..1944fb83e3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl.rb @@ -0,0 +1,13 @@ +# +# TkTreeCtrl support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/treectrl/setup.rb' + +# load library +require 'tkextlib/treectrl/tktreectrl' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb new file mode 100644 index 0000000000..12f7cffabf --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -0,0 +1,2311 @@ +# +# tkextlib/treectrl/tktreectrl.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/treectrl/setup.rb' + +# TkPackage.require('treectrl', '1.0') +# TkPackage.require('treectrl', '1.1') +TkPackage.require('treectrl') + +module Tk + class TreeCtrl < TkWindow + BindTag_FileList = TkBindTag.new_by_name('TreeCtrlFileList') + + PACKAGE_NAME = 'treectrl'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('treectrl') + rescue + '' + end + end + + HasColumnCreateCommand = + (TkPackage.vcompare(self.package_version, '1.1') >= 0) + + # dummy :: + # pkgIndex.tcl of TreeCtrl-1.0 doesn't support auto_load for + # 'loupe' command (probably it is bug, I think). + # So, calling a 'treectrl' command for loading the dll with + # the auto_load facility. + begin + tk_call('treectrl') + rescue + end + def self.loupe(img, x, y, w, h, zoom) + # NOTE: platform == 'unix' only + + # img => TkPhotoImage + # x, y => screen coords + # w, h => magnifier width and height + # zoom => zooming rate + Tk.tk_call_without_enc('loupe', img, x, y, w, h, zoom) + end + + def self.text_layout(font, text, keys={}) + TkComm.list(Tk.tk_call_without_enc('textlayout', font, text, keys)) + end + + def self.image_tint(img, color, alpha) + Tk.tk_call_without_enc('imagetint', img, color, alpha) + end + + class NotifyEvent < TkUtil::CallbackSubst + end + + module ConfigMethod + end + end + TreeCtrl_Widget = TreeCtrl +end + +############################################## + +class Tk::TreeCtrl::NotifyEvent + # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>] + KEY_TBL = [ + [ ?c, ?n, :item_num ], + [ ?d, ?s, :detail ], + [ ?D, ?l, :items ], + [ ?e, ?e, :event ], + [ ?I, ?n, :id ], + [ ?l, ?n, :lower_bound ], + [ ?p, ?n, :active_id ], + [ ?P, ?e, :pattern ], + [ ?S, ?l, :sel_items ], + [ ?T, ?w, :widget ], + [ ?u, ?n, :upper_bound ], + [ ?W, ?o, :object ], + [ ??, ?x, :parm_info ], + nil + ] + + # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>] + PROC_TBL = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?l, TkComm.method(:list) ], + [ ?w, TkComm.method(:window) ], + + [ ?e, proc{|val| + case val + when /^<<[^<>]+>>$/ + TkVirtualEvent.getobj(val[1..-2]) + when /^<[^<>]+>$/ + val[1..-2] + else + val + end + } + ], + + [ ?o, proc{|val| TkComm.tk_tcl2ruby(val)} ], + + [ ?x, proc{|val| + begin + inf = {} + Hash[*(TkComm.list(val))].each{|k, v| + if keyinfo = KEY_TBL.assoc(k[0]) + if cmd = PROC_TBL.assoc(keyinfo[1]) + begin + new_v = cmd.call(v) + v = new_v + rescue + end + end + end + inf[k] = v + } + inf + rescue + 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 + +############################################## + +module Tk::TreeCtrl::ConfigMethod + include TkItemConfigMethod + + def treectrl_tagid(key, obj) + if key.kind_of?(Array) + key = key.join(' ') + else + key = key.to_s + end + + if (obj.kind_of?(Tk::TreeCtrl::Column) || + obj.kind_of?(Tk::TreeCtrl::Element) || + obj.kind_of?(Tk::TreeCtrl::Item) || + obj.kind_of?(Tk::TreeCtrl::Style)) + obj = obj.id + end + + case key + when 'column' + obj + + when 'debug' + None + + when 'dragimage' + None + + when 'element' + obj + + when 'item element' + obj + + when 'marquee' + None + + when 'notify' + obj + + when 'style' + obj + + else + obj + end + end + + def tagid(mixed_id) + if mixed_id == 'debug' + ['debug', None] + elsif mixed_id == 'dragimage' + ['dragimage', None] + elsif mixed_id == 'marquee' + ['marquee', None] + elsif mixed_id.kind_of?(Array) + [mixed_id[0], treectrl_tagid(*mixed_id)] + else + tagid(mixed_id.split(':')) + end + end + + def __item_cget_cmd(mixed_id) + if mixed_id[0] == 'column' && mixed_id[1] == 'drag' + return [self.path, 'column', 'dragcget'] + end + + if mixed_id[1].kind_of?(Array) + id = mixed_id[1] + else + id = [mixed_id[1]] + end + + if mixed_id[0].kind_of?(Array) + ([self.path].concat(mixed_id[0]) << 'cget').concat(id) + else + [self.path, mixed_id[0], 'cget'].concat(id) + end + end + private :__item_cget_cmd + + def __item_config_cmd(mixed_id) + if mixed_id[0] == 'column' && mixed_id[1] == 'drag' + return [self.path, 'column', 'dragconfigure'] + end + + if mixed_id[1].kind_of?(Array) + id = mixed_id[1] + else + id = [mixed_id[1]] + end + + if mixed_id[0].kind_of?(Array) + ([self.path].concat(mixed_id[0]) << 'configure').concat(id) + else + [self.path, mixed_id[0], 'configure'].concat(id) + end + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + key = id[0] + if key.kind_of?(Array) + key = key.join(' ') + end + + tag = id[1] + if tag.kind_of?(Array) + tag = tag.join(' ') + end + + id = [key, tag].join(':') + end + [self.path, id].join(';') + end + private :__item_pathname + + def __item_configinfo_struct(id) + if id.kind_of?(Array) && id[0].to_s == 'notify' + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>nil, :current_value=>1} + else + {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, + :default_value=>3, :current_value=>4} + end + end + private :__item_configinfo_struct + + + def __item_font_optkeys(id) + if id.kind_of?(Array) && (id[0] == 'element' || + (id[0].kind_of?(Array) && id[0][1] == 'element')) + [] + else + ['font'] + end + end + private :__item_font_optkeys + + def __item_numstrval_optkeys(id) + if id == 'debug' + ['displaydelay'] + else + super(id) + end + end + private :__item_numstrval_optkeys + + def __item_boolval_optkeys(id) + if id == 'debug' + ['data', 'display', 'enable'] + elsif id == 'dragimage' + ['visible'] + elsif id == 'marquee' + ['visible'] + elsif id.kind_of?(Array) + case id[0] + when 'item' + ['button', 'visible'] + when 'column' + if id[1] == 'drag' + ['enable'] + else + ['button', 'expand', 'resize', 'squeeze', 'sunken', + 'visible', 'widthhack'] + end + when 'element' + ['draw', 'filled', 'showfocus', 'destroy'] + when 'notify' + ['active'] + when 'style' + ['detach'] + else + if id[0].kind_of?(Array) && id[0][1] == 'element' + ['filled', 'showfocus'] + else + super(id) + end + end + else + super(id) + end + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + if id == 'debug' + ['erasecolor'] + elsif id.kind_of?(Array) + case id[0] + when 'column' + if id[1] == 'drag' + ['indicatorcolor'] + else + super(id) << 'textcolor' + end + when 'element' + super(id) << 'fill' << 'outline' << 'format' + else + super(id) + end + else + super(id) + end + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + if id.kind_of?(Array) + case id[0] + when 'column' + ['itembackground'] + when 'element' + ['relief'] + when 'style' + ['union'] + else + if id[0].kind_of?(Array) && id[0][1] == 'element' + ['relief'] + else + [] + end + end + else + [] + end + end + private :__item_listval_optkeys + + def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... } + { + 'notreally'=>nil, + 'increasing'=>'decreasing', + 'decreasing'=>'increasing', + 'ascii'=>nil, + 'dictionary'=>nil, + 'integer'=>nil, + 'real'=>nil + } + end + private :__item_keyonly_optkeys + + def column_cget(tagOrId, option) + itemcget(['column', tagOrId], option) + end + def column_configure(tagOrId, slot, value=None) + itemconfigure(['column', tagOrId], slot, value) + end + def column_configinfo(tagOrId, slot=nil) + itemconfiginfo(['column', tagOrId], slot) + end + def current_column_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['column', tagOrId], slot) + end + + def column_dragcget(option) + itemcget(['column', 'drag'], option) + end + def column_dragconfigure(slot, value=None) + itemconfigure(['column', 'drag'], slot, value) + end + def column_dragconfiginfo(slot=nil) + itemconfiginfo(['column', 'drag'], slot) + end + def current_column_dragconfiginfo(slot=nil) + current_itemconfiginfo(['column', 'drag'], slot) + end + + def debug_cget(option) + itemcget('debug', option) + end + def debug_configure(slot, value=None) + itemconfigure('debug', slot, value) + end + def debug_configinfo(slot=nil) + itemconfiginfo('debug', slot) + end + def current_debug_configinfo(slot=nil) + current_itemconfiginfo('debug', slot) + end + + def dragimage_cget(option) + itemcget('dragimage', option) + end + def dragimage_configure(slot, value=None) + itemconfigure('dragimage', slot, value) + end + def dragimage_configinfo(slot=nil) + itemconfiginfo('dragimage', slot) + end + def current_dragimage_configinfo(slot=nil) + current_itemconfiginfo('dragimage', slot) + end + + def element_cget(tagOrId, option) + itemcget(['element', tagOrId], option) + end + def element_configure(tagOrId, slot, value=None) + itemconfigure(['element', tagOrId], slot, value) + end + def element_configinfo(tagOrId, slot=nil) + itemconfiginfo(['element', tagOrId], slot) + end + def current_element_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['element', tagOrId], slot) + end + + def item_cget(tagOrId, option) + itemcget(['item', tagOrId], option) + end + def item_configure(tagOrId, slot, value=None) + itemconfigure(['item', tagOrId], slot, value) + end + def item_configinfo(tagOrId, slot=nil) + itemconfiginfo(['item', tagOrId], slot) + end + def current_item_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['item', tagOrId], slot) + end + + def item_element_cget(item, column, elem, option) + itemcget([['item', 'element'], [item, column, elem]], option) + end + def item_element_configure(item, column, elem, slot, value=None) + itemconfigure([['item', 'element'], [item, column, elem]], slot, value) + end + def item_element_configinfo(item, column, elem, slot=nil) + itemconfiginfo([['item', 'element'], [item, column, elem]], slot) + end + def current_item_element_configinfo(item, column, elem, slot=nil) + current_itemconfiginfo([['item', 'element'], [item, column, elem]], slot) + end + + def marquee_cget(option) + itemcget('marquee', option) + end + def marquee_configure(slot, value=None) + itemconfigure('marquee', slot, value) + end + def marquee_configinfo(slot=nil) + itemconfiginfo('marquee', slot) + end + def current_marquee_configinfo(slot=nil) + current_itemconfiginfo('marquee', slot) + end + + def notify_cget(win, pattern, option) + pattern = "<#{pattern}>" + itemconfigure(['notify', [win, pattern]], option) + end + def notify_configure(win, pattern, slot, value=None) + pattern = "<#{pattern}>" + itemconfigure(['notify', [win, pattern]], slot, value) + end + def notify_configinfo(win, pattern, slot=nil) + pattern = "<#{pattern}>" + itemconfiginfo(['notify', [win, pattern]], slot) + end + alias current_notify_configinfo notify_configinfo + + def style_cget(tagOrId, option) + itemcget(['style', tagOrId], option) + end + def style_configure(tagOrId, slot, value=None) + itemconfigure(['style', tagOrId], slot, value) + end + def style_configinfo(tagOrId, slot=nil) + itemconfiginfo(['style', tagOrId], slot) + end + def current_style_configinfo(tagOrId, slot=nil) + current_itemconfiginfo(['style', tagOrId], slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +############################################## + +class Tk::TreeCtrl + include Tk::TreeCtrl::ConfigMethod + include Scrollable + + TkCommandNames = ['treectrl'.freeze].freeze + WidgetClassName = 'TreeCtrl'.freeze + WidgetClassNames[WidgetClassName] = self + + ######################### + + def __destroy_hook__ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.delete(@path) + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.delete(@path) + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.delete(@path) + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.delete(@path) + end + + ######################### + + def __strval_optkeys + super() + [ + 'buttoncolor', 'columnprefix', 'itemprefix', 'linecolor' + ] + end + private :__strval_optkeys + + def __boolval_optkeys + [ + 'itemwidthequal', 'usetheme', + 'showbuttons', 'showheader', 'showlines', 'showroot', + 'showrootbutton', 'showrootlines', + ] + end + private :__boolval_optkeys + + def __listval_optkeys + [ 'defaultstyle' ] + end + private :__listval_optkeys + + ######################### + + def install_bind(cmd, *args) + install_bind_for_event_class(Tk::TreeCtrl::NotifyEvent, cmd, *args) + end + + ######################### + + def create_self(keys) + if keys and keys != None + tk_call_without_enc(self.class::TkCommandNames[0], @path, + *hash_kv(keys, true)) + else + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + end + private :create_self + + ######################### + + def activate(desc) + tk_send('activate', desc) + self + end + + def canvasx(x) + number(tk_send('canvasx', x)) + end + + def canvasy(y) + number(tk_send('canvasy', y)) + end + + def collapse(*dsc) + tk_send_without_enc('collapse', *(dsc.map!{|d| _get_eval_string(d, true)})) + self + end + + def collapse_recurse(*dsc) + tk_send_without_enc('collapse', '-recurse', + *(dsc.map!{|d| _get_eval_string(d, true)})) + self + end + + def column_bbox(idx) + list(tk_send('column', 'bbox', idx)) + end + + def column_compare(column1, op, column2) + bool(tk_send('column', 'compare', column1, op, column2)) + end + + def column_count + num_or_str(tk_send('column', 'count')) + end + + def column_create(keys=nil) + if keys && keys.kind_of?(Hash) + num_or_str(tk_send('column', 'create', *hash_kv(keys))) + else + num_or_str(tk_send('column', 'create')) + end + end + + def column_delete(idx) + if Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[self.path] + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[self.path].delete(idx) + end + tk_send('column', 'delete', idx) + self + end + + def column_index(idx) + num_or_str(tk_send('column', 'index', idx)) + end + + def column_id(idx) + tk_send('column', 'id', idx) + end + + def column_list(visible=false) + if visible + simplelist(tk_send('column', 'list', '-visible')) + else + simplelist(tk_send('column', 'list')) + end + end + def column_visible_list + column_list(true) + end + + def column_move(idx, before) + tk_send('column', 'move', idx, before) + self + end + + def column_needed_width(idx) + num_or_str(tk_send('column', 'neededwidth', idx)) + end + alias column_neededwidth column_needed_width + + def column_order(column, visible=false) + if visible + num_or_str(tk_send('column', 'order', column, '-visible')) + else + num_or_str(tk_send('column', 'order', column)) + end + end + def column_visible_order(column) + column_order(column, true) + end + + def column_width(idx) + num_or_str(tk_send('column', 'width', idx)) + end + + def compare(item1, op, item2) + bool(tk_send('compare', item1, op, item2)) + end + + def contentbox() + list(tk_send('contentbox')) + end + + def depth(item=None) + num_or_str(tk_send_without_enc('depth', _get_eval_string(item, true))) + end + + def dragimage_add(item, *args) + tk_send('dragimage', 'add', item, *args) + self + end + + def dragimage_clear() + tk_send('dragimage', 'clear') + self + end + + def dragimage_offset(*args) # x, y + if args.empty? + list(tk_send('dragimage', 'offset')) + else + tk_send('dragimage', 'offset', *args) + self + end + end + + def dragimage_visible(*args) # mode + if args..empty? + bool(tk_send('dragimage', 'visible')) + else + tk_send('dragimage', 'visible', *args) + self + end + end + def dragimage_visible? + dragimage_visible() + end + + def debug_dinfo + tk_send('debug', 'dinfo') + self + end + + def debug_scroll + tk_send('debug', 'scroll') + end + + def element_create(elem, type, keys=nil) + if keys && keys.kind_of?(Hash) + tk_send('element', 'create', elem, type, *hash_kv(keys)) + else + tk_send('element', 'create', elem, type) + end + end + + def element_delete(*elems) + if Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[self.path] + elems.each{|elem| + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[self.path].delete(elem) + } + end + tk_send('element', 'delete', *elems) + self + end + + def element_names() + list(tk_send('element', 'names')).collect!{|elem| + Tk::TreeCtrl::Element.id2obj(self, elem) + } + end + + def _conv_element_perstate_val(opt, val) + case opt + when 'background', 'foreground', 'fill', 'outline', 'format' + val + when 'draw', 'filled', 'showfocus', 'destroy' + bool(val) + else + tk_tcl2ruby(val) + end + end + private :_conv_element_perstate_val + + def element_perstate(elem, opt, st_list) + tk_send('element', 'perstate', elem, "-{opt}", st_list) + end + + def element_type(elem) + tk_send('element', 'type', elem) + end + + def element_class(elem) + Tk::TreeCtrl::Element.type2class(element_type(elem)) + end + + def expand(*dsc) + tk_send('expand', *dsc) + self + end + + def expand_recurse(*dsc) + tk_send('expand', '-recurse', *dsc) + self + end + + def identify(x, y) + lst = list(tk_send('identify', x, y)) + + if lst[0] == 'item' + lst[1] = Tk::TreeCtrl::Item.id2obj(self, lst[1]) + size = lst.size + i = 2 + while i < size + case lst[i] + when 'line' + i += 1 + lst[i] = Tk::TreeCtrl::Item.id2obj(self, lst[i]) + i += 1 + + when 'button' + i += 1 + + when 'column' + i += 2 + + when 'elem' + i += 1 + lst[i] = Tk::TreeCtrl::Element.id2obj(self, lst[i]) + i += 1 + + else + i += 1 + end + end + end + + lst + end + + def index(idx) + num_or_str(tk_send('index', idx)) + end + + def item_ancestors(item) + list(tk_send('item', 'ancestors', item)).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def item_bbox(item, *args) + list(tk_send('item', 'bbox', item, *args)) + end + + def item_children(item) + list(tk_send('item', 'children', item)).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def item_collapse(item) + tk_send_without_enc('item', 'collapse', _get_eval_string(item, true)) + self + end + + def item_collapse_recurse(item) + tk_send_without_enc('item', 'collapse', + _get_eval_string(item, true), '-recurse') + self + end + + def item_compare(item1, op, item2) + bool(tk_send('item', 'compare', item1, op, item2)) + end + + def item_complex(item, *args) + tk_send_without_enc('item', 'complex', + _get_eval_string(item, true), + *(args.map!{|arg| _get_eval_string(arg, true)})) + self + end + + def item_count + num_or_str(tk_send('item', 'count')) + end + + def item_create(keys={}) + num_or_str(tk_send_without_enc('item', 'create', *hash_kv(keys, true))) + end + + def _erase_children(item) + item_children(item).each{|i| _erase_children(i)} + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path].delete(item) + end + private :_erase_children + + def item_delete(first, last=None) + if Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path] + if first == 'all' || first == :all || last == 'all' || last == :all + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path].clear + elsif last == None + _erase_children(first) + else + self.range(first, last).each{|id| + _erase_children(id) + } + end + end + tk_send('item', 'delete', first, last) + self + end + + def item_dump(item) + list(tk_send('item', 'dump', item)) + end + + def item_dump_hash(item) + Hash[*list(tk_send('item', 'dump', item))] + end + + def item_element_actual(item, column, elem, key) + tk_send('item', 'element', 'actual', item, column, elem, "-#{key}") + end + + def item_element_perstate(elem, opt, st_list) + tk_send('item', 'element', 'perstate', elem, "-{opt}", st_list) + end + + def item_expand(item) + tk_send('item', 'expand', item) + self + end + + def item_expand_recurse(item) + tk_send('item', 'expand', item, '-recurse') + self + end + + def item_firstchild(parent, child=nil) + if child + tk_send_without_enc('item', 'firstchild', + _get_eval_string(parent, true), + _get_eval_string(child, true)) + self + else + id = num_or_str(tk_send_without_enc('item', 'firstchild', + _get_eval_string(parent, true))) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_first_child item_firstchild + + def item_hasbutton(item, st=None) + if st == None + bool(tk_send_without_enc('item', 'hasbutton', + _get_eval_string(item, true))) + else + tk_send_without_enc('item', 'hasbutton', + _get_eval_string(item, true), + _get_eval_string(st)) + self + end + end + alias item_has_button item_hasbutton + + def item_hasbutton?(item) + item_hasbutton(item) + end + alias item_has_button? item_hasbutton? + + def item_id(item) + tk_send('item', 'id', item) + end + + def item_image(item, column=nil, *args) + if args.empty? + if column + img = tk_send('item', 'image', item, column) + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img + else + simplelist(tk_send('item', 'image', item)).collect!{|img| + TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img + } + end + else + tk_send('item', 'image', item, column, *args) + self + end + end + def get_item_image(item, column=nil) + item_image(item, column) + end + def set_item_image(item, col, img, *args) + item_image(item, col, img, *args) + end + + def item_index(item) + list(tk_send('item', 'index', item)) + end + + def item_isancestor(item, des) + bool(tk_send('item', 'isancestor', item, des)) + end + alias item_is_ancestor item_isancestor + alias item_isancestor? item_isancestor + alias item_is_ancestor? item_isancestor + + def item_isopen(item) + bool(tk_send('item', 'isopen', item)) + end + alias item_is_open item_isopen + alias item_isopen? item_isopen + alias item_is_open? item_isopen + alias item_isopened? item_isopen + alias item_is_opened? item_isopen + + def item_lastchild(parent, child=nil) + if child + tk_send_without_enc('item', 'lastchild', + _get_eval_string(parent, true), + _get_eval_string(child, true)) + self + else + id = num_or_str(tk_send_without_enc('item', 'lastchild', + _get_eval_string(parent, true))) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_last_child item_lastchild + + def item_nextsibling(sibling, nxt=nil) + if nxt + tk_send('item', 'nextsibling', sibling, nxt) + self + else + id = num_or_str(tk_send('item', 'nextsibling', sibling)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_next_sibling item_nextsibling + + def item_numchildren(item) + number(tk_send_without_enc('item', 'numchildren', + _get_eval_string(item, true))) + end + alias item_num_children item_numchildren + alias item_children_size item_numchildren + + def item_order(item, visible=false) + if visible + ret = num_or_str(tk_send('item', 'order', item, '-visible')) + else + ret = num_or_str(tk_send('item', 'order', item)) + end + + (ret.kind_of?(Fixnum) && ret < 0)? nil: ret + end + def item_visible_order(item) + item_order(item, true) + end + + def item_parent(item) + id = num_or_str(tk_send('item', 'parent', item)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + + def item_prevsibling(sibling, prev=nil) + if prev + tk_send('item', 'prevsibling', sibling, prev) + self + else + id = num_or_str(tk_send('item', 'prevsibling', sibling)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + end + alias item_prev_sibling item_prevsibling + + def item_range(first, last) + simplelist(tk_send('item', 'range', first, last)) + end + + def item_remove(item) + tk_send('item', 'remove', item) + self + end + + def item_rnc(item) + list(tk_send('item', 'rnc', item)) + end + + def _item_sort_core(real_sort, item, *opts) + # opts ::= sort_param [, sort_param, ... ] + # sort_param ::= {key=>val, ...} + # [type, desc, {key=>val, ...}] + # param + opts = opts.collect{|param| + if param.kind_of?(Hash) + param = _symbolkey2str(param) + if param.key?('column') + key = '-column' + desc = param.delete('column') + elsif param.key?('element') + key = '-element' + desc = param.delete('element') + else + key = nil + end + + if param.empty? + param = None + else + param = hash_kv(__conv_item_keyonly_opts(item, param)) + end + + if key + [key, desc].concat(param) + else + param + end + + elsif param.kind_of?(Array) + if param[2].kind_of?(Hash) + param[2] = hash_kv(__conv_item_keyonly_opts(item, param[2])) + end + param + + elsif param.kind_of?(String) && param =~ /\A[a-z]+\Z/ + '-' << param + + elsif param.kind_of?(Symbol) + '-' << param.to_s + + else + param + end + }.flatten + + if real_sort + tk_send('item', 'sort', item, *opts) + self + else + list(tk_send('item', 'sort', item, '-notreally', *opts)) + end + end + private :_item_sort_core + + def item_sort(item, *opts) + _item_sort_core(true, item, *opts) + end + def item_sort_not_really(item, *opts) + _item_sort_core(false, item, *opts) + end + + def item_span(item, column=nil, *args) + if args.empty? + if column + list(tk_send('item', 'span', item, column)) + else + simplelist(tk_send('item', 'span', item)).collect!{|elem| list(elem)} + end + else + tk_send('item', 'span', item, column, *args) + self + end + end + def get_item_span(item, column=nil) + item_span(item, column) + end + def set_item_span(item, col, num, *args) + item_span(item, col, num, *args) + end + + def item_state_forcolumn(item, column, *args) + tk_send('item', 'state', 'forcolumn', item, column, *args) + end + alias item_state_for_column item_state_forcolumn + + def item_state_get(item, *args) + if args.empty? + list(tk_send('item', 'state', 'get', item *args)) + else + bool(tk_send('item', 'state', 'get', item)) + end + end + + def item_state_set(item, *args) + tk_send('item', 'state', 'set', item, *args) + end + + def item_style_elements(item, column) + list(tk_send('item', 'style', 'elements', item, column)).collect!{|id| + Tk::TreeCtrl::Style.id2obj(self, id) + } + end + + def item_style_map(item, column, style, map) + tk_send('item', 'style', 'map', item, column, style, map) + self + end + + def item_style_set(item, column=nil, *args) + if args.empty? + if column + id = tk_send_without_enc('item', 'style', 'set', + _get_eval_string(item, true), + _get_eval_string(column, true)) + Tk::TreeCtrl::Style.id2obj(self, id) + else + list(tk_send_without_enc('item', 'style', 'set', + _get_eval_string(item, true))).collect!{|id| + Tk::TreeCtrl::Style.id2obj(self, id) + } + end + else + tk_send_without_enc('item', 'style', 'set', + _get_eval_string(item, true), + _get_eval_string(column, true), + *(args.flatten.map!{|arg| + _get_eval_string(arg, true) + })) + self + end + end + + def item_text(item, column, txt=nil, *args) + if args.empty? + if txt + tk_send('item', 'text', item, column, txt) + self + else + tk_send('item', 'text', item, column) + end + else + tk_send('item', 'text', item, column, txt, *args) + self + end + end + + def item_toggle(item) + tk_send('item', 'toggle', item) + self + end + + def item_toggle_recurse(item) + tk_send('item', 'toggle', item, '-recurse') + self + end + + def item_visible(item, st=None) + if st == None + bool(tk_send('item', 'visible', item)) + else + tk_send('item', 'visible', item, st) + self + end + end + def item_visible?(item) + item_visible(item) + end + + def marquee_anchor(*args) + if args.empty? + list(tk_send('marquee', 'anchor')) + else + tk_send('marquee', 'anchor', *args) + self + end + end + + def marquee_coords(*args) + if args.empty? + list(tk_send('marquee', 'coords')) + else + tk_send('marquee', 'coords', *args) + self + end + end + + def marquee_corner(*args) + if args.empty? + tk_send('marquee', 'corner') + else + tk_send('marquee', 'corner', *args) + self + end + end + + def marquee_identify() + list(tk_send('marquee', 'identify')).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def marquee_visible(st=None) + if st == None + bool(tk_send('marquee', 'visible')) + else + tk_send('marquee', 'visible', st) + self + end + end + def marquee_visible?() + marquee_visible() + end + + #def notify_bind(obj, event, cmd=Proc.new, *args) + # _bind([@path, 'notify', 'bind', obj], event, cmd, *args) + # self + #end + def notify_bind(obj, event, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([@path, 'notify', 'bind', obj], event, cmd, *args) + self + end + + #def notify_bind_append(obj, event, cmd=Proc.new, *args) + # _bind_append([@path, 'notify', 'bind', obj], event, cmd, *args) + # self + #end + def notify_bind_append(obj, event, *args) + # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([@path, 'notify', 'bind', obj], event, cmd, *args) + self + end + + def notify_bind_remove(obj, event) + _bind_remove([@path, 'notify', 'bind', obj], event) + self + end + + def notify_bindinfo(obj, event=nil) + _bindinfo([@path, 'notify', 'bind', obj], event) + end + + def notify_detailnames(event) + list(tk_send('notify', 'detailnames', event)) + end + + def notify_eventnames() + list(tk_send('notify', 'eventnames')) + end + + def notify_generate(pattern, char_map=None, percents_cmd=None) + pattern = "<#{pattern}>" + tk_send('notify', 'generate', pattern, char_map, percents_cmd) + self + end + + def notify_install(pattern, percents_cmd=nil, &b) + pattern = "<#{pattern}>" + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + procedure(tk_send('notify', 'install', pattern, percents_cmd)) + else + procedure(tk_send('notify', 'install', pattern)) + end + end + + def notify_install_detail(event, detail, percents_cmd=nil, &b) + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + tk_send('notify', 'install', 'detail', event, detail, percents_cmd) + else + tk_send('notify', 'install', 'detail', event, detail) + end + end + + def notify_install_event(event, percents_cmd=nil, &b) + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + tk_send('notify', 'install', 'event', event, percents_cmd) + else + tk_send('notify', 'install', 'event', event) + end + end + + def notify_linkage(pattern, detail=None) + if detail != None + tk_send('notify', 'linkage', pattern, detail) + else + begin + if pattern.to_s.index(?-) + # TreeCtrl 1.1 format? + begin + tk_send('notify', 'linkage', "<#{pattern}>") + rescue + # TreeCtrl 1.0? + tk_send('notify', 'linkage', pattern) + end + else + # TreeCtrl 1.0 format? + begin + tk_send('notify', 'linkage', pattern) + rescue + # TreeCtrl 1.1? + tk_send('notify', 'linkage', "<#{pattern}>") + end + end + end + end + end + + def notify_unbind(pattern=nil) + if pattern + tk_send('notify', 'unbind', "<#{pattern}>") + else + tk_send('notify', 'unbind') + end + self + end + + def notify_uninstall(pattern) + pattern = "<#{pattern}>" + tk_send('notify', 'uninstall', pattern) + self + end + + def notify_uninstall_detail(event, detail) + tk_send('notify', 'uninstall', 'detail', event, detail) + self + end + + def notify_uninstall_event(event) + tk_send('notify', 'uninstall', 'event', event) + self + end + + def numcolumns() + num_or_str(tk_send('numcolumns')) + end + alias num_columns numcolumns + alias columns_size numcolumns + + def numitems() + num_or_str(tk_send('numitems')) + end + alias num_items numitems + alias items_size numitems + + def orphans() + list(tk_send('orphans')).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def range(first, last) + list(tk_send('range', first, last)).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def state_define(name) + tk_send('state', 'define', name) + self + end + + def state_linkage(name) + tk_send('state', 'linkage', name) + end + + def state_names() + list(tk_send('state', 'names')) + end + + def state_undefine(*names) + tk_send('state', 'undefine', *names) + self + end + + def see(item) + tk_send('see', item) + self + end + + def selection_add(first, last=None) + tk_send('selection', 'add', first, last) + self + end + + def selection_anchor(item=None) + id = num_or_str(tk_send('selection', 'anchor', item)) + Tk::TreeCtrl::Item.id2obj(self, id) + end + + def selection_clear(*args) # first, last + tk_send('selection', 'clear', *args) + self + end + + def selection_count() + number(tk_send('selection', 'count')) + end + + def selection_get() + list(tk_send('selection', 'get')).collect!{|id| + Tk::TreeCtrl::Item.id2obj(self, id) + } + end + + def selection_includes(item) + bool(tk_send('selection', 'includes', item)) + end + + def selection_modify(sel, desel) + tk_send('selection', 'modify', sel, desel) + self + end + + def style_create(style, keys=None) + if keys && keys != None + tk_send('style', 'create', style, *hash_kv(keys)) + else + tk_send('style', 'create', style) + end + end + + def style_delete(*args) + if Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[self.path] + args.each{|sty| + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[self.path].delete(sty) + } + end + tk_send('style', 'delete', *args) + self + end + + def style_elements(style, *elems) + if elems.empty? + list(tk_send('style', 'elements', style)).collect!{|id| + Tk::TreeCtrl::Element.id2obj(self, id) + } + else + tk_send('style', 'elements', style, elems.flatten) + self + end + end + + def _conv_style_layout_val(sty, val) + case sty.to_s + when 'padx', 'pady', 'ipadx', 'ipady' + lst = list(val) + (lst.size == 1)? lst[0]: lst + when 'detach', 'indent' + bool(val) + when 'union' + simplelist(val).collect!{|elem| + Tk::TreeCtrl::Element.id2obj(self, elem) + } + else + val + end + end + private :_conv_style_layout_val + + def style_layout(style, elem, keys=None) + if keys && keys != None + if keys.kind_of?(Hash) + tk_send('style', 'layout', style, elem, *hash_kv(keys)) + self + else + _conv_style_layout_val(keys, + tk_send('style', 'layout', + style, elem, "-#{keys}")) + end + else + ret = Hash.new + Hash[*simplelist(tk_send('style', 'layout', style, elem))].each{|k, v| + k = k[1..-1] + ret[k] = _conv_style_layout_val(k, v) + } + ret + end + end + def get_style_layout(style, elem, opt=None) + style_layout(style, elem, opt) + end + def set_style_layout(style, elem, slot, value=None) + if slot.kind_of?(Hash) + style_layout(style, elem, slot) + else + style_layout(style, elem, {slot=>value}) + end + end + + def style_names() + list(tk_send('style', 'names')).collect!{|id| + Tk::TreeCtrl::Style.id2obj(self, id) + } + end + + def toggle(*items) + tk_send('toggle', *items) + self + end + + def toggle_recurse() + tk_send('toggle', '-recurse', *items) + self + end +end + +##################### + +class Tk::TreeCtrl::Column < TkObject + TreeCtrlColumnID_TBL = TkCore::INTERP.create_table + TreeCtrlColumnID = ['treectrl_column'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.clear} + + def self.id2obj(tree, id) + tpath = tree.path + return id unless Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath] + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath][id]? \ + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath][id] : id + end + + def initialize(parent, keys={}) + @tree = parent + @tpath = parent.path + + keys = _symbolkey2str(keys) + + @path = @id = + keys.delete('tag') || + Tk::TreeCtrl::Column::TreeCtrlColumnID.join(TkCore::INTERP._ip_id_) + + keys['tag'] = @id + + unless Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath] + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath] = {} + end + Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath][@id] = self + Tk::TreeCtrl::Column::TreeCtrlColumnID[1].succ! + + @tree.column_create(keys) + end + + def id + @id + end + + def to_s + @id.to_s.dup + end + + def cget(opt) + @tree.column_cget(@tree.column_index(@id), opt) + end + + def configure(*args) + @tree.column_configure(@tree.column_index(@id), *args) + end + + def configinfo(*args) + @tree.column_configinfo(@tree.column_index(@id), *args) + end + + def current_configinfo(*args) + @tree.current_column_configinfo(@tree.column_index(@id), *args) + end + + def delete + @tree.column_delete(@tree.column_index(@id)) + self + end + + def index + @tree.column_index(@id) + end + + def move(before) + @tree.column_move(@tree.column_index(@id), before) + self + end + + def needed_width + @tree.column_needed_width(@tree.column_index(@id)) + end + alias neededwidth needed_width + + def current_width + @tree.column_width(@tree.column_index(@id)) + end +end + +##################### + +class Tk::TreeCtrl::Element < TkObject + TreeCtrlElementID_TBL = TkCore::INTERP.create_table + TreeCtrlElementID = ['treectrl_element'.freeze, '00000'.taint].freeze + TreeCtrlElemTypeToClass = {} + + TkCore::INTERP.init_ip_env{ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.clear + } + + def self.type2class(type) + TreeCtrlElemTypeToClass[type] || type + end + + def self.id2obj(tree, id) + tpath = tree.path + return id unless Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath] + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath][id]? \ + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath][id] : id + end + + def initialize(parent, type, keys=nil) + @tree = parent + @tpath = parent.path + @type = type.to_s + @path = @id = + Tk::TreeCtrl::Element::TreeCtrlElementID.join(TkCore::INTERP._ip_id_) + unless Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath] + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath] = {} + end + Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath][@id] = self + Tk::TreeCtrl::Element::TreeCtrlElementID[1].succ! + + @tree.element_create(@id, @type, keys) + end + + def id + @id + end + + def to_s + @id.dup + end + + def cget(opt) + @tree.element_cget(@id, opt) + end + + def configure(*args) + @tree.element_configure(@id, *args) + end + + def configinfo(*args) + @tree.element_configinfo(@id, *args) + end + + def current_configinfo(*args) + @tree.current_element_configinfo(@id, *args) + end + + def delete + @tree.element_delete(@id) + self + end + + def element_type + @tree.element_type(@id) + end + + def element_class + @tree.element_class(@id) + end +end + +class Tk::TreeCtrl::BitmapElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['bitmap'] = self + + def initialize(parent, keys=nil) + super(parent, 'bitmap', keys) + end +end + +class Tk::TreeCtrl::BorderElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['border'] = self + + def initialize(parent, keys=nil) + super(parent, 'border', keys) + end +end + +class Tk::TreeCtrl::ImageElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['image'] = self + + def initialize(parent, keys=nil) + super(parent, 'image', keys) + end +end + +class Tk::TreeCtrl::RectangleElement < Tk::TreeCtrl::Element + TreeCtrlElemTypeToClass['rect'] = self + + def initialize(parent, keys=nil) + super(parent, 'rect', keys) + end +end + +##################### + +class Tk::TreeCtrl::Item < TkObject + TreeCtrlItemID_TBL = TkCore::INTERP.create_table + + TkCore::INTERP.init_ip_env{Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.clear} + + def self.id2obj(tree, id) + tpath = tree.path + return id unless Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath] + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath][id]? \ + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath][id] : id + end + + def initialize(parent, keys={}) + @tree = parent + @tpath = parent.path + @path = @id = @tree.item_create(keys) + + unless Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath] + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath] = {} + end + Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath][@id] = self + end + + def id + @id + end + + def to_s + @id.to_s.dup + end + + def ancestors + @tree.item_ancestors(@id) + end + + def bbox(*args) + @tree.item_bbox(@id, *args) + end + + def children + @tree.item_children(@id) + end + + def collapse + @tree.item_collapse(@id) + self + end + + def collapse_recurse + @tree.item_collapse_recurse(@id) + self + end + + def complex(*args) + @tree.item_complex(@id, *args) + self + end + + def cget(opt) + @tree.item_cget(@id, opt) + end + + def configure(*args) + @tree.item_configure(@id, *args) + end + + def configinfo(*args) + @tree.item_configinfo(@id, *args) + end + + def current_configinfo(*args) + @tree.current_item_configinfo(@id, *args) + end + + def delete + @tree.item_delete(@id) + self + end + + def element_dump + @tree.item_dump(@id) + end + + def element_dump_hash + @tree.item_dump_hash(@id) + end + + def element_actual(column, elem, key) + @tree.item_element_actual(@id, column, elem, key) + end + + def element_cget(opt) + @tree.item_element_cget(@id, opt) + end + + def element_configure(*args) + @tree.item_element_configure(@id, *args) + end + + def element_configinfo(*args) + @tree.item_element_configinfo(@id, *args) + end + + def current_element_configinfo(*args) + @tree.current_item_element_configinfo(@id, *args) + end + + def expand + @tree.item_expand(@id) + self + end + + def expand_recurse + @tree.item_expand_recurse(@id) + self + end + + def firstchild(child=nil) + if child + @tree.item_firstchild(@id, child) + self + else + @tree.item_firstchild(@id) + end + end + alias first_child firstchild + + def hasbutton(st=None) + if st == None + @tree.item_hasbutton(@id) + else + @tree.item_hasbutton(@id, st) + self + end + end + alias has_button hasbutton + + def hasbutton? + @tree.item_hasbutton(@id) + end + alias has_button? hasbutton? + + def index + @tree.item_index(@id) + end + + def isancestor(des) + @tree.item_isancestor(@id, des) + end + alias is_ancestor isancestor + alias isancestor? isancestor + alias is_ancestor? isancestor + alias ancestor? isancestor + + def isopen + @tree.item_isopen(@id) + end + alias is_open isopen + alias isopen? isopen + alias is_open? isopen + alias isopened? isopen + alias is_opened? isopen + alias open? isopen + + def lastchild(child=nil) + if child + @tree.item_lastchild(@id, child) + self + else + @tree.item_lastchild(@id) + end + end + alias last_child lastchild + + def nextsibling(nxt=nil) + if nxt + @tree.item_nextsibling(@id, nxt) + self + else + @tree.item_nextsibling(@id) + end + end + alias next_sibling nextsibling + + def numchildren + @tree.item_numchildren(@id) + end + alias num_children numchildren + alias children_size numchildren + + def parent_index + @tree.item_parent(@id) + end + + def prevsibling(nxt=nil) + if nxt + @tree.item_prevsibling(@id, nxt) + self + else + @tree.item_prevsibling(@id) + end + end + alias prev_sibling prevsibling + + def remove + @tree.item_remove(@id) + end + + def rnc + @tree.item_rnc(@id) + end + + def sort(*opts) + @tree.item_sort(@id, *opts) + end + def sort_not_really(*opts) + @tree.item_sort_not_really(@id, *opts) + self + end + + def state_forcolumn(column, *args) + @tree.item_state_forcolumn(@id, column, *args) + self + end + alias state_for_column state_forcolumn + + def state_get(*args) + @tree.item_state_get(@id, *args) + end + + def state_set(*args) + @tree.item_state_set(@id, *args) + self + end + + def style_elements(column) + @tree.item_style_elements(@id, column) + end + + def style_map(column, style, map) + @tree.item_style_map(@id, column, style, map) + self + end + + def style_set(column=nil, *args) + if args.empty? + @tree.item_style_set(@id, column) + else + @tree.item_style_set(@id, column, *args) + self + end + end + + def item_text(column, txt=nil, *args) + if args.empty? + if txt + @tree.item_text(@id, column, txt) + self + else + @tree.item_text(@id, column) + end + else + @tree.item_text(@id, column, txt, *args) + self + end + end + + def toggle + @tree.item_toggle(@id) + self + end + + def toggle_recurse + @tree.item_toggle_recurse(@id) + self + end + + def visible(st=None) + if st == None + @tree.item_visible(@id) + else + @tree.item_visible(@id, st) + self + end + end +end + +##################### + +class Tk::TreeCtrl::Style < TkObject + TreeCtrlStyleID_TBL = TkCore::INTERP.create_table + TreeCtrlStyleID = ['treectrl_style'.freeze, '00000'.taint].freeze + + TkCore::INTERP.init_ip_env{ Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.clear } + + def self.id2obj(tree, id) + tpath = tree.path + return id unless Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath] + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath][id]? \ + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath][id] : id + end + + def initialize(parent, keys=nil) + @tree = parent + @tpath = parent.path + @path = @id = + Tk::TreeCtrl::Style::TreeCtrlStyleID.join(TkCore::INTERP._ip_id_) + unless Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath] + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath] = {} + end + Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath][@id] = self + Tk::TreeCtrl::Style::TreeCtrlStyleID[1].succ! + + @tree.style_create(@id, keys) + end + + def id + @id + end + + def to_s + @id.dup + end + + def cget(opt) + @tree.style_cget(@id, opt) + end + + def configure(*args) + @tree.style_configure(@id, *args) + end + + def configinfo(*args) + @tree.style_configinfo(@id, *args) + end + + def current_configinfo(*args) + @tree.current_style_configinfo(@id, *args) + end + + def delete + @tree.style_delete(@id) + self + end + + def elements(*elems) + if elems.empty? + @tree.style_elements(@id) + else + @tree.style_elements(@id, *elems) + self + end + end + + def layout(elem, keys=None) + if keys && keys != None && keys.kind_of?(Hash) + @tree.style_layout(@id, elem, keys) + self + else + @tree.style_layout(@id, elem, keys) + end + end +end + +module Tk::TreeCtrl::BindCallback + include Tk + extend Tk +end + +class << Tk::TreeCtrl::BindCallback + def percentsCmd(*args) + tk_call('::TreeCtrl::PercentsCmd', *args) + end + def cursorCheck(w, x, y) + tk_call('::TreeCtrl::CursorCheck', w, x, y) + end + def cursorCheckAux(w) + tk_call('::TreeCtrl::CursorCheckAux', w) + end + def cursorCancel(w) + tk_call('::TreeCtrl::CursorCancel', w) + end + def buttonPress1(w, x, y) + tk_call('::TreeCtrl::ButtonPress1', w, x, y) + end + def doubleButton1(w, x, y) + tk_call('::TreeCtrl::DoubleButton1', w, x, y) + end + def motion1(w, x, y) + tk_call('::TreeCtrl::Motion1', w, x, y) + end + def leave1(w, x, y) + tk_call('::TreeCtrl::Leave1', w, x, y) + end + def release1(w, x, y) + tk_call('::TreeCtrl::Release1', w, x, y) + end + def beginSelect(w, el) + tk_call('::TreeCtrl::BeginSelect', w, el) + end + def motion(w, le) + tk_call('::TreeCtrl::Motion', w, el) + end + def beginExtend(w, el) + tk_call('::TreeCtrl::BeginExtend', w, el) + end + def beginToggle(w, el) + tk_call('::TreeCtrl::BeginToggle', w, el) + end + def cancelRepeat + tk_call('::TreeCtrl::CancelRepeat') + end + def autoScanCheck(w, x, y) + tk_call('::TreeCtrl::AutoScanCheck', w, x, y) + end + def autoScanCheckAux(w) + tk_call('::TreeCtrl::AutoScanCheckAux', w) + end + def autoScanCancel(w) + tk_call('::TreeCtrl::AutoScanCancel', w) + end + def up_down(w, n) + tk_call('::TreeCtrl::UpDown', w, n) + end + def left_right(w, n) + tk_call('::TreeCtrl::LeftRight', w, n) + end + def setActiveItem(w, idx) + tk_call('::TreeCtrl::SetActiveItem', w, idx) + end + def extendUpDown(w, amount) + tk_call('::TreeCtrl::ExtendUpDown', w, amount) + end + def dataExtend(w, el) + tk_call('::TreeCtrl::DataExtend', w, el) + end + def cancel(w) + tk_call('::TreeCtrl::Cancel', w) + end + def selectAll(w) + tk_call('::TreeCtrl::selectAll', w) + end + def marqueeBegin(w, x, y) + tk_call('::TreeCtrl::MarqueeBegin', w, x, y) + end + def marqueeUpdate(w, x, y) + tk_call('::TreeCtrl::MarqueeUpdate', w, x, y) + end + def marqueeEnd(w, x, y) + tk_call('::TreeCtrl::MarqueeEnd', w, x, y) + end + def scanMark(w, x, y) + tk_call('::TreeCtrl::ScanMark', w, x, y) + end + def scanDrag(w, x, y) + tk_call('::TreeCtrl::ScanDrag', w, x, y) + end + + # filelist-bindings + def fileList_button1(w, x, y) + tk_call('::TreeCtrl::FileListButton1', w, x, y) + end + def fileList_motion1(w, x, y) + tk_call('::TreeCtrl::FileListMotion1', w, x, y) + end + def fileList_motion(w, x, y) + tk_call('::TreeCtrl::FileListMotion', w, x, y) + end + def fileList_leave1(w, x, y) + tk_call('::TreeCtrl::FileListLeave1', w, x, y) + end + def fileList_release1(w, x, y) + tk_call('::TreeCtrl::FileListRelease1', w, x, y) + end + def fileList_edit(w, i, s, e) + tk_call('::TreeCtrl::FileListEdit', w, i, s, e) + end + def fileList_editCancel(w) + tk_call('::TreeCtrl::FileListEditCancel', w) + end + def fileList_autoScanCheck(w, x, y) + tk_call('::TreeCtrl::FileListAutoScanCheck', w, x, y) + end + def fileList_autoScanCheckAux(w) + tk_call('::TreeCtrl::FileListAutoScanCheckAux', w) + end + + def entryOpen(w, item, col, elem) + tk_call('::TreeCtrl::EntryOpen', w, item, col, elem) + end + def entryExpanderOpen(w, item, col, elem) + tk_call('::TreeCtrl::EntryExpanderOpen', w, item, col, elem) + end + def entryClose(w, accept) + tk_call('::TreeCtrl::EntryClose', w, accept) + end + def entryExpanderKeypress(w) + tk_call('::TreeCtrl::EntryExpanderKeypress', w) + end + def textOpen(w, item, col, elem, width=0, height=0) + tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width, height) + end + def textExpanderOpen(w, item, col, elem, width) + tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width) + end + def textClose(w, accept) + tk_call('::TreeCtrl::TextClose', w, accept) + end + def textExpanderKeypress(w) + tk_call('::TreeCtrl::TextExpanderKeypress', w) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/trofs.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/trofs.rb new file mode 100644 index 0000000000..5914e5165f --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/trofs.rb @@ -0,0 +1,13 @@ +# +# trofs support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/trofs/setup.rb' + +# load library +require 'tkextlib/trofs/trofs.rb' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/trofs/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/trofs/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/trofs/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/trofs/trofs.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/trofs/trofs.rb new file mode 100644 index 0000000000..7a2606a275 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/trofs/trofs.rb @@ -0,0 +1,51 @@ +# +# tkextlib/trofs/trofs.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/trofs/setup.rb' + +# TkPackage.require('trofs', '0.4') +TkPackage.require('trofs') + +module Tk + module Trofs + extend TkCore + + PACKAGE_NAME = 'trofs'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('trofs') + rescue + '' + end + end + + ############################################## + + def self.create_archive(dir, archive) + tk_call('::trofs::archive', dir, archive) + archive + end + + def self.mount(archive, mountpoint=None) + # returns the normalized path to mountpoint + tk_call('::trofs::mount', archive, mountpoint) + end + + def self.umount(mountpoint) + tk_call('::trofs::umount', mountpoint) + mountpoint + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/version.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/version.rb new file mode 100644 index 0000000000..c7816fd4a5 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/version.rb @@ -0,0 +1,6 @@ +# +# release date of tkextlib +# +module Tk + Tkextlib_RELEASE_DATE = '2007-05-26'.freeze +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu.rb new file mode 100644 index 0000000000..d2234eb2a8 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu.rb @@ -0,0 +1,48 @@ +# +# The vu widget set support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/vu/setup.rb' + +# load package +# TkPackage.require('vu', '2.1') +TkPackage.require('vu') + +# autoload +module Tk + module Vu + TkComm::TkExtlibAutoloadModule.unshift(self) + + PACKAGE_NAME = 'vu'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('vu') + rescue + '' + end + end + + ########################################## + + autoload :Dial, 'tkextlib/vu/dial' + + autoload :Pie, 'tkextlib/vu/pie' + autoload :PieSlice, 'tkextlib/vu/pie' + autoload :NamedPieSlice, 'tkextlib/vu/pie' + + autoload :Spinbox, 'tkextlib/vu/spinbox' + + autoload :Bargraph, 'tkextlib/vu/bargraph' + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu/bargraph.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/bargraph.rb new file mode 100644 index 0000000000..27ff3c7cd0 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/bargraph.rb @@ -0,0 +1,61 @@ +# +# ::vu::bargraph widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# create module/class +module Tk + module Vu + class Bargraph < TkWindow + end + end +end + + +# call setup script -- <libdir>/tkextlib/vu.rb +require 'tkextlib/vu.rb' + +class Tk::Vu::Bargraph < TkWindow + TkCommandNames = ['::vu::bargraph'.freeze].freeze + WidgetClassName = 'Bargraph'.freeze + WidgetClassNames[WidgetClassName] = self + + ############################### + + def __boolval_optkeys + ['showminmax', 'showvalue'] + end + private :__boolval_optkeys + + def __strval_optkeys + super() + [ + 'title', + 'barbackground', 'barcolor', 'barcolour', + 'tickcolor', 'tickcolour', + 'textcolor', 'textcolour', + ] + end + private :__strval_optkeys + + def __listval_optkeys + ['alabels', 'blabels'] + end + private :__listval_optkeys + + def __font_optkeys + ['alabfont', 'blabfont'] + end + private :__font_optkeys + + ############################### + + def set(val = None) + tk_call_without_enc(@path, 'set', val) + self + end + + def get() + num_or_str(tk_call_without_enc(@path, 'get')) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu/charts.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/charts.rb new file mode 100644 index 0000000000..ee4298fa1c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/charts.rb @@ -0,0 +1,53 @@ +# +# charts -- Create and manipulate canvas Add-On Items +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' +require 'tk/canvas' + +# call setup script -- <libdir>/tkextlib/vu.rb +require 'tkextlib/vu.rb' + +module Tk + module Vu + module ChartsConfig + include TkItemConfigOptkeys + def __item_boolval_optkeys(id) + super(id) << 'lefttrunc' << 'autocolor' + end + private :__item_boolval_optkeys + + def __item_strval_optkeys(id) + super(id) << 'bar' << 'color' << 'outline' << + 'fill' << 'scaleline' << 'stripline' + end + private :__item_strval_optkeys + + def __item_listval_optkeys(id) + super(id) << 'values' << 'tags' + end + private :__item_listval_optkeys + end + + class TkcSticker < TkcItem + include ChartsConfig + + CItemTypeName = 'sticker'.freeze + CItemTypeToClass[CItemTypeName] = self + end + + class TkcStripchart < TkcItem + include ChartsConfig + + CItemTypeName = 'stripchart'.freeze + CItemTypeToClass[CItemTypeName] = self + end + + class TkcBarchart < TkcItem + include ChartsConfig + + CItemTypeName = 'barchart'.freeze + CItemTypeToClass[CItemTypeName] = self + end + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu/dial.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/dial.rb new file mode 100644 index 0000000000..e27a38ae42 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/dial.rb @@ -0,0 +1,102 @@ +# +# ::vu::dial widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# create module/class +module Tk + module Vu + class Dial < TkWindow + end + end +end + +# call setup script -- <libdir>/tkextlib/vu.rb +require 'tkextlib/vu.rb' + +# define module/class +class Tk::Vu::Dial < TkWindow + TkCommandNames = ['::vu::dial'.freeze].freeze + WidgetClassName = 'Dial'.freeze + WidgetClassNames[WidgetClassName] = self + + ############################### + + def __methodcall_optkeys # { key=>method, ... } + {'coords'=>'coords'} + end + private :__methodcall_optkeys + + ############################### + + def coords(val = nil) + if val + tk_split_list(tk_send_without_enc('coords')) + else + tk_send_without_enc('coords', val) + self + end + end + + def constrain(val = None) + num_or_str(tk_call(@path, 'constrain', val)) + end + + def get(*args) + num_or_str(tk_call(@path, 'get', *args)) + end + + def identify(x, y) + tk_call(@path, 'identify', x, y) + end + + def get_label(val=nil) + if val + tk_call(@path, 'label', val) + else + ret = [] + lst = simplelist(tk_call(@path, 'label')) + while lst.size > 0 + ret << ([num_or_str(lst.shift)] << lst.shift) + end + end + end + + def set_label(val, str, *args) + tk_call(@path, 'label', val, str, *args) + self + end + + def set_label_constrain(val, str, *args) + tk_call(@path, 'label', '-constrain', val, str, *args) + self + end + + def get_tag(val=nil) + if val + tk_call(@path, 'tag', val) + else + ret = [] + lst = simplelist(tk_call(@path, 'tag')) + while lst.size > 0 + ret << ([num_or_str(lst.shift)] << lst.shift) + end + end + end + + def set_tag(val, str, *args) + tk_call(@path, 'tag', val, str, *args) + self + end + + def set_tag_constrain(val, str, *args) + tk_call(@path, 'tag', '-constrain', val, str, *args) + self + end + + def set(val = None) + tk_call_without_enc(@path, 'set', val) + self + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu/pie.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/pie.rb new file mode 100644 index 0000000000..78f3fa54da --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/pie.rb @@ -0,0 +1,235 @@ +# +# ::vu::pie widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# create module/class +module Tk + module Vu + module PieSliceConfigMethod + end + class Pie < TkWindow + end + class PieSlice < TkObject + end + class NamedPieSlice < PieSlice + end + end +end + +# call setup script -- <libdir>/tkextlib/vu.rb +require 'tkextlib/vu.rb' + +module Tk::Vu::PieSliceConfigMethod + include TkItemConfigMethod + + def __item_pathname(tagOrId) + if tagOrId.kind_of?(Tk::Vu::PieSlice) + self.path + ';' + tagOrId.id.to_s + else + self.path + ';' + tagOrId.to_s + end + end + private :__item_pathname +end + +class Tk::Vu::Pie < TkWindow + TkCommandNames = ['::vu::pie'.freeze].freeze + WidgetClassName = 'Pie'.freeze + WidgetClassNames[WidgetClassName] = self + + def __destroy_hook__ + Tk::Vu::PieSlice::SliceID_TBL.delete(@path) + end + + ############################### + + include Tk::Vu::PieSliceConfigMethod + + def tagid(tag) + if tag.kind_of?(Tk::Vu::PieSlice) + tag.id + else + # tag + _get_eval_string(tag) + end + end + + ############################### + + def delete(*glob_pats) + tk_call(@path, 'delete', *glob_pats) + self + end + + def explode(slice, *args) + tk_call(@path, 'explode', slice, *args) + self + end + + def explode_value(slice) + num_or_str(tk_call(@path, 'explode', slice)) + end + + def lower(slice, below=None) + tk_call(@path, 'lower', slice, below) + self + end + + def names(*glob_pats) + simplelist(tk_call(@path, 'names', *glob_pats)) + end + alias slices names + + def order(*args) + tk_call(@path, 'order', *args) + self + end + + def raise(slice, above=None) + tk_call(@path, 'raise', slice, above) + self + end + + def swap(slice1, slice2) + tk_call(@path, 'swap', slice1, slice2) + self + end + + def set(slice, *args) + num_or_str(tk_call(@path, 'set', slice, *args)) + end + alias set_value set + alias set_values set + alias create set + + def slice_value(slice) + num_or_str(tk_call(@path, 'set', slice)) + end + + def value(val = None) + num_or_str(tk_call_without_enc(@path, 'value')) + end + alias sum_value value +end + +class Tk::Vu::PieSlice + SliceID_TBL = TkCore::INTERP.create_table + Pie_Slice_ID = ['vu:pie'.freeze, '00000'.taint].freeze + TkCore::INTERP.init_ip_env{ SliceID_TBL.clear } + + def self.id2obj(pie, id) + pie_path = pie.path + return id unless SliceID_TBL[pie_path] + SliceID_TBL[pie_path][id]? SliceID_TBL[pie_path][id]: id + end + + def initialize(parent, *args) + unless parent.kind_of?(Tk::Vu::Pie) + fail ArgumentError, "expect a Tk::Vu::Pie instance for 1st argument" + end + @parent = @pie = parent + @ppath = parent.path + @path = @id = Pie_Slice_ID.join(TkCore::INTERP._ip_id_) + SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath] + SliceID_TBL[@ppath][@id] = self + Pie_Slice_ID[1].succ! + + if args[-1].kind_of?(Hash) + keys = args.unshift + end + @pie.set(@id, *args) + configure(keys) + end + + def id + @id + end + + def [](key) + cget key + end + + def []=(key,val) + configure key, val + val + end + + def cget(slot) + @pie.itemcget(@id, slot) + end + + def configure(*args) + @pie.itemconfigure(@id, *args) + self + end + + def configinfo(*args) + @pie.itemconfiginfo(@id, *args) + end + + def current_configinfo(*args) + @pie.current_itemconfiginfo(@id, *args) + end + + def delete + @pie.delete(@id) + end + + def explode(value) + @pie.explode(@id, value) + self + end + + def explode_value + @pie.explode_value(@id) + end + + def lower(other=None) + @pie.lower(@id, other) + self + end + + def raise(other=None) + @pie.raise(@id, other) + self + end + + def set(value) + @pie.set(@id, value) + self + end + alias set_value set + + def value + @pie.set(@id) + end +end + +class Tk::Vu::NamedPieSlice + def self.new(parent, name, *args) + if SliceID_TBL[parent.path] && SliceID_TBL[parent.path][name] + return SliceID_TBL[parent.path][name] + else + super(parent, name, *args) + end + end + + def initialize(parent, name, *args) + unless parent.kind_of?(Tk::Vu::Pie) + fail ArgumentError, "expect a Tk::Vu::Pie instance for 1st argument" + end + @parent = @pie = parent + @ppath = parent.path + @path = @id = name.to_s + SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath] + SliceID_TBL[@ppath][@id] = self + + if args[-1].kind_of?(Hash) + keys = args.unshift + end + @pie.set(@id, *args) + configure(keys) + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/vu/spinbox.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/spinbox.rb new file mode 100644 index 0000000000..b6499645a3 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/vu/spinbox.rb @@ -0,0 +1,22 @@ +# +# ::vu::spinbox widget +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +# a standard spinbox (<= 8.3) +# This is the same as the 8.4 core spinbox widget. +# +require 'tk' + +if (Tk::TK_MAJOR_VERSION < 8 || + (Tk::TK_MAJOR_VERSION == 8 && Tk::TK_MINOR_VERSION < 4)) + # call setup script -- <libdir>/tkextlib/vu.rb + require 'tkextlib/vu.rb' + + Tk.tk_call('namespace', 'import', '::vu::spinbox') +end + +module Tk + module Vu + Spinbox = TkSpinbox + end +end diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/winico.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/winico.rb new file mode 100644 index 0000000000..ce7b8eac5c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/winico.rb @@ -0,0 +1,14 @@ +# +# winico -- Windows Icon extension support +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/tktable/setup.rb' + +# load library +require 'tkextlib/winico/winico' diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/winico/setup.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/winico/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/winico/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ruby_1_8_6/ext/tk/lib/tkextlib/winico/winico.rb b/ruby_1_8_6/ext/tk/lib/tkextlib/winico/winico.rb new file mode 100644 index 0000000000..c53a3ff48c --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkextlib/winico/winico.rb @@ -0,0 +1,189 @@ +# +# tkextlib/winico/winico.rb +# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require 'tkextlib/winico/setup.rb' + +# TkPackage.require('winico', '0.5') +# TkPackage.require('winico', '0.6') +TkPackage.require('winico') + +module Tk + class Winico < TkObject + PACKAGE_NAME = 'winico'.freeze + def self.package_name + PACKAGE_NAME + end + + def self.package_version + begin + TkPackage.require('winico') + rescue + '' + end + end + end +end + +class Tk::Winico + WinicoID_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ WinicoID_TBL.clear } + + def self.id2obj(id) + (WinicoID_TBL.key?(id))? WinicoID_TBL[id] : id + end + + def self.info + simplelist(Tk.tk_call('winico', 'info')).collect{|id| + Tk::Winico.id2obj(id) + } + end + + def self.icon_info(id) + simplelist(Tk.tk_call('winico', 'info', id)).collect{|inf| + h = Hash[*list(inf)] + h.keys.each{|k| h[k[1..-1]] = h.delete(k)} + } + end + + ################################# + + def self.new_from_file(file_name) + self.new(file_name) + end + + def self.new_from_resource(resource_name, file_name = nil) + self.new(file_name, resource_name) + end + + def initialize(file_name, resource_name=nil, winico_id=nil) + if resource_name + # from resource + if file_name + @id = Tk.tk_call('winico', 'load', resource_name, file_name) + else + @id = Tk.tk_call('winico', 'load', resource_name) + end + elsif file_name + # from .ico file + @id = Tk.tk_call('winico', 'createfrom', file_name) + elsif winico_id + @id = winico_id + else + fail ArgumentError, + "must be given proper information from where loading icons" + end + @path = @id + WinicoID_TBL[@id] = self + end + + def id + @id + end + + def set_window(win_id, *opts) # opts := ?'big'|'small'?, ?pos? + # NOTE:: the window, which is denoted by win_id, MUST BE MAPPED. + # If not, then this may fail or crash. + tk_call('winico', 'setwindow', win_id, @id, *opts) + end + + def delete + tk_call('winico', 'delete', @id) + WinicoID_TBL.delete(@id) + self + end + alias destroy delete + + def info + Tk::Winico.icon_info(@id) + end + + ################################# + + class Winico_callback < TkValidateCommand + class ValidateArgs < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?m, ?s, :message ], + [ ?i, ?x, :icon ], + [ ?x, ?n, :x ], + [ ?y, ?n, :y ], + [ ?X, ?n, :last_x ], + [ ?Y, ?n, :last_y ], + [ ?t, ?n, :tickcount ], + [ ?w, ?n, :icon_idnum ], + [ ?l, ?n, :msg_idnum ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:number) ], + [ ?s, TkComm.method(:string) ], + [ ?x, proc{|id| + if Tk::Winico::WinicoID_TBL.key?(id) + Tk::Winico::WinicoID_TBL[id] + else + Tk::Winico.new(nil, nil, id) + end + } ], + nil + ] + + _setup_subst_table(KEY_TBL, PROC_TBL); + + def self.ret_val(val) + val + end + end + + def self._config_keys + ['callback'] + end + end + + ################################# + + def add_to_taskbar(keys = {}) + keys = _symbolkey2str(keys) + Winico_callback._config_keys.each{|k| + if keys[k].kind_of?(Array) + cmd, *args = keys[k] + keys[k] = Winico_callback.new(cmd, args.join(' ')) + # elsif keys[k].kind_of?(Proc) + elsif TkComm._callback_entry?(keys[k]) + keys[k] = Winico_callback.new(keys[k]) + end + } + tk_call('winico', 'taskbar', 'add', @id, *(hash_kv(keys))) + self + end + alias taskbar_add add_to_taskbar + + def modify_taskbar(keys = {}) + keys = _symbolkey2str(keys) + Winico_callback._config_keys.each{|k| + if keys[k].kind_of?(Array) + cmd, *args = keys[k] + keys[k] = Winico_callback.new(cmd, args.join(' ')) + # elsif keys[k].kind_of?(Proc) + elsif TkComm._callback_entry?(keys[k]) + keys[k] = Winico_callback.new(keys[k]) + end + } + tk_call('winico', 'taskbar', 'modify', @id, *(hash_kv(keys))) + self + end + alias taskbar_modify modify_taskbar + + def delete_from_taskbar + tk_call('winico', 'taskbar', 'delete', @id) + self + end + alias taskbar_delete delete_from_taskbar +end diff --git a/ruby_1_8_6/ext/tk/lib/tkfont.rb b/ruby_1_8_6/ext/tk/lib/tkfont.rb new file mode 100644 index 0000000000..38a96633de --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkfont.rb @@ -0,0 +1,4 @@ +# +# tkfont.rb - load tk/font.rb +# +require 'tk/font' diff --git a/ruby_1_8_6/ext/tk/lib/tkmacpkg.rb b/ruby_1_8_6/ext/tk/lib/tkmacpkg.rb new file mode 100644 index 0000000000..35560e78ce --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkmacpkg.rb @@ -0,0 +1,4 @@ +# +# tkmacpkg.rb - load tk/macpkg.rb +# +require 'tk/macpkg' diff --git a/ruby_1_8_6/ext/tk/lib/tkmenubar.rb b/ruby_1_8_6/ext/tk/lib/tkmenubar.rb new file mode 100644 index 0000000000..70214fda1a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkmenubar.rb @@ -0,0 +1,4 @@ +# +# tkmenubar.rb - load tk/menubar.rb +# +require 'tk/menubar' diff --git a/ruby_1_8_6/ext/tk/lib/tkmngfocus.rb b/ruby_1_8_6/ext/tk/lib/tkmngfocus.rb new file mode 100644 index 0000000000..fe70950e8e --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkmngfocus.rb @@ -0,0 +1,4 @@ +# +# tkmngfocus.rb - load tk/mngfocus.rb +# +require 'tk/mngfocus' diff --git a/ruby_1_8_6/ext/tk/lib/tkpalette.rb b/ruby_1_8_6/ext/tk/lib/tkpalette.rb new file mode 100644 index 0000000000..56b203bbb9 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkpalette.rb @@ -0,0 +1,4 @@ +# +# tkpalette.rb - load tk/palette.rb +# +require 'tk/palette' diff --git a/ruby_1_8_6/ext/tk/lib/tkscrollbox.rb b/ruby_1_8_6/ext/tk/lib/tkscrollbox.rb new file mode 100644 index 0000000000..6093b2e4e7 --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkscrollbox.rb @@ -0,0 +1,4 @@ +# +# tkscrollbox.rb - load tk/scrollbox.rb +# +require 'tk/scrollbox' diff --git a/ruby_1_8_6/ext/tk/lib/tktext.rb b/ruby_1_8_6/ext/tk/lib/tktext.rb new file mode 100644 index 0000000000..97ad62a3ea --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tktext.rb @@ -0,0 +1,4 @@ +# +# tktext.rb - load tk/text.rb +# +require 'tk/text' diff --git a/ruby_1_8_6/ext/tk/lib/tkvirtevent.rb b/ruby_1_8_6/ext/tk/lib/tkvirtevent.rb new file mode 100644 index 0000000000..f4fae19a0a --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkvirtevent.rb @@ -0,0 +1,4 @@ +# +# tkvirtevent.rb - load tk/virtevent.rb +# +require 'tk/virtevent' diff --git a/ruby_1_8_6/ext/tk/lib/tkwinpkg.rb b/ruby_1_8_6/ext/tk/lib/tkwinpkg.rb new file mode 100644 index 0000000000..83371c546d --- /dev/null +++ b/ruby_1_8_6/ext/tk/lib/tkwinpkg.rb @@ -0,0 +1,4 @@ +# +# tkwinpkg.rb - load tk/winpkg.rb +# +require 'tk/winpkg' |