require 'tk'
module Tk::ScrollbarComposite
include TkComposite
def component_construct_keys
[]
end
private :component_construct_keys
def create_component(keys={})
end
private :create_component
def component_delegates
end
private :component_delegates
def define_delegates
option_methods([:scrollbarwidth, :get_scrollbarwidth])
delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll)
delegate_alias('framebackground', 'background',
@frame, @h_scroll, @v_scroll)
delegate_alias('activeframebackground', 'activebackground',
@h_scroll, @v_scroll)
delegate('DEFAULT', @component)
delegate('troughcolor', @h_scroll, @v_scroll)
delegate('repeatdelay', @h_scroll, @v_scroll)
delegate('repeatinterval', @h_scroll, @v_scroll)
delegate('borderwidth', @frame)
delegate('relief', @frame)
component_delegates
end
private :define_delegates
DEFAULT_VSCROLL = true
DEFAULT_HSCROLL = true
def initialize_composite(keys={})
keys = _symbolkey2str(keys)
@v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')
@h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal')
construct_keys = {}
((component_construct_keys.map{|k| k.to_s}) & keys.keys).each{|k|
construct_keys[k] = keys.delete(k)
}
@component = create_component(construct_keys)
@path = @component.path
@component.xscrollbar(@h_scroll)
@component.yscrollbar(@v_scroll)
TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)
TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)
@component.grid('row'=>0, 'column'=>0, 'sticky'=>'news')
vscroll(keys.delete('vscroll'){self.class::DEFAULT_VSCROLL})
hscroll(keys.delete('hscroll'){self.class::DEFAULT_HSCROLL})
define_delegates
configure keys unless keys.empty?
end
private :initialize_composite
def get_scrollbarwidth
@v_scroll.width
end
def set_scrollbarwidth(width)
@v_scroll.width(width)
@h_scroll.width(width)
end
alias :scrollbarwidth :set_scrollbarwidth
def hook_vscroll_on(*args); end
def hook_vscroll_off(*args); end
def hook_hscroll_on(*args); end
def hook_hscroll_off(*args); end
private :hook_vscroll_on,:hook_vscroll_off,:hook_hscroll_on,:hook_hscroll_off
def vscroll(mode, *args)
st = TkGrid.info(@v_scroll)
if mode && st.size == 0 then
@v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
hook_vscroll_on(*args)
elsif !mode && st.size != 0 then
@v_scroll.ungrid
hook_vscroll_off(*args)
end
self
end
def hscroll(mode, *args)
st = TkGrid.info(@h_scroll)
if mode && st.size == 0 then
@h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
hook_hscroll_on(*args)
elsif !mode && st.size != 0 then
@h_scroll.ungrid
hook_hscroll_off(*args)
end
self
end
end
class TkTextFrame < TkText
include Tk::ScrollbarComposite
def create_component(keys={})
@text = TkText.new(@frame, 'wrap'=>'none')
@text.configure(keys) unless keys.empty?
option_methods(
[:textbackground, nil, :textbg_info],
:textborderwidth,
:textrelief
)
@text
end
private :create_component
def hook_hscroll_on(wrap_mode=nil)
if wrap_mode
wrap wrap_mode
else
wrap 'none' end
end
def hook_hscroll_off(wrap_mode)
wrap wrap_mode end
def hscroll(mode, wrap_mode="char")
super
end
def textbackground(color = nil)
if color
@text.background(color)
else
@text.background
end
end
def textbg_info
info = @text.configinfo(:background)
if TkComm::GET_CONFIGINFO_AS_ARRAY
info[0] = 'textbackground'
info
else {'textbackground' => info['background']}
end
end
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
def textrelief(type)
@text.relief(type)
end
end
if __FILE__ == $0
TkLabel.new(:text=>'TkTextFrame is an example of Tk::ScrollbarComposite module.').pack
f = TkFrame.new.pack('fill'=>'x')
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',
'command'=>proc{t.vscroll(true)}).pack('side'=>'right')
TkButton.new(f, 'text'=>'hscr ON',
'command'=>proc{t.hscroll(true)}).pack('side'=>'left')
TkButton.new(f, 'text'=>'hscr OFF',
'command'=>proc{t.hscroll(false)}).pack('side'=>'left')
TkFrame.new.pack(:pady=>10)
TkLabel.new(:text=>'The following is another example of Tk::ScrollbarComposite module.').pack
class ScrListbox < TkListbox
include Tk::ScrollbarComposite
DEFAULT_HSCROLL = false
def create_component(keys={})
TkListbox.new(@frame, keys)
end
private :create_component
end
f = TkFrame.new.pack(:pady=>5)
lbox = ScrListbox.new(f).pack(:side=>:left)
lbox.value = %w(aa bb cc dd eeeeeeeeeeeeeeeeeeeeeeeeee ffffffffff gg hh ii jj kk ll mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm nn oo pp qq)
fb = TkFrame.new(f).pack(:expand=>true, :fill=>:y, :padx=>5)
TkButton.new(fb, 'text'=>'lbox hscr OFF',
'command'=>proc{lbox.hscroll(false)}).pack(:side=>:bottom,
:fill=>:x)
TkButton.new(fb, 'text'=>'lbox hscr ON',
'command'=>proc{lbox.hscroll(true)}).pack(:side=>:bottom,
:fill=>:x)
TkFrame.new(fb).pack(:pady=>5, :side=>:bottom)
TkButton.new(fb, 'text'=>'lbox vscr OFF',
'command'=>proc{lbox.vscroll(false)}).pack(:side=>:bottom,
:fill=>:x)
TkButton.new(fb, 'text'=>'lbox vscr ON',
'command'=>proc{lbox.vscroll(true)}).pack(:side=>:bottom,
:fill=>:x)
Tk.mainloop
end