WJG If anyone's using versions of Tcl earlier than 8.5, then simply replace lassign with:
foreach {x y} [winfo pointerxy $w] {} #----------------------------------------------------------------
# popups.tcl
#----------------------------------------------------------------
# Created by William J Giddings, 2005.
#
# Description:
# -----------
# In automating the conversion of Chinese hanzi into roman pinyin,
# a single character may a have number of variant pronunciations.
# Rather than including all the available choices in the displayed output
# the first item in the list is offered, the text tagged with a unique
# id and the alternatives are then used to create selectable items in a popup-menu.
# Access to the menu occurs when a <Button-3> event occurs over the tagged text.
# Should one of the menu items be selected, the currently displayed
# word is replaced with the new choice.
#
# Usage:
# -----
# See demo proc for example
#----------------------------------------------------------------
namespace eval popup {
set cursor "" ;# store default widget cursor during rollovers
}
#----------------------------------------------------------------
# create menu (m) with from list of supplied items (a)
#----------------------------------------------------------------
proc popup::create {m a} {
# destroy any pre-exising menu with the same name
destroy $m
# create new menus
menu $m -tearoff 0
foreach i $a {
$m add command -label $i -command "popup::swap $m $i"
}
popup::config [winfo parent $m] $m
}
#----------------------------------------------------------------
# display the popup menu adjacent to the current pointer location
#----------------------------------------------------------------
proc popup::show {m} {
set w [winfo parent $m]
lassign [winfo pointerxy $w] x y
set ::active(tag) $m
#get active ta
tk_popup $m $x $y
}
#----------------------------------------------------------------
# swap text displayed in the text widget with the selected menu item
#----------------------------------------------------------------
proc popup::swap {m i} {
# get ranges of tag $m
lassign [[winfo parent $m] tag ranges $m] from to
# swap range content for $i
[winfo parent $m] delete $from $to
[winfo parent $m] insert $from "$i " $m
}
#----------------------------------------------------------------
# configure tag display options and bindings
#----------------------------------------------------------------
proc popup::config {path name} {
$path tag configure $name -foreground red
$path tag bind $name <Button-3> "popup::show $name"
$path tag bind $name <Enter> {
set popup::cursor [%W cget -cursor]
%W configure -cursor arrow
}
$path tag bind $name <Leave> {
%W configure -cursor $popup::cursor
}
}
#----------------------------------------------------------------
# the ubiquitous demo
#----------------------------------------------------------------
proc demo {} {
package require Tk
# build simple GUI
text .txt -font {Palatino 12}
pack .txt -fill both -expand 1
focus .txt
# A few examples
.txt insert insert "A demonstration of alternatives.\nSimply click Button-3 over a red word for a popup menu of choices.\n"
# Step 1) add some tagged words
.txt insert insert "Fruit " .txt.menu_1
# Step 2) build a list of alternatives
set menuitems(1) [list Apple Bannana Cherry Damson Elder]
# Step 3) create popup
popup::create .txt.menu_1 $menuitems(1)
# just a few other entries for company....
.txt insert insert "Trees " .txt.menu_2
set menuitems(2) [list Ash Birch Chestnut ]
popup::create .txt.menu_2 $menuitems(2)
.txt insert insert "Birds " .txt.menu_3
set menuitems(3) [list Blue-Tit Great-Tit Coal-Tit Robin]
popup::create .txt.menu_3 $menuitems(3)
}
demo
