Updated 2012-11-26 11:46:38 by RLE

[Question]  edit

The following block of code creates a button as a window item on a canvas and then binds button 3 to allow moving the item. Button 3 grabs the item and begins to move it, but the button jumps back and forth with even the tiniest of movement. It's almost as if the mouse is moving backwards as many steps as it goes forwards, but that's not the case. In any case, the button appears to jiggle all around the screen, which is cool if that's what you're going for. It's not in my case.

Can someone tell me what's going on here?
pack [canvas .c] -expand 1 -fill both
button .b -text "Test Button"

set i [.c create window 100 100 -window .b]

bind .b <3> {set x %x; set y %y}
bind .b <B3-Motion> "
    set ix \[expr %x - \$x]
    set iy \[expr %y - \$y]
    .c move $i \$ix \$iy
    set x %x
    set y %y
"

Answer * edit

GPS: Try this:
catch {console show}

proc drag.canvas.item {canWin item newX newY} {
    set xDiff [expr {$newX - $::x}]
    set yDiff [expr {$newY - $::y}]

    set ::x $newX
    set ::y $newY

    puts $xDiff
    puts $yDiff
    $canWin move $item $xDiff $yDiff
}

pack [canvas .c] -expand 1 -fill both
button .b -text "Test Button"
set id [.c create window 100 100 -window .b]

bind .b <3> {
    set ::x %X
    set ::y %Y
}
bind .b <B3-Motion> [list drag.canvas.item .c $id %X %Y]

Now for an explanation. I believe the problem is that you were using %x instead of %X, and so forth. The %x gives you the position of the cursor relative to the internal coordinates of the button. By using %X (note the upper-case) you get the proper value.