Click me

Richard Suchenwirth 2003-02-18 - Reading a Java tutorial in a bored moment, I came upon the ClickMe example at http://java.sun.com/docs/books/tutorial/java/concepts/practical.html (2007-10-03: dead link), where with only two Java class files, in less than 40 LOC, you can implement a rectangle where a red spot appears when you click on it. After compilation, you have 5 files (one HTML) that perform this feat.

Hm, thought I, how would that look in Tcl?


 package require Tk
 proc drawSpot {w x y r} {
    $w delete spot
    $w create oval [expr {$x-$r}] [expr {$y-$r}] [expr {$x+$r}] [expr {$y+$r}]\
        -fill red -outline red -tag spot
 }
 pack [canvas .c]
 .c create rect 5 5 205 205 -fill white -outline black -tag box
 .c bind box <1> {drawSpot %W %x %y 7}

In order to reduce the ugly heap of expr calls, setok proposed this variation, with "specialist" functions for addition and subtraction:

 package require Tk
 proc + {x y} {expr {$x + $y}}
 proc - {x y} {expr {$x - $y}}
 proc drawSpot {w x y r} {
    $w delete spot
    $w create oval [- $x $r] [- $y $r] [+ $x $r] [+ $y $r]\
        -fill red -outline red -tag spot
 }
 pack [canvas .c]
 .c create rect 5 5 305 155 -fill white -outline black -tag box
 .c bind box <1> {drawSpot %W %x %y 7}

another variation without ugly expr calls:

 package require Tk
 interp alias {} = {} expr
 proc drawSpot {w x y r} {
    $w delete spot
    $w create oval [= $x-$r] [= $y-$r] [= $x+$r] [= $y+$r]\
      -fill red -outline red -tag spot
 }
 pack [canvas .c]
 .c create rect 5 5 305 155 -fill white -outline black -tag box
 .c bind box <1> {drawSpot %W %x %y 7}

(expr argument not in {...}, thus slower, but harmless here. Refer also to expr shorthand for Tcl9 -- RJM)

-- CN 03/10/2007: here's a variation with an expr that uses the tcl::mathfunc stuff that comes with 8.5:

 package require Tk 8.5
 proc tcl::mathfunc::drawSpot {w x1 y1 x2 y2} {
    $w delete spot 
    $w create oval $x1 $y1 $x2 $y2 -fill red -outline red -tag spot
 }
 pack [canvas .c]
 .c create rect 5 5 205 205 -fill white -outline black -tag box
 .c bind box <1> {expr {drawSpot("%W",%x-7,%y-7,%x+7,%y+7)}}

NEM 2008-01-17 offers this variant:

proc func {name params body} { proc $name $params [regsub -all {\(([^\)]*)\)} $body {[expr {\1}]}] }
func drawSpot {w x y r} { $w coords spot ($x-$r) ($y-$r) ($x+$r) ($y+$r) }
pack [canvas .c] -fill both -expand 1
.c create rect 5 5 205 205 -fill white -outline black -tags box
.c create oval 0 0 0 0 -fill red -outline red -tags spot
.c bind box <1> {drawSpot %W %x %y 7}

LV 2007-Jan-18

One difference in functionality between the Java example and the Tcl example is that, once built, the Java version, plus its HTML page, can relatively trivially be deployed to a web page and will be able to be used by most web browsing users.

The above Tcl examples are all desktop solutions.

Maybe it would be educational to go over doing it in a way that would also run within a browser.

Certainly there is a tcl plugin - though I've had a variety of results trying to get that to work in recent days with recent versions of tcl and browsers. And does that plugin do tk? I don't recall.

NEM IIRC, these scripts here should run as-is in the Tcl plugin (plugin does do Tk).