mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/tk/sample/tkballoonhelp.rb: new sample script
* ext/tk/sample/tkmultilistbox.rb: ditto * ext/tk/sample/tktextframe.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4991 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b33ea38a9b
commit
f465e8a1c8
5 changed files with 865 additions and 0 deletions
|
@ -1,3 +1,11 @@
|
|||
Thu Nov 20 17:50:58 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* ext/tk/sample/tkballoonhelp.rb: new sample script
|
||||
|
||||
* ext/tk/sample/tkmultilistbox.rb: ditto
|
||||
|
||||
* ext/tk/sample/tktextframe.rb: ditto
|
||||
|
||||
Thu Nov 20 13:37:34 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* ruby.h: define is_ruby_native_thread() for no native thread
|
||||
|
|
|
@ -23,6 +23,7 @@ lib/tktext.rb
|
|||
lib/tkvirtevent.rb
|
||||
lib/tkwinpkg.rb
|
||||
sample/safe-tk.rb
|
||||
sample/tkballoonhelp.rb
|
||||
sample/tkbiff.rb
|
||||
sample/tkbrowse.rb
|
||||
sample/tkdialog.rb
|
||||
|
@ -30,8 +31,10 @@ sample/tkfrom.rb
|
|||
sample/tkhello.rb
|
||||
sample/tkline.rb
|
||||
sample/tkmenubutton.rb
|
||||
sample/tkmultilistbox.rb
|
||||
sample/tkoptdb-safeTk.rb
|
||||
sample/tkoptdb.rb
|
||||
sample/tktextframe.rb
|
||||
sample/resource.ja
|
||||
sample/resource.en
|
||||
sample/tktimer.rb
|
||||
|
|
99
ext/tk/sample/tkballoonhelp.rb
Normal file
99
ext/tk/sample/tkballoonhelp.rb
Normal file
|
@ -0,0 +1,99 @@
|
|||
#
|
||||
# tkballoonhelp.rb : simple balloon help widget
|
||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||
#
|
||||
# Add a balloon help to a widget.
|
||||
# This widget has only poor featureas. If you need more useful features,
|
||||
# please try to use the Tix extension of Tcl/Tk under Ruby/Tk.
|
||||
#
|
||||
# The interval time to display a balloon help is defined 'interval' option
|
||||
# (default is 1000ms).
|
||||
#
|
||||
require 'tk'
|
||||
|
||||
class TkBalloonHelp<TkLabel
|
||||
def _balloon_binding(interval)
|
||||
@timer = TkAfter.new(interval, 1, proc{show})
|
||||
def @timer.interval(val)
|
||||
@sleep_time = val
|
||||
end
|
||||
@bindtag = TkBindTag.new
|
||||
@bindtag.bind('Enter', proc{@timer.start})
|
||||
@bindtag.bind('Motion', proc{@timer.restart; erase})
|
||||
@bindtag.bind('Any-ButtonPress', proc{@timer.restart; erase})
|
||||
@bindtag.bind('Leave', proc{@timer.stop; erase})
|
||||
tags = @parent.bindtags
|
||||
idx = tags.index(@parent)
|
||||
tags[idx,0] = @bindtag
|
||||
@parent.bindtags(tags)
|
||||
end
|
||||
private :_balloon_binding
|
||||
|
||||
def initialize(parent=nil, keys={})
|
||||
@parent = parent
|
||||
|
||||
@frame = TkToplevel.new(@parent)
|
||||
@frame.withdraw
|
||||
@frame.overrideredirect(true)
|
||||
@frame.transient(TkWinfo.toplevel(@parent))
|
||||
@epath = @frame.path
|
||||
|
||||
keys = {} unless keys
|
||||
|
||||
@interval = keys.delete('interval'){1000}
|
||||
_balloon_binding(@interval)
|
||||
|
||||
@label = TkLabel.new(@frame, 'background'=>'bisque').pack
|
||||
@label.configure(_symbolkey2str(keys)) unless keys.empty?
|
||||
@path = @label
|
||||
end
|
||||
|
||||
def epath
|
||||
@epath
|
||||
end
|
||||
|
||||
def interval(val)
|
||||
if val
|
||||
@timer.interval(val)
|
||||
else
|
||||
@interval
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
x = TkWinfo.pointerx(@parent)
|
||||
y = TkWinfo.pointery(@parent)
|
||||
@frame.geometry("+#{x+1}+#{y+1}")
|
||||
@frame.deiconify
|
||||
@frame.raise
|
||||
|
||||
@org_cursor = @parent['cursor']
|
||||
@parent.cursor('crosshair')
|
||||
end
|
||||
|
||||
def erase
|
||||
@parent.cursor(@org_cursor)
|
||||
@frame.withdraw
|
||||
end
|
||||
|
||||
def destroy
|
||||
@frame.destroy
|
||||
end
|
||||
end
|
||||
|
||||
################################################
|
||||
# test
|
||||
################################################
|
||||
if __FILE__ == $0
|
||||
TkButton.new('text'=>'This button has a balloon help') {|b|
|
||||
pack('fill'=>'x')
|
||||
TkBalloonHelp.new(b, 'text'=>' Message ')
|
||||
}
|
||||
TkButton.new('text'=>'This button has another balloon help') {|b|
|
||||
pack('fill'=>'x')
|
||||
TkBalloonHelp.new(b, 'text'=>'configured message',
|
||||
'interval'=>500, 'font'=>'courier',
|
||||
'background'=>'gray', 'foreground'=>'red')
|
||||
}
|
||||
Tk.mainloop
|
||||
end
|
650
ext/tk/sample/tkmultilistbox.rb
Normal file
650
ext/tk/sample/tkmultilistbox.rb
Normal file
|
@ -0,0 +1,650 @@
|
|||
#
|
||||
# tkmultilistbox.rb : multiple listbox widget
|
||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||
#
|
||||
require 'tk'
|
||||
|
||||
class TkMultiListbox < 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
|
||||
|
||||
# decide total width
|
||||
@width_total = 0
|
||||
title_info.each{|title, width| @width_total += width.to_f}
|
||||
|
||||
# virtical scrollbar
|
||||
@v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')
|
||||
|
||||
# init arrays
|
||||
@base_list = []
|
||||
@rel_list = []
|
||||
@title_list = []
|
||||
@lbox_list = []
|
||||
@hscr_list = []
|
||||
|
||||
# rel-table of label=>index
|
||||
@name_index = {}
|
||||
|
||||
# create base flames
|
||||
@f_title = TkFrame.new(@frame, 'width'=>@width_total)
|
||||
@f_lbox = TkFrame.new(@frame,
|
||||
'width'=>@width_total, 'height'=>lbox_height)
|
||||
@f_hscr = TkFrame.new(@frame, 'width'=>@width_total,
|
||||
'height'=>@v_scroll.cget('width') +
|
||||
2 * @v_scroll.cget('borderwidth'))
|
||||
|
||||
# dummy label to keep the hight of title space
|
||||
TkLabel.new(@f_title, 'text'=>' ').pack
|
||||
|
||||
# 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_list << TkLabel.new(f, 'text'=>label).pack('fill'=>'x')
|
||||
f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>-6,
|
||||
'relwidth'=>@rel_list[idx+1] - @rel_list[idx])
|
||||
|
||||
# listbox field
|
||||
f = TkFrame.new(@f_lbox, 'width'=>width)
|
||||
base << f
|
||||
@lbox_list << TkListbox.new(f).pack('fill'=>'both', 'expand'=>true)
|
||||
f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>-4,
|
||||
'relwidth'=>@rel_list[idx+1] - @rel_list[idx], 'relheight'=>1.0)
|
||||
|
||||
# scrollbar field
|
||||
f = TkFrame.new(@f_hscr, 'width'=>width)
|
||||
base << f
|
||||
@hscr_list << TkScrollbar.new(f, 'orient'=>'horizontal') .
|
||||
pack('fill'=>'x', 'anchor'=>'w')
|
||||
f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>-4,
|
||||
'relwidth'=>@rel_list[idx+1] - @rel_list[idx])
|
||||
|
||||
@lbox_list[idx].xscrollcommand proc{|first, last|
|
||||
@hscr_list[idx].set first, last
|
||||
}
|
||||
@hscr_list[idx].command proc{|*args| @lbox_list[idx].xview *args}
|
||||
|
||||
# add new base
|
||||
@base_list << base
|
||||
}
|
||||
|
||||
# create tab
|
||||
@tab_list = [nil]
|
||||
(1..(@rel_list.size - 2)).each{|idx|
|
||||
tab = TkFrame.new(@f_title, 'cursor'=>'sb_h_double_arrow',
|
||||
'width'=>6, 'borderwidth'=>2, 'relief'=>'raised')
|
||||
@tab_list << tab
|
||||
tab.place('relx'=>@rel_list[idx], 'anchor'=>'ne', 'relheight'=>0.95)
|
||||
tab.bind('Button-1',
|
||||
proc{|x| @x = x; @frame_width = TkWinfo.width(@f_title).to_f},
|
||||
'%X')
|
||||
tab.bind('B1-Motion', proc{|x, idx| resize(x, idx.to_i)}, "%X #{idx}")
|
||||
}
|
||||
|
||||
# set control procedure for virtical scroll
|
||||
@lbox_list.each{|lbox|
|
||||
lbox.yscrollcommand proc{|first, last|
|
||||
@v_scroll.set first, last
|
||||
idx = lbox.nearest(0)
|
||||
@lbox_list.each{|l| l.yview(idx)}
|
||||
}
|
||||
}
|
||||
@v_scroll.command proc{|*args| @lbox_list.each{|lbox| lbox.yview *args} }
|
||||
|
||||
# binding for listboxes
|
||||
@mode = {}
|
||||
@mode['browse'] = browse_mode_bindtag
|
||||
@mode['single'] = single_mode_bindtag
|
||||
@mode['extended'] = extended_mode_bindtag
|
||||
@mode['multiple'] = multiple_mode_bindtag
|
||||
@current_mode = 'browse'
|
||||
@lbox_list.each{|l|
|
||||
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_list.each{|lbox| lbox.scan_mark(x, y)}
|
||||
}, '%x %y')
|
||||
l.bind('B2-Motion', proc{|x, y|
|
||||
@lbox_list.each{|lbox| lbox.scan_dragto(x, y)}
|
||||
}, '%x %y')
|
||||
|
||||
l.bindtags(l.bindtags.unshift(@mode[@current_mode]))
|
||||
}
|
||||
|
||||
# alignment
|
||||
TkGrid.rowconfigure(@frame, 0, 'weight'=>0)
|
||||
TkGrid.rowconfigure(@frame, 1, 'weight'=>1)
|
||||
TkGrid.rowconfigure(@frame, 2, 'weight'=>0)
|
||||
TkGrid.columnconfigure(@frame, 0, 'weight'=>1)
|
||||
TkGrid.columnconfigure(@frame, 1, 'weight'=>0)
|
||||
@v_scroll.grid('row'=>1, 'column'=>1, 'sticky'=>'ns')
|
||||
@f_title.grid('row'=>0, 'column'=>0, 'sticky'=>'news')
|
||||
@f_lbox.grid('row'=>1, 'column'=>0, 'sticky'=>'news')
|
||||
@f_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew')
|
||||
|
||||
# binding for 'Configure' event
|
||||
@frame.bind('Configure', proc{reconstruct})
|
||||
|
||||
# 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')
|
||||
title_fg = keys.delete('titleforeground')
|
||||
title_bg = keys.delete('titlebackground')
|
||||
if title_font or title_fg or title_bg
|
||||
titleconfig(title_font, title_fg, title_bg)
|
||||
end
|
||||
|
||||
# set receivers for configure methods
|
||||
delegate('DELETE', *@lbox_list)
|
||||
delegate('activebackground', @v_scroll, *@hscr_list)
|
||||
delegate('troughcolor', @v_scroll, *@hscr_list)
|
||||
delegate('repeatdelay', @v_scroll, *@hscr_list)
|
||||
delegate('repeatinterval', @v_scroll, *@hscr_list)
|
||||
delegate('borderwidth', @frame)
|
||||
delegate('relief', @frame)
|
||||
end
|
||||
|
||||
# set 'mode' option of listboxes
|
||||
def mode(sel_mode)
|
||||
@lbox_list.each{|l|
|
||||
tags = l.bindtags
|
||||
tags = tags - [ @mode[@current_mode] ]
|
||||
l.bindtags(tags.unshift(@mode[sel_mode]))
|
||||
@current_mode = sel_mode
|
||||
}
|
||||
end
|
||||
|
||||
# set scrollbar width
|
||||
def scrollbarwidth(width)
|
||||
@v_scroll['width'] = width
|
||||
@hscr_list.each{|hscr| hscr['width'] = width}
|
||||
@f_hscr['height'] = width + 2 * @v_scroll.cget('borderwidth')
|
||||
end
|
||||
|
||||
# set options of titles
|
||||
def titleconfig(font, fg, bg)
|
||||
keys = {}
|
||||
keys['font'] = font if font
|
||||
keys['foreground'] = fg if fg
|
||||
keys['background'] = bg if bg
|
||||
@title_list.each{|label| label.configure(keys)}
|
||||
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
|
||||
(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])
|
||||
|
||||
tab = @tab_list[idx]
|
||||
tab.place('relx'=>@rel_list[idx]) if tab
|
||||
}
|
||||
end
|
||||
|
||||
def resize(x, idx)
|
||||
# adjustment of relative positioning
|
||||
delta = (x - @x) / @frame_width
|
||||
if delta < @rel_list[idx-1] - @rel_list[idx] + 0.02
|
||||
delta = @rel_list[idx-1] - @rel_list[idx] + 0.02
|
||||
elsif delta > @rel_list[idx+1] - @rel_list[idx] - 0.02
|
||||
delta = @rel_list[idx+1] - @rel_list[idx] - 0.02
|
||||
end
|
||||
@rel_list[idx] += delta
|
||||
|
||||
# adjustment of leftside widget of the tab
|
||||
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 the tab position
|
||||
@tab_list[idx].place('relx'=>@rel_list[idx])
|
||||
|
||||
# adjustment of rightside widget of the tab
|
||||
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 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
|
||||
f = TkFrame.new(nil, 'width'=>300,
|
||||
'height'=>200).pack('fill'=>'both', 'expand'=>'true')
|
||||
#f = TkFrame.new.pack('fill'=>'both', 'expand'=>'true')
|
||||
l = TkMultiListbox.new(f, 150,
|
||||
[ ['L1', 100],
|
||||
['L2', 200],
|
||||
['L3', 50] ],
|
||||
'titlefont'=>'courier',
|
||||
'titleforeground'=>'yellow',
|
||||
'titlebackground'=>'navy'
|
||||
).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', ['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
|
105
ext/tk/sample/tktextframe.rb
Normal file
105
ext/tk/sample/tktextframe.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
#
|
||||
# tktextframe.rb : a sample of TkComposite
|
||||
#
|
||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||
#
|
||||
require 'tk'
|
||||
|
||||
class TkTextFrame < TkText
|
||||
include TkComposite
|
||||
|
||||
def initialize_composite(keys={})
|
||||
keys = _symbolkey2str(keys)
|
||||
|
||||
# create scrollbars
|
||||
@v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')
|
||||
@h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal')
|
||||
|
||||
# create a text widget
|
||||
@text = TkText.new(@frame, 'wrap'=>'none')
|
||||
|
||||
# set default receiver of method calls
|
||||
@path = @text.path
|
||||
|
||||
# assign scrollbars
|
||||
@text.xscrollbar(@h_scroll)
|
||||
@text.yscrollbar(@v_scroll)
|
||||
|
||||
# allignment
|
||||
TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)
|
||||
TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)
|
||||
@text.grid('row'=>0, 'column'=>0, 'sticky'=>'news')
|
||||
|
||||
# scrollbars ON
|
||||
vscroll(keys.delete('vscroll'){true})
|
||||
hscroll(keys.delete('hscroll'){true})
|
||||
|
||||
# set background of the text widget
|
||||
color = keys.delete('textbackground')
|
||||
textbackground(color) if color
|
||||
|
||||
# set receiver widgets for configure methods
|
||||
delegate('DEFAULT', @text)
|
||||
delegate('background', @frame, @h_scroll, @v_scroll)
|
||||
delegate('activebackground', @h_scroll, @v_scroll)
|
||||
delegate('troughcolor', @h_scroll, @v_scroll)
|
||||
delegate('repeatdelay', @h_scroll, @v_scroll)
|
||||
delegate('repeatinterval', @h_scroll, @v_scroll)
|
||||
delegate('borderwidth', @frame)
|
||||
delegate('relief', @frame)
|
||||
|
||||
# do configure
|
||||
configure keys unless keys.empty?
|
||||
end
|
||||
|
||||
# set background color of text widget
|
||||
def textbackground(color = nil)
|
||||
if color
|
||||
@text.background(color)
|
||||
else
|
||||
@text.background
|
||||
end
|
||||
end
|
||||
|
||||
# vertical scrollbar : ON/OFF
|
||||
def vscroll(mode)
|
||||
st = TkGrid.info(@v_scroll)
|
||||
if mode && st == [] then
|
||||
@v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
|
||||
elsif !mode && st != [] then
|
||||
@v_scroll.ungrid
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# horizontal scrollbar : ON/OFF
|
||||
def hscroll(mode, wrap_mode="char")
|
||||
st = TkGrid.info(@h_scroll)
|
||||
if mode && st == [] then
|
||||
@h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
|
||||
wrap 'none' # => self.wrap('none')
|
||||
elsif !mode && st != [] then
|
||||
@h_scroll.ungrid
|
||||
wrap wrap_mode # => self.wrap(wrap_mode)
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
################################################
|
||||
# test
|
||||
################################################
|
||||
if __FILE__ == $0
|
||||
f = TkFrame.new.pack('fill'=>'x')
|
||||
t = TkTextFrame.new.pack
|
||||
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')
|
||||
Tk.mainloop
|
||||
end
|
Loading…
Add table
Reference in a new issue