2003-11-20 03:53:52 -05:00
|
|
|
#
|
|
|
|
# tkballoonhelp.rb : simple balloon help widget
|
|
|
|
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
|
|
|
#
|
2009-03-05 22:56:38 -05:00
|
|
|
# Add a balloon help to a widget.
|
|
|
|
# This widget has only poor featureas. If you need more useful features,
|
2003-11-20 03:53:52 -05:00
|
|
|
# please try to use the Tix extension of Tcl/Tk under Ruby/Tk.
|
2009-03-05 22:56:38 -05:00
|
|
|
#
|
2003-11-20 03:53:52 -05:00
|
|
|
# The interval time to display a balloon help is defined 'interval' option
|
2009-07-12 19:08:32 -04:00
|
|
|
# (default is 750ms).
|
2003-11-20 03:53:52 -05:00
|
|
|
#
|
|
|
|
require 'tk'
|
|
|
|
|
2009-07-12 19:08:32 -04:00
|
|
|
module Tk
|
|
|
|
module RbWidget
|
|
|
|
class BalloonHelp<TkLabel
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class Tk::RbWidget::BalloonHelp<TkLabel
|
|
|
|
DEFAULT_FOREGROUND = 'black'
|
|
|
|
DEFAULT_BACKGROUND = 'white'
|
|
|
|
DEFAULT_INTERVAL = 750
|
|
|
|
|
2003-11-20 03:53:52 -05:00
|
|
|
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)
|
2006-01-11 21:56:11 -05:00
|
|
|
unless idx
|
|
|
|
ppath = TkComm.window(@parent.path)
|
|
|
|
idx = tags.index(ppath) || 0
|
|
|
|
end
|
2003-11-20 03:53:52 -05:00
|
|
|
tags[idx,0] = @bindtag
|
|
|
|
@parent.bindtags(tags)
|
|
|
|
end
|
|
|
|
private :_balloon_binding
|
|
|
|
|
|
|
|
def initialize(parent=nil, keys={})
|
2006-01-11 21:56:11 -05:00
|
|
|
@parent = parent || Tk.root
|
2003-11-20 03:53:52 -05:00
|
|
|
|
|
|
|
@frame = TkToplevel.new(@parent)
|
|
|
|
@frame.withdraw
|
|
|
|
@frame.overrideredirect(true)
|
|
|
|
@frame.transient(TkWinfo.toplevel(@parent))
|
|
|
|
@epath = @frame.path
|
|
|
|
|
2006-01-11 21:56:11 -05:00
|
|
|
if keys
|
|
|
|
keys = _symbolkey2str(keys)
|
|
|
|
else
|
|
|
|
keys = {}
|
|
|
|
end
|
|
|
|
|
|
|
|
@command = keys.delete('command')
|
2003-11-20 03:53:52 -05:00
|
|
|
|
2009-07-12 19:08:32 -04:00
|
|
|
@interval = keys.delete('interval'){DEFAULT_INTERVAL}
|
2003-11-20 03:53:52 -05:00
|
|
|
_balloon_binding(@interval)
|
|
|
|
|
2009-07-12 19:08:32 -04:00
|
|
|
# @label = TkLabel.new(@frame, 'background'=>'bisque').pack
|
|
|
|
@label = TkLabel.new(@frame,
|
|
|
|
'foreground'=>DEFAULT_FOREGROUND,
|
|
|
|
'background'=>DEFAULT_BACKGROUND).pack
|
2003-11-20 03:53:52 -05:00
|
|
|
@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
|
|
|
|
|
2006-01-11 21:56:11 -05:00
|
|
|
def command(cmd = Proc.new)
|
|
|
|
@command = cmd
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2003-11-20 03:53:52 -05:00
|
|
|
def show
|
|
|
|
x = TkWinfo.pointerx(@parent)
|
|
|
|
y = TkWinfo.pointery(@parent)
|
|
|
|
@frame.geometry("+#{x+1}+#{y+1}")
|
2006-01-11 21:56:11 -05:00
|
|
|
|
|
|
|
if @command
|
|
|
|
case @command.arity
|
|
|
|
when 0
|
|
|
|
@command.call
|
|
|
|
when 2
|
|
|
|
@command.call(x - TkWinfo.rootx(@parent), y - TkWinfo.rooty(@parent))
|
|
|
|
when 3
|
2009-03-05 22:56:38 -05:00
|
|
|
@command.call(x - TkWinfo.rootx(@parent), y - TkWinfo.rooty(@parent),
|
2006-01-11 21:56:11 -05:00
|
|
|
self)
|
|
|
|
else
|
2009-03-05 22:56:38 -05:00
|
|
|
@command.call(x - TkWinfo.rootx(@parent), y - TkWinfo.rooty(@parent),
|
2006-01-11 21:56:11 -05:00
|
|
|
self, @parent)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2003-11-20 03:53:52 -05:00
|
|
|
@frame.deiconify
|
|
|
|
@frame.raise
|
|
|
|
|
|
|
|
@org_cursor = @parent['cursor']
|
2009-03-05 22:56:38 -05:00
|
|
|
@parent.cursor('crosshair')
|
2003-11-20 03:53:52 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def erase
|
2009-03-05 22:56:38 -05:00
|
|
|
@parent.cursor(@org_cursor)
|
2003-11-20 03:53:52 -05:00
|
|
|
@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')
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(b, 'text'=>' Message ')
|
2003-11-20 03:53:52 -05:00
|
|
|
}
|
|
|
|
TkButton.new('text'=>'This button has another balloon help') {|b|
|
|
|
|
pack('fill'=>'x')
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(b,
|
|
|
|
'text'=>"CONFIGURED MESSAGE\nchange colors, and so on",
|
|
|
|
'interval'=>200, 'font'=>'courier',
|
|
|
|
'background'=>'gray', 'foreground'=>'red')
|
2003-11-20 03:53:52 -05:00
|
|
|
}
|
2006-01-11 21:56:11 -05:00
|
|
|
|
|
|
|
sb = TkScrollbox.new.pack(:fill=>:x)
|
|
|
|
sb.insert(:end, *%w(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm))
|
|
|
|
=begin
|
|
|
|
# CASE1 : command takes no arguemnt
|
2009-07-12 19:08:32 -04:00
|
|
|
bh = Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
|
|
|
|
:relief=>:ridge, :background=>'white',
|
|
|
|
:command=>proc{
|
|
|
|
y = TkWinfo.pointery(sb) - TkWinfo.rooty(sb)
|
|
|
|
bh.text "current index == #{sb.nearest(y)}"
|
|
|
|
})
|
2006-01-11 21:56:11 -05:00
|
|
|
=end
|
|
|
|
=begin
|
|
|
|
# CASE2 : command takes 2 arguemnts
|
2009-07-12 19:08:32 -04:00
|
|
|
bh = Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
|
|
|
|
:relief=>:ridge, :background=>'white',
|
|
|
|
:command=>proc{|x, y|
|
|
|
|
bh.text "current index == #{sb.nearest(y)}"
|
|
|
|
})
|
2006-01-11 21:56:11 -05:00
|
|
|
=end
|
|
|
|
=begin
|
|
|
|
# CASE3 : command takes 3 arguemnts
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
|
|
|
|
:relief=>:ridge, :background=>'white',
|
|
|
|
:command=>proc{|x, y, bhelp|
|
|
|
|
bhelp.text "current index == #{sb.nearest(y)}"
|
|
|
|
})
|
2006-01-11 21:56:11 -05:00
|
|
|
=end
|
|
|
|
=begin
|
|
|
|
# CASE4a : command is a Proc object and takes 4 arguemnts
|
|
|
|
cmd = proc{|x, y, bhelp, parent|
|
|
|
|
bhelp.text "current index == #{parent.nearest(y)}"
|
|
|
|
}
|
|
|
|
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
|
|
|
|
:relief=>:ridge, :background=>'white',
|
|
|
|
:command=>cmd)
|
2006-01-11 21:56:11 -05:00
|
|
|
|
|
|
|
sb2 = TkScrollbox.new.pack(:fill=>:x)
|
|
|
|
sb2.insert(:end, *%w(AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK LLL MMM))
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(sb2, :interval=>500,
|
|
|
|
:padx=>5, :relief=>:raised,
|
|
|
|
:background=>'gray25', :foreground=>'white',
|
|
|
|
:command=>cmd)
|
2006-01-11 21:56:11 -05:00
|
|
|
=end
|
|
|
|
#=begin
|
|
|
|
# CASE4b : command is a Method object and takes 4 arguemnts
|
|
|
|
def set_msg(x, y, bhelp, parent)
|
|
|
|
bhelp.text "current index == #{parent.nearest(y)}"
|
|
|
|
end
|
|
|
|
cmd = self.method(:set_msg)
|
|
|
|
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
|
|
|
|
:relief=>:ridge, :background=>'white',
|
|
|
|
:command=>cmd)
|
2006-01-11 21:56:11 -05:00
|
|
|
|
|
|
|
sb2 = TkScrollbox.new.pack(:fill=>:x)
|
|
|
|
sb2.insert(:end, *%w(AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK LLL MMM))
|
2009-07-12 19:08:32 -04:00
|
|
|
Tk::RbWidget::BalloonHelp.new(sb2, :interval=>500,
|
|
|
|
:padx=>5, :relief=>:raised,
|
|
|
|
:background=>'gray25', :foreground=>'white',
|
|
|
|
:command=>cmd)
|
2006-01-11 21:56:11 -05:00
|
|
|
#=end
|
|
|
|
|
2003-11-20 03:53:52 -05:00
|
|
|
Tk.mainloop
|
|
|
|
end
|