From: Hidetoshi NAGAI Date: 2004-05-11T18:26:46+09:00 Subject: Re: TkComposite Fix Hi, From: mhm26@drexel.edu (matt) Subject: TkComposite Fix Date: Mon, 10 May 2004 06:48:54 +0900 Message-ID: <13383d7a.0405091347.7ad64fa2@posting.google.com> > I noticed that TkComposite had a bug in it by refering to the default > slot for delegation as DEFALUT in configure. I also noticed that > TkComposite isn't in the tk.rb in cvs... On the latest CVS, TkComposite class is in tk/composite.rb. The library file is autoloaded when TkComposite is refered (see tk/autoload.rb). > Anyway, here's the version of configure that I hacked together to fix > the above mentioned problem, and another function which is useful Thank you for your report. Based on your proposal, I'm working for improving tk/composite.rb. Please see the attached source script. If it satisfies you, I'll commit it. ---------------------------------------- # # tk/composite.rb : # require 'tk' module TkComposite include Tk extend Tk 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) # @delegates['DEFAULT'] = [@frame] @path = @epath = @frame.path initialize_composite(keys) else @frame = TkFrame.new(parent) # @delegates['DEFAULT'] = [@frame] @path = @epath = @frame.path initialize_composite(*args) end end def epath @epath end def initialize_composite(*args) end private :initialize_composite def 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(option, *wins) option = option.to_s if @delegates[option].kind_of?(Array) wins.each{|w| @delegates[option].push(w) } else @delegates[option] = wins end 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 return @option_setting[slot] end end wins = @delegates[slot] wins = @delegates['DEFAULT'] unless wins if wins && wins[-1] wins[-1].cget(slot) else super end 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) @option_setting[slot] = value if @option_methods[slot][:cget] return self.__send__(@option_methods[slot][:set], value) end wins = @delegates[slot] wins = @delegates['DEFAULT'] unless wins if wins last = nil wins.each{|w| last = w.configure(slot, value)} last else super end 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 wins = @delegates[slot] wins = @delegates['DEFAULT'] unless wins if wins && wins[-1] wins[-1].configinfo(slot) else super end else # slot == nil info_list = super wins = @delegates['DEFAULT'] if wins && wins[-1] wins[-1].configinfo.each{|info| slot = info[0] info_list.delete_if{|i| i[0] == slot} << info } end @delegates.each{|slot, wins| if slot != 'DEFAULT' && wins && wins[-1] info_list.delete_if{|i| i[0] == slot} << wins[-1].configinfo(slot) 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 wins = @delegates[slot] wins = @delegates['DEFAULT'] unless wins if wins && wins[-1] wins[-1].configinfo(slot) else super end else # slot == nil info_list = super wins = @delegates['DEFAULT'] info_list.update(wins[-1].configinfo) if wins && wins[-1] @delegates.each{|slot, wins| next if slot == 'DEFAULT' info_list.update(wins[-1].configinfo(slot)) if wins && wins[-1] } @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 ---------------------------------------- -- Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)