1# 2# tktextframe.rb : a sample of TkComposite 3# 4# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) 5# 6require 'tk' 7 8module Tk::ScrollbarComposite 9 include TkComposite 10 11 def component_construct_keys 12 # If a component requires options for construction, 13 # return an Array of option-keys. 14 [] 15 end 16 private :component_construct_keys 17 18 def create_component(keys={}) 19 # This method must return the created component widget. 20 end 21 private :create_component 22 23 def component_delegates 24 # if want to override defalut option-methods or delegates, 25 # please define here. 26 end 27 private :component_delegates 28 29 def define_delegates 30 # option methods for scrollbars 31 option_methods([:scrollbarwidth, :get_scrollbarwidth]) 32 33 # set receiver widgets for configure methods (with alias) 34 delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll) 35 delegate_alias('framebackground', 'background', 36 @frame, @h_scroll, @v_scroll) 37 delegate_alias('activeframebackground', 'activebackground', 38 @h_scroll, @v_scroll) 39 40 # set receiver widgets for configure methods 41 delegate('DEFAULT', @component) 42 delegate('troughcolor', @h_scroll, @v_scroll) 43 delegate('repeatdelay', @h_scroll, @v_scroll) 44 delegate('repeatinterval', @h_scroll, @v_scroll) 45 delegate('borderwidth', @frame) 46 delegate('relief', @frame) 47 48 component_delegates 49 end 50 private :define_delegates 51 52 DEFAULT_VSCROLL = true 53 DEFAULT_HSCROLL = true 54 55 def initialize_composite(keys={}) 56 keys = _symbolkey2str(keys) 57 58 # create scrollbars 59 @v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical') 60 @h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal') 61 62 # create a component 63 construct_keys = {} 64 ((component_construct_keys.map{|k| k.to_s}) & keys.keys).each{|k| 65 construct_keys[k] = keys.delete(k) 66 } 67 68 # create a component (the component must be scrollable) 69 @component = create_component(construct_keys) 70 71 # set default receiver of method calls 72 @path = @component.path 73 74 # assign scrollbars 75 @component.xscrollbar(@h_scroll) 76 @component.yscrollbar(@v_scroll) 77 78 # allignment 79 TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0) 80 TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0) 81 @component.grid('row'=>0, 'column'=>0, 'sticky'=>'news') 82 83 # scrollbars ON 84 vscroll(keys.delete('vscroll'){self.class::DEFAULT_VSCROLL}) 85 hscroll(keys.delete('hscroll'){self.class::DEFAULT_HSCROLL}) 86 87 # do configure 88 define_delegates 89 90 # do configure 91 configure keys unless keys.empty? 92 end 93 private :initialize_composite 94 95 # get/set width of scrollbar 96 def get_scrollbarwidth 97 @v_scroll.width 98 end 99 def set_scrollbarwidth(width) 100 @v_scroll.width(width) 101 @h_scroll.width(width) 102 end 103 alias :scrollbarwidth :set_scrollbarwidth 104 105 def hook_vscroll_on(*args); end 106 def hook_vscroll_off(*args); end 107 def hook_hscroll_on(*args); end 108 def hook_hscroll_off(*args); end 109 private :hook_vscroll_on,:hook_vscroll_off,:hook_hscroll_on,:hook_hscroll_off 110 111 # vertical scrollbar : ON/OFF 112 def vscroll(mode, *args) 113 st = TkGrid.info(@v_scroll) 114 if mode && st.size == 0 then 115 @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns') 116 hook_vscroll_on(*args) 117 elsif !mode && st.size != 0 then 118 @v_scroll.ungrid 119 hook_vscroll_off(*args) 120 end 121 self 122 end 123 124 # horizontal scrollbar : ON/OFF 125 def hscroll(mode, *args) 126 st = TkGrid.info(@h_scroll) 127 if mode && st.size == 0 then 128 @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew') 129 hook_hscroll_on(*args) 130 elsif !mode && st.size != 0 then 131 @h_scroll.ungrid 132 hook_hscroll_off(*args) 133 end 134 self 135 end 136end 137 138################################################ 139 140class TkTextFrame < TkText 141 include Tk::ScrollbarComposite 142 143 # def component_construct_keys; []; end 144 # private :component_construct_keys 145 146 def create_component(keys={}) 147 # keys has options which are listed by component_construct_keys method. 148 @text = TkText.new(@frame, 'wrap'=>'none') 149 @text.configure(keys) unless keys.empty? 150 151 # option methods for component 152 option_methods( 153 [:textbackground, nil, :textbg_info], 154 :textborderwidth, 155 :textrelief 156 ) 157 158 # return the created componet 159 @text 160 end 161 private :create_component 162 163 # def component_delegates; end 164 # private :component_delegates 165 166 def hook_hscroll_on(wrap_mode=nil) 167 if wrap_mode 168 wrap wrap_mode 169 else 170 wrap 'none' # => self.wrap('none') 171 end 172 end 173 def hook_hscroll_off(wrap_mode) 174 wrap wrap_mode # => self.wrap(wrap_mode) 175 end 176 def hscroll(mode, wrap_mode="char") 177 super 178 end 179 180 # set background color of text widget 181 def textbackground(color = nil) 182 if color 183 @text.background(color) 184 else 185 @text.background 186 end 187 end 188 189 def textbg_info 190 info = @text.configinfo(:background) 191 if TkComm::GET_CONFIGINFO_AS_ARRAY 192 info[0] = 'textbackground' 193 info 194 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY 195 {'textbackground' => info['background']} 196 end 197 end 198 199 # get/set borderwidth of text widget 200 def set_textborderwidth(width) 201 @text.borderwidth(width) 202 end 203 def get_textborderwidth 204 @text.borderwidth 205 end 206 def textborderwidth(width = nil) 207 if width 208 set_textborderwidth(width) 209 else 210 get_textborderwidth 211 end 212 end 213 214 # set relief of text widget 215 def textrelief(type) 216 @text.relief(type) 217 end 218end 219 220################################################ 221# test 222################################################ 223if __FILE__ == $0 224 TkLabel.new(:text=>'TkTextFrame is an example of Tk::ScrollbarComposite module.').pack 225 f = TkFrame.new.pack('fill'=>'x') 226 #t = TkTextFrame.new.pack 227 t = TkTextFrame.new(:textborderwidth=>3, 228 :textrelief=>:ridge, 229 :scrollbarrelief=>:ridge).pack 230 p t.configinfo 231 TkButton.new(f, 'text'=>'vscr OFF', 232 'command'=>proc{t.vscroll(false)}).pack('side'=>'right') 233 TkButton.new(f, 'text'=>'vscr ON', 234 'command'=>proc{t.vscroll(true)}).pack('side'=>'right') 235 TkButton.new(f, 'text'=>'hscr ON', 236 'command'=>proc{t.hscroll(true)}).pack('side'=>'left') 237 TkButton.new(f, 'text'=>'hscr OFF', 238 'command'=>proc{t.hscroll(false)}).pack('side'=>'left') 239 240 ############################################ 241 242 # Tk.default_widget_set = :Ttk 243 244 TkFrame.new.pack(:pady=>10) 245 TkLabel.new(:text=>'The following is another example of Tk::ScrollbarComposite module.').pack 246 247 #---------------------------------- 248 class ScrListbox < TkListbox 249 include Tk::ScrollbarComposite 250 251 DEFAULT_HSCROLL = false 252 253 def create_component(keys={}) 254 TkListbox.new(@frame, keys) 255 end 256 private :create_component 257 end 258 #---------------------------------- 259 260 f = TkFrame.new.pack(:pady=>5) 261 lbox = ScrListbox.new(f).pack(:side=>:left) 262 lbox.value = %w(aa bb cc dd eeeeeeeeeeeeeeeeeeeeeeeeee ffffffffff gg hh ii jj kk ll mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm nn oo pp qq) 263 fb = TkFrame.new(f).pack(:expand=>true, :fill=>:y, :padx=>5) 264 TkButton.new(fb, 'text'=>'lbox hscr OFF', 265 'command'=>proc{lbox.hscroll(false)}).pack(:side=>:bottom, 266 :fill=>:x) 267 TkButton.new(fb, 'text'=>'lbox hscr ON', 268 'command'=>proc{lbox.hscroll(true)}).pack(:side=>:bottom, 269 :fill=>:x) 270 TkFrame.new(fb).pack(:pady=>5, :side=>:bottom) 271 TkButton.new(fb, 'text'=>'lbox vscr OFF', 272 'command'=>proc{lbox.vscroll(false)}).pack(:side=>:bottom, 273 :fill=>:x) 274 TkButton.new(fb, 'text'=>'lbox vscr ON', 275 'command'=>proc{lbox.vscroll(true)}).pack(:side=>:bottom, 276 :fill=>:x) 277 278 ############################################ 279 280 Tk.mainloop 281end 282