TkComposite Fix

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…

Anyway, here’s the version of configure that I hacked together to fix
the above mentioned problem, and another function which is useful

def method_configure(*methodnames)
@methodnames += methodnames.map {|m| m.to_s}
end

def configure(slot, value=None)
if slot.kind_of? Hash then
slot.each{|slot,value| configure slot, value}
elsif (meth = @methodnames.find {|m| m == slot.to_s}) then
self.send(meth.intern, value)
elsif @delegates and [slot, ‘DEFAULT’].any? {|slot_key|
@delegates.has_key?(slot_key)} then
last = nil
@delegates[@delegates.has_key?(slot) ? slot : ‘DEFAULT’].each
{|i| last = i.configure(slot, value)}
last
else
super
end
end

@methodnames is initialized to [] inside initialize. This way, you
can just do the following:

inside some class using TkComposite

method_configure(:scrollbars, :width, :

and whenever you configure a la

TkMoo.new(parent, ‘scrollbars’=>‘x’, …)

it will call your scrollbars function and do all that needs to be

done.

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)

Message-ID: 20040511.182644.74754194.nagai@ai.kyutech.ac.jp

On the latest CVS, TkComposite class is in tk/composite.rb.
^^^^^^^^^^^^^^^^^
TkComposite module

Sorry.

···

From: Hidetoshi NAGAI nagai@ai.kyutech.ac.jp
Subject: Re: TkComposite Fix
Date: Tue, 11 May 2004 18:26:46 +0900

                              Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)