diff options
Diffstat (limited to 'ext/tk/sample/tkmultilistframe.rb')
-rw-r--r-- | ext/tk/sample/tkmultilistframe.rb | 941 |
1 files changed, 0 insertions, 941 deletions
diff --git a/ext/tk/sample/tkmultilistframe.rb b/ext/tk/sample/tkmultilistframe.rb deleted file mode 100644 index 5e07b4e230..0000000000 --- a/ext/tk/sample/tkmultilistframe.rb +++ /dev/null @@ -1,941 +0,0 @@ -# frozen_string_literal: false -# -# tkmultilistframe.rb : multiple listbox widget on scrollable frame -# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) -# -require 'tk' - -class TkMultiListFrame < TkListbox - include TkComposite - - # lbox_height : height of listboxes (pixel) - # title_info : array [ [<title_string>,<init_width>], ... ] - # keys : hash {<option>=><value>, ... } - def initialize_composite(lbox_height, title_info, keys={}) - # argument check - if (! title_info.kind_of? Array) or (title_info.size < 2) - raise - end - - # mode - @keep_minsize = true - @show_each_hscr = true - @show_win_hscr = true - - # init arrays - @base_list = [] - @rel_list = [] - @title_list = [] - @title_cmd = [] - @lbox_list = [] - @hscr_list = [] - - # decide total width - @lbox_total = title_info.size - @width_total = 0 - title_info.each{|title, width, cmd| - @width_total += width.to_f - @title_cmd << cmd - } - - # rel-table of label=>index - @name_index = {} - - # size definition - @window_width = @width_total - @sash = 5 - @scrbar_width = 15 - @scrbar_border = 3 - @lbox_border = 1 - @title_border = 3 - @h_l_thick = 0 - - # init status - @mode = :title - - # vertical scrollbar -=begin - @v_scroll = TkScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, - 'borderwidth'=>@scrbar_border, - 'orient'=>'vertical', 'width'=>@scrbar_width) -=end - @v_scroll = TkYScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, - 'borderwidth'=>@scrbar_border, - 'width'=>@scrbar_width) - - # horizontal scrollbar -=begin - @h_scroll = TkScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, - 'borderwidth'=>@scrbar_border, - 'orient'=>'horizontal', 'width'=>@scrbar_width) -=end - @h_scroll = TkXScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, - 'borderwidth'=>@scrbar_border, - 'width'=>@scrbar_width) - - # create base flames - @c_title = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, - 'width'=>@window_width) - @f_title = TkFrame.new(@c_title, 'width'=>@width_total) - @w_title = TkcWindow.new(@c_title, 0, 0, - 'window'=>@f_title, 'anchor'=>'nw') - - @c_lbox = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, - 'width'=>@window_width) - @f_lbox = TkFrame.new(@c_lbox, 'width'=>@width_total) - @w_lbox = TkcWindow.new(@c_lbox, 0, 0, 'window'=>@f_lbox, 'anchor'=>'nw') - - @c_hscr = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, - 'width'=>@window_width) - @f_hscr = TkFrame.new(@c_hscr, 'width'=>@width_total) - @w_hscr = TkcWindow.new(@c_hscr, 0, 0, 'window'=>@f_hscr, 'anchor'=>'nw') - - # create each listbox - sum = 0.0 - @rel_list << sum/@width_total - title_info.each_with_index{|(label, width), idx| - # set relation between label and index - if @name_index.include?(label) - @name_index[label] << idx - else - @name_index[label] = [idx] - end - - # calculate relative positioning - sum += width - @rel_list << sum/@width_total - - # title field - f = TkFrame.new(@f_title, 'width'=>width) - base = [f] - - title = TkLabel.new(f, 'text'=>label, 'borderwidth'=>@title_border, - 'relief'=>'raised', 'highlightthickness'=>@h_l_thick) - title_binding(title, idx) - title.pack('fill'=>'x') - - @title_list << title - - f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, - 'relheight'=>1.0, - 'relwidth'=>@rel_list[idx+1] - @rel_list[idx]) - - # listbox field - f = TkFrame.new(@f_lbox, 'width'=>width) - base << f - @lbox_list << TkListbox.new(f, 'highlightthickness'=>@h_l_thick, - 'borderwidth'=>@lbox_border - ).pack('fill'=>'both', 'expand'=>true) - f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, - 'relwidth'=>@rel_list[idx+1] - @rel_list[idx], 'relheight'=>1.0) - - # scrollbar field - f = TkFrame.new(@f_hscr, 'width'=>width) - base << f -=begin - @hscr_list << TkScrollbar.new(f, 'orient'=>'horizontal', - 'width'=>@scrbar_width, - 'borderwidth'=>@scrbar_border, - 'highlightthickness'=>@h_l_thick - ).pack('fill'=>'x', 'anchor'=>'w') -=end - @hscr_list << TkXScrollbar.new(f, 'width'=>@scrbar_width, - 'borderwidth'=>@scrbar_border, - 'highlightthickness'=>@h_l_thick - ).pack('fill'=>'x', 'anchor'=>'w') - f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, - 'relwidth'=>@rel_list[idx+1] - @rel_list[idx]) - -=begin - @lbox_list[idx].xscrollcommand proc{|first, last| - @hscr_list[idx].set first, last - } - @hscr_list[idx].command proc{|*args| @lbox_list[idx].xview *args} -=end - @lbox_list[idx].xscrollbar(@hscr_list[idx]) - - # add new base - @base_list << base - } - - # pad - # @f_title_pad = TkFrame.new(@frame) - @f_title_pad = TkFrame.new(@frame, 'relief'=>'raised', - 'borderwidth'=>@title_border, - 'highlightthickness'=>@h_l_thick) - - @f_scr_pad = TkFrame.new(@frame, 'relief'=>'sunken', - 'borderwidth'=>1, - 'highlightthickness'=>@h_l_thick) - - # height check - title_height = 0 - @title_list.each{|w| - h = w.winfo_reqheight - title_height = h if title_height < h - } - - hscr_height = 0 - @hscr_list.each{|w| - h = w.winfo_reqheight - hscr_height = h if hscr_height < h - } - - @f_title.height title_height - @f_lbox.height lbox_height - @f_hscr.height hscr_height - - # set control procedure for vertical scroll -=begin - @lbox_list.each{|lbox| - lbox.yscrollcommand proc{|first, last| - @v_scroll.set first, last - } - } - @v_scroll.command proc{|*args| @lbox_list.each{|lbox| lbox.yview *args} } -=end - @v_scroll.assign(*@lbox_list) - - # set control procedure for horizontal scroll -=begin - @c_title.xscrollcommand proc{|first, last| - @h_scroll.set first, last - } - @c_lbox.xscrollcommand proc{|first, last| - @h_scroll.set first, last - } - @c_hscr.xscrollcommand proc{|first, last| - @h_scroll.set first, last - } - @h_scroll.command proc{|*args| - @c_title.xview *args - @c_lbox.xview *args - @c_hscr.xview *args if @show_each_hscr - } -=end - @h_scroll.assign(@c_title, @c_lbox, @c_hscr) - - # binding for listboxes - @lbox_mode = {} - @lbox_mode['browse'] = browse_mode_bindtag - @lbox_mode['single'] = single_mode_bindtag - @lbox_mode['extended'] = extended_mode_bindtag - @lbox_mode['multiple'] = multiple_mode_bindtag - @current_mode = 'browse' - @lbox_list.each_with_index{|l, idx| - l.bind('Shift-Key-Left', - proc{|w| focus_shift(w, -1); Tk.callback_break}, '%W') - l.bind('Shift-Key-Right', - proc{|w| focus_shift(w, 1); Tk.callback_break}, '%W') - - l.bind('Button-2', proc{|x, y| - @lbox_mark_x = x - @lbox_list.each{|lbox| lbox.scan_mark(x, y)} - }, '%x %y') - l.bind('B2-Motion', proc{|x, y| - @lbox_list.each{|lbox| lbox.scan_dragto(@lbox_mark_x, y)} - l.scan_dragto(x, y) - }, '%x %y') - - l.bindtags(l.bindtags.unshift(@lbox_mode[@current_mode])) - } - - bbox = @w_title.bbox - @c_title.height(bbox[3]) - @c_title.scrollregion(bbox) - - bbox = @w_lbox.bbox - @c_lbox.height(bbox[3]) - @c_lbox.scrollregion(bbox) - - if @show_each_hscr - bbox = @w_hscr.bbox - @c_hscr.height(bbox[3]) - @c_hscr.scrollregion(bbox) - end - - # alignment - TkGrid.rowconfigure(@frame, 0, 'weight'=>0) - TkGrid.rowconfigure(@frame, 1, 'weight'=>1) - TkGrid.rowconfigure(@frame, 2, 'weight'=>0) - TkGrid.rowconfigure(@frame, 3, 'weight'=>0) - TkGrid.columnconfigure(@frame, 0, 'weight'=>1) - TkGrid.columnconfigure(@frame, 1, 'weight'=>0) - TkGrid.columnconfigure(@frame, 2, 'weight'=>0) - @v_scroll.grid('row'=>1, 'column'=>2, 'sticky'=>'ns') - @c_title.grid('row'=>0, 'column'=>0, 'sticky'=>'news') - @f_title_pad.grid('row'=>0, 'column'=>2, 'sticky'=>'news') - @c_lbox.grid('row'=>1, 'column'=>0, 'sticky'=>'news') - @c_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew') if @show_each_hscr - @h_scroll.grid('row'=>3, 'column'=>0, 'sticky'=>'ew') if @show_win_hscr - @f_scr_pad.grid('row'=>2, 'rowspan'=>2, 'column'=>2, 'sticky'=>'news') - - # binding for 'Configure' event - @c_lbox.bind('Configure', - proc{|height, width| reconstruct(height, width)}, - '%h %w') - - # set default receiver of method calls - @path = @lbox_list[0].path - - # configure options - keys = {} unless keys - keys = _symbolkey2str(keys) - - # 'mode' option of listboxes - sel_mode = keys.delete('mode') - mode(sel_mode) if sel_mode - - # 'scrollbarwidth' option == 'width' option of scrollbars - width = keys.delete('scrollbarwidth') - scrollbarwidth(width) if width - - # options for listbox titles - title_font = keys.delete('titlefont') - titlefont(title_font) if title_font - - title_fg = keys.delete('titleforeground') - titleforeground(title_fg) if title_fg - - title_bg = keys.delete('titlebackground') - titlebackground(title_bg) if title_bg - - # set receivers for configure methods - delegate('DEFAULT', *@lbox_list) - delegate('activebackground', @v_scroll, @h_scroll, *@hscr_list) - delegate('troughcolor', @v_scroll, @h_scroll, *@hscr_list) - delegate('repeatdelay', @v_scroll, @h_scroll, *@hscr_list) - delegate('repeatinterval', @v_scroll, @h_scroll, *@hscr_list) - delegate('borderwidth', @frame) - delegate('width', @c_lbox, @c_title, @c_hscr) - delegate('relief', @frame) - - # configure - configure(keys) if keys.size > 0 - end - private :initialize_composite - - # set 'mode' option of listboxes - def mode(sel_mode) - @lbox_list.each{|l| - tags = l.bindtags - tags = tags - [ @lbox_mode[@current_mode] ] - l.bindtags(tags.unshift(@lbox_mode[sel_mode])) - @current_mode = sel_mode - } - end - - # keep_minsize? - def keep_minsize? - @keep_minsize - end - def keep_minsize(bool) - @keep_minsize = bool - end - - # each hscr - def show_each_hscr - @show_each_hscr = true - @c_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew') - end - def hide_each_hscr - @show_each_hscr = false - @c_hscr.ungrid - end - - # window hscroll - def show_win_hscr - @show_win_hscr = true - @h_scroll.grid('row'=>3, 'column'=>0, 'sticky'=>'ew') - end - def hide_win_hscr - @show_each_hscr = false - @h_scroll.ungrid - end - - # set scrollbar width - def scrollbarwidth(width) - @scrbar_width = width - @v_scroll['width'] = @scrbar_width - @h_scroll['width'] = @scrbar_width - @hscr_list.each{|hscr| hscr['width'] = @scrbar_width} - self - end - - # set scrollbar border - def scrollbarborder(width) - @scrbar_border = width - @v_scroll['border'] = @scrbar_border - @h_scroll['border'] = @scrbar_border - @hscr_list.each{|hscr| hscr['border'] = @scrbar_border} - self - end - - # set listbox borders - def listboxborder(width) - @lbox_border = width - @lbox_list.each{|w| w['border'] = @lbox_border} - self - end - - # set listbox relief - def listboxrelief(relief) - @lbox_list.each{|w| w['relief'] = relief} - self - end - - # set title borders - def titleborder(width) - @title_border = width - @f_title_pad['border'] = @title_border - @title_list.each{|label| label['border'] = @title_border} - self - end - - # set title font - def titlefont(font) - @title_list.each{|label| label['font'] = font} - title_height = 0 - @title_list.each{|w| - h = w.winfo_reqheight - title_height = h if title_height < h - } - @f_title.height title_height - bbox = @w_title.bbox - @c_title.height(bbox[3]) - @c_title.scrollregion(bbox) - self - end - - # set title foreground color - def titleforeground(fg) - @title_list.each{|label| label['foreground'] = fg} - self - end - - # set title background color - def titlebackground(bg) - @f_title_pad['background'] = bg - @title_list.each{|label| label['background'] = bg} - self - end - - # set title cmds - def titlecommand(idx, cmd=Proc.new) - @title_cmd[idx] = cmd - end - - # call title cmds - def titleinvoke(idx) - @title_cmd[idx].call if @title_cmd[idx] - end - - # get label widgets of listbox titles - def titlelabels(*indices) - @title_list[*indices] - end - - # get listbox widgets - def columns(*indices) - @lbox_list[*indices] - end - - def activate(idx) - @lbox_list.each{|lbox| lbox.activate(idx)} - end - - def bbox(idx) - @lbox_list.collect{|lbox| lbox.bbox(idx)} - end - - def delete(*idx) - @lbox_list.collect{|lbox| lbox.delete(*idx)} - end - - def get(*idx) - if idx.size == 1 - @lbox_list.collect{|lbox| lbox.get(*idx)} - else - list = @lbox_list.collect{|lbox| lbox.get(*idx)} - result = [] - list[0].each_with_index{|line, index| - result << list.collect{|lines| lines[index]} - } - result - end - end - - def _line_array_to_hash(line) - result = {} - @name_index.each_pair{|label, indices| - if indices.size == 1 - result[label] = line[indices[0]] - else - result[label] = indices.collect{|index| line[index]} - end - } - result - end - private :_line_array_to_hash - - def get_by_hash(*idx) - get_result = get(*idx) - if idx.size == 1 - _line_array_to_hash(get_result) - else - get_result.collect{|line| _line_array_to_hash(line)} - end - end - - def insert(idx, *lines) - lbox_ins = [] - (0..@lbox_list.size).each{lbox_ins << []} - - lines.each{|line| - if line.kind_of? Hash - array = [] - @name_index.each_pair{|label, indices| - if indices.size == 1 - array[indices[0]] = line[label] - else - if line[label].kind_of? Array - indices.each_with_index{|index, num| - array[index] = line[label][num] - } - else - array[indices[0]] = line[label] - end - end - } - line = array - end - - @name_index.each_pair{|label, indices| - if indices.size == 1 - lbox_ins[indices[0]] << line[indices[0]] - else - indices.each{|index| lbox_ins[index] << line[index]} - end - } - } - - @lbox_list.each_with_index{|lbox, index| - lbox.insert(idx, *lbox_ins[index]) if lbox_ins[index] - } - end - - def selection_anchor(index) - @lbox_list.each{|lbox| lbox.selection_anchor(index)} - end - - def selection_clear(first, last=None) - @lbox_list.each{|lbox| lbox.selection_clear(first, last=None)} - end - - def selection_set(first, last=None) - @lbox_list.each{|lbox| lbox.selection_set(first, last=None)} - end - - ########################################### - private - - def reconstruct(height, width) - if @keep_minsize && width <= @width_total - @f_title.width(@width_total) - @f_lbox.width(@width_total) - @f_hscr.width(@width_total) if @show_each_hscr - @window_width = @width_total - else - @f_title.width(width) - @f_lbox.width(width) - @f_hscr.width(width) if @show_each_hscr - @window_width = width - end - - @f_lbox.height(height) - - @c_title.scrollregion(@w_title.bbox) - @c_lbox.scrollregion(@w_lbox.bbox) - @c_hscr.scrollregion(@w_hscr.bbox) if @show_each_hscr - - (0..(@rel_list.size - 2)).each{|idx| - title, lbox, hscr = @base_list[idx] - title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx]) - lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], - 'relheight'=>1.0) - hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx]) - } - end - - def resize(x) - idx = @sel_sash - return if idx == 0 - - # adjustment of relative positioning - delta = (x - @x) / @frame_width - if delta < @rel_list[idx-1] - @rel_list[idx] + (2*@sash/@frame_width) - delta = @rel_list[idx-1] - @rel_list[idx] + (2*@sash/@frame_width) - elsif delta > @rel_list[idx+1] - @rel_list[idx] - (2*@sash/@frame_width) - delta = @rel_list[idx+1] - @rel_list[idx] - (2*@sash/@frame_width) - end - @rel_list[idx] += delta - - # adjustment of leftside widget of the sash - title, lbox, hscr = @base_list[idx - 1] - title.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1]) - lbox.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1], 'relheight'=>1.0) - hscr.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1]) - - # adjustment of rightside widget of the sash - title, lbox, hscr = @base_list[idx] - title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], - 'relx'=>@rel_list[idx]) - lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], - 'relx'=>@rel_list[idx], 'relheight'=>1.0) - hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], - 'relx'=>@rel_list[idx]) - - # update reference position - @x = x - end - - def motion_cb(w, x, idx) - if x <= @sash && idx > 0 - w.cursor 'sb_h_double_arrow' - @mode = :sash - @sel_sash = idx - elsif x >= w.winfo_width - @sash && idx < @lbox_total - 1 - w.cursor 'sb_h_double_arrow' - @mode = :sash - @sel_sash = idx + 1 - else - w.cursor "" - @mode = :title - @sel_sash = 0 - end - end - - def title_binding(title, index) - title.bind('Motion', proc{|w, x, idx| motion_cb(w, x, idx.to_i)}, - "%W %x #{index}") - - title.bind('Enter', proc{|w, x, idx| motion_cb(w, x, idx.to_i)}, - "%W %x #{index}") - - title.bind('Leave', proc{|w| w.cursor ""}, "%W") - - title.bind('Button-1', - proc{|w, x| - if @mode == :sash - @x = x - @frame_width = TkWinfo.width(@f_title).to_f - else - title.relief 'sunken' - end - }, - '%W %X') - - title.bind('ButtonRelease-1', - proc{|w, x, idx| - i = idx.to_i - if @mode == :title && @title_cmd[i].kind_of?(Proc) - @title_cmd[i].call - end - title.relief 'raised' - motion_cb(w,x,i) - }, - "%W %x #{index}") - - title.bind('B1-Motion', proc{|x| resize(x) if @mode == :sash}, "%X") - end - - ################################# - def browse_mode_bindtag - t = TkBindTag.new - t.bind('Button-1', - proc{|w, y| w.focus; select_line(w, w.nearest(y))}, '%W %y') - t.bind('B1-Motion', proc{|w, y| select_line(w, w.nearest(y))}, '%W %y') - - t.bind('Shift-Button-1', - proc{|w, y| active_line(w, w.nearest(y))}, '%W %y') - - t.bind('Key-Up', proc{|w| select_shift(w, -1)}, '%W') - t.bind('Key-Down', proc{|w| select_shift(w, 1)}, '%W') - - t.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W') - t.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W') - - t.bind('space', proc{|w| select_line(w, w.index('active').to_i)}, '%W') - t.bind('Select', proc{|w| select_line(w, w.index('active').to_i)}, '%W') - t.bind('Control-slash', - proc{|w| select_line(w, w.index('active').to_i)}, '%W') - - t - end - - ######################## - def single_mode_bindtag - t = TkBindTag.new - t.bind('Button-1', - proc{|w, y| w.focus; select_only(w, w.nearest(y))}, '%W %y') - t.bind('ButtonRelease-1', - proc{|w, y| active_line(w, w.nearest(y))}, '%W %y') - - t.bind('Shift-Button-1', - proc{|w, y| active_line(w, w.nearest(y))}, '%W %y') - - t.bind('Key-Up', proc{|w| select_shift(w, -1)}, '%W') - t.bind('Key-Down', proc{|w| select_shift(w, 1)}, '%W') - - t.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W') - t.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W') - - t.bind('space', proc{|w| select_line(w, w.index('active').to_i)}, '%W') - t.bind('Select', proc{|w| select_line(w, w.index('active').to_i)}, '%W') - t.bind('Control-slash', - proc{|w| select_line(w, w.index('active').to_i)}, '%W') - t.bind('Control-backslash', - proc{@lbox_list.each{|l| l.selection_clear(0, 'end')}}) - - t - end - - ######################## - def extended_mode_bindtag - t = TkBindTag.new - t.bind('Button-1', - proc{|w, y| w.focus; select_only(w, w.nearest(y))}, '%W %y') - t.bind('B1-Motion', proc{|w, y| select_range(w, w.nearest(y))}, '%W %y') - - t.bind('ButtonRelease-1', - proc{|w, y| active_line(w, w.nearest(y))}, '%W %y') - - t.bind('Shift-Button-1', - proc{|w, y| select_range(w, w.nearest(y))}, '%W %y') - t.bind('Shift-B1-Motion', - proc{|w, y| select_range(w, w.nearest(y))}, '%W %y') - - t.bind('Control-Button-1', - proc{|w, y| select_toggle(w, w.nearest(y))}, '%W %y') - - t.bind('Control-B1-Motion', - proc{|w, y| select_drag(w, w.nearest(y))}, '%W %y') - - t.bind('Key-Up', proc{|w| active_shift(w, -1)}, '%W') - t.bind('Key-Down', proc{|w| active_shift(w, 1)}, '%W') - - t.bind('Shift-Up', proc{|w| select_expand(w, -1)}, '%W') - t.bind('Shift-Down', proc{|w| select_expand(w, 1)}, '%W') - - t.bind('Control-Home', proc{|w| select_line2(w, 0)}, '%W') - t.bind('Control-End', proc{|w| select_line2(w, 'end')}, '%W') - - t.bind('Control-Shift-Home', proc{|w| select_range(w, 0)}, '%W') - t.bind('Control-Shift-End', proc{|w| select_range(w, 'end')}, '%W') - - t.bind('space', proc{|w| select_active(w)}, '%W') - t.bind('Select', proc{|w| select_active(w)}, '%W') - t.bind('Control-slash', proc{|w| select_all}, '%W') - t.bind('Control-backslash', proc{|w| clear_all}, '%W') - - t - end - - ######################## - def multiple_mode_bindtag - t = TkBindTag.new - t.bind('Button-1', - proc{|w, y| w.focus; select_line3(w, w.nearest(y))}, '%W %y') - t.bind('ButtonRelease-1', - proc{|w, y| active_line(w, w.nearest(y))}, '%W %y') - - t.bind('Key-Up', proc{|w| active_shift(w, -1)}, '%W') - t.bind('Key-Down', proc{|w| active_shift(w, 1)}, '%W') - - t.bind('Control-Home', proc{|w| select_line2(w, 0)}, '%W') - t.bind('Control-End', proc{|w| select_line2(w, 'end')}, '%W') - - t.bind('Control-Shift-Home', proc{|w| active_line(w, 0)}, '%W') - t.bind('Control-Shift-End', proc{|w| active_line(w, 'end')}, '%W') - - t.bind('space', proc{|w| select_active(w)}, '%W') - t.bind('Select', proc{|w| select_active(w)}, '%W') - t.bind('Control-slash', proc{|w| select_all}, '%W') - t.bind('Control-backslash', proc{|w| clear_all}, '%W') - - t - end - - ######################## - def active_line(w, idx) - @lbox_list.each{|l| l.activate(idx)} - end - - def select_only(w, idx) - @lbox_list.each{|l| - l.selection_clear(0, 'end') - l.selection_anchor(idx) - l.selection_set('anchor') - } - end - - def select_range(w, idx) - @lbox_list.each{|l| - l.selection_clear(0, 'end') - l.selection_set('anchor', idx) - } - end - - def select_toggle(w, idx) - st = w.selection_includes(idx) - @lbox_list.each{|l| - l.selection_anchor(idx) - if st == 1 - l.selection_clear(idx) - else - l.selection_set(idx) - end - } - end - - def select_drag(w, idx) - st = w.selection_includes('anchor') - @lbox_list.each{|l| - if st == 1 - l.selection_set('anchor', idx) - else - l.selection_clear('anchor', idx) - end - } - end - - def select_line(w, idx) - @lbox_list.each{|l| - l.selection_clear(0, 'end') - l.activate(idx) - l.selection_anchor(idx) - l.selection_set('anchor') - } - w.selection_set('anchor') - end - - def select_line2(w, idx) - @lbox_list.each{|l| - l.activate(idx) - l.selection_anchor(idx) - l.selection_set('anchor') - } - end - - def select_line3(w, idx) - @lbox_list.each{|l| - l.selection_set(idx) - } - end - - def select_active(w) - idx = l.activate(idx) - @lbox_list.each{|l| - l.selection_set(idx) - } - end - - def select_expand(w, dir) - idx = w.index('active').to_i + dir - if idx < 0 - idx = 0 - elsif idx >= w.size - idx = w.size - 1 - end - @lbox_list.each{|l| - l.activate(idx) - l.selection_set(idx) - } - end - - def active_shift(w, dir) - idx = w.index('active').to_i + dir - if idx < 0 - idx = 0 - elsif idx >= w.size - idx = w.size - 1 - end - @lbox_list.each{|l| - l.activate(idx) - l.selection_anchor(idx) - } - end - - def select_shift(w, dir) - idx = w.index('anchor').to_i + dir - if idx < 0 - idx = 0 - elsif idx >= w.size - idx = w.size - 1 - end - @lbox_list.each{|l| - l.selection_clear(0, 'end') - l.activate(idx) - l.selection_anchor(idx) - l.selection_set('anchor') - } - end - - def select_all - @lbox_list.each{|l| - l.selection_set(0, 'end') - } - end - - def clear_all - @lbox_list.each{|l| - l.selection_clear(0, 'end') - } - end - - def focus_shift(w, dir) - idx = @lbox_list.index(w) + dir - return if idx < 0 - return if idx >= @lbox_list.size - @lbox_list[idx].focus - end - ######################## -end - -################################################ -# test -################################################ -if __FILE__ == $0 - l = TkMultiListFrame.new(nil, 200, - [ ['L1', 200, proc{p 'click L1'}], - ['L2', 100], - ['L3', 200] ], - 'width'=>350, - #'titleforeground'=>'yellow', - 'titleforeground'=>'white', - #'titlebackground'=>'navy', - 'titlebackground'=>'blue', - 'titlefont'=>'courier' - ).pack('fill'=>'both', 'expand'=>true) - l.insert('end', [1,2,3]) - l.insert('end', [4,5,6]) - l.insert('end', [4,5,6], [4,5,6]) - l.insert('end', ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', - 'cccccccccccccccccccccccccccccccccccccccccccccccccccc']) - l.insert('end', [1,2,3]) - l.insert('end', [4,5,6], [4,5,6]) - l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc']) - l.insert('end', [1,2,3]) - l.insert('end', [4,5,6], [4,5,6]) - l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc']) - l.insert('end', [1,2,3]) - l.insert('end', [4,5,6], [4,5,6]) - l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc']) - l.insert('end', [1,2,3]) - l.insert('end', [4,5,6], [4,5,6]) - p l.columns(1) - p l.columns(1..3) - p l.columns(1,2) - Tk.mainloop -end |