From d1dc51319f76a3b6ac32a2fd17da11cbf790ba6d Mon Sep 17 00:00:00 2001 From: nagai Date: Wed, 12 May 2004 04:24:55 +0000 Subject: * ext/tk/lib/tk/composite.rb: improve configure methods. (based on the proposal of [ruby-talk:99671]) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6294 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 + ext/tk/lib/tk/composite.rb | 263 ++++++++++++++++++++++++++++++++++++++++--- ext/tk/sample/tktextframe.rb | 58 +++++++++- 3 files changed, 308 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 20b90758c5..d947240d5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed May 12 13:20:19 2004 Hidetoshi NAGAI + + * ext/tk/lib/tk/composite.rb: improve configure methods (based on + the proposal of [ruby-talk:99671]). + Wed May 12 11:51:08 2004 Dave Thomas * class.c (rb_obj_singleton_methods): fix rdoc diff --git a/ext/tk/lib/tk/composite.rb b/ext/tk/lib/tk/composite.rb index ed7796aafb..ac5ed2f171 100644 --- a/ext/tk/lib/tk/composite.rb +++ b/ext/tk/lib/tk/composite.rb @@ -8,18 +8,18 @@ module TkComposite extend Tk def initialize(parent=nil, *args) - @delegates = {} + @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 @@ -32,32 +32,261 @@ module TkComposite def initialize_composite(*args) end private :initialize_composite - def delegate(option, *wins) - if @delegates[option].kind_of?(Array) - for i in wins - @delegates[option].push(i) + 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[option] = wins + @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 + end + def configure(slot, value=None) if slot.kind_of? Hash slot.each{|slot,value| configure slot, value} - else - if @delegates and @delegates[slot] - for i in @delegates[slot] - if not i - i = @delegates['DEFALUT'] - redo + 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 + 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 - last = i.configure(slot, value) + return [slot, '', '', '', self.cget(slot)] end end - last - else + + 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 + + else # slot == nil + info_list = super + + 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 + + else # slot == nil + info_list = super + + 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 diff --git a/ext/tk/sample/tktextframe.rb b/ext/tk/sample/tktextframe.rb index 5d16f2b0be..72bc7c1876 100644 --- a/ext/tk/sample/tktextframe.rb +++ b/ext/tk/sample/tktextframe.rb @@ -35,8 +35,20 @@ class TkTextFrame < TkText hscroll(keys.delete('hscroll'){true}) # set background of the text widget +=begin color = keys.delete('textbackground') textbackground(color) if color +=end + # please check the differences of the following definitions + option_methods( + [:scrollbarwidth, :get_scrollbarwidth], + [:textbackground, nil, :textbg_info], + :textborderwidth, + :textrelief + ) + + # set receiver widgets for configure methods (with alias) + delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll) # set receiver widgets for configure methods delegate('DEFAULT', @text) @@ -62,6 +74,46 @@ class TkTextFrame < TkText end end + def textbg_info + info = @text.configinfo(:background) + if TkComm::GET_CONFIGINFO_AS_ARRAY + info[0] = 'textbackground' + info + else # ! TkComm::GET_CONFIGINFO_AS_ARRAY + {'textbackground' => info['background']} + end + end + + # get/set borderwidth of text widget + def set_textborderwidth(width) + @text.borderwidth(width) + end + def get_textborderwidth + @text.borderwidth + end + def textborderwidth(width = nil) + if width + set_textborderwidth(width) + else + get_textborderwidth + end + end + + # set relief of text widget + def textrelief(type) + @text.relief(type) + end + + # get/set width of scrollbar + def get_scrollbarwidth + @v_scroll.width + end + def set_scrollbarwidth(width) + @v_scroll.width(width) + @h_scroll.width(width) + end + alias :scrollbarwidth :set_scrollbarwidth + # vertical scrollbar : ON/OFF def vscroll(mode) st = TkGrid.info(@v_scroll) @@ -93,7 +145,11 @@ end ################################################ if __FILE__ == $0 f = TkFrame.new.pack('fill'=>'x') - t = TkTextFrame.new.pack + #t = TkTextFrame.new.pack + t = TkTextFrame.new(:textborderwidth=>3, + :textrelief=>:ridge, + :scrollbarrelief=>:ridge).pack + p t.configinfo TkButton.new(f, 'text'=>'vscr OFF', 'command'=>proc{t.vscroll(false)}).pack('side'=>'right') TkButton.new(f, 'text'=>'vscr ON', -- cgit v1.2.3