Thread from comp.lang.tcl (6 replies)

ISO a way to select programmatically an entry from a popup
Posted by Helmut Giese <hgiese@ratiosoft.com> 2 weeks 5 days ago

Hello out there,
it seems like as long as a popup is posted the app cannot do anything
- in particular it cannot post any events. Consider this script:
	---
package require Tk
foreach ch [winfo children "."] {destroy $ch}

# Turn $x & $y into absolute coords
proc mkAbsCoords {c x y} {
    # get the canvas's coord relative to the toplevel
    set xOfs [expr {[winfo rootx $c]}]
    set yOfs [expr {[winfo rooty $c]}]
    return [list [expr {$x + $xOfs}] [expr {$y + $yOfs}]]
}

proc popupMenu {c x y} {
    catch {destroy .popup}
    set popup [menu .popup -tearoff false]
    set inactiveBG #b2b2b2
    $popup add command -label "Choose an op" \
        -background  #b2b2b2 -activebackground  #b2b2b2 \
        -activeforeground [$popup cget -fg]
    $popup add command -label "Op 1" -command {puts "Op1 selected"}
    $popup add command -label "Op 2" -command {puts "Op2 selected"}
    lassign [mkAbsCoords $c $x $y] x y
    tk_popup $popup $x $y
}

set num [lindex $argv 0]
set c [canvas .c -width 200 -height 200]
pack $c
set id [$c create rectangle 50 50 150 150 -fill lightyellow]
$c bind $id <Button-3> [list popupMenu $c %x %y]
update
if {$num} {
    set event Button
} else {
    set event ButtonPress
}
event generate $c <$event> -button 3 -x 100 -y 100 -warp 1
puts "Back from '$event'"
if {$num == 0} {
    event generate $c <ButtonRelease> -button 3 -x 100 -y 100 -warp 1
    puts "Back from 'ButtonRelease'"
}
	---
and this output:
	---
Microsoft Windows [Version 10.0.19045.4894]
(c) Microsoft Corporation. Alle Rechte vorbehalten.

d:\proj\_ToolsSE\Skeleton\TclTests>tclsh tst.tcl 1
Back from 'Button'
Op1 selected

d:\proj\_ToolsSE\Skeleton\TclTests>tclsh tst.tcl 0
Back from 'ButtonPress'
Back from 'ButtonRelease'
Op1 selected
	---
To me this seems to clearly indicate that the selection cannot be
influenced by the controlling app: control only returns when the
selection has happened - which is too bad.

Or is there a trick by which one can influence the selection from a
popup?
Any idea will be highly appreciated.
Helmut
Oh, this is on Windows 64 bit under Tcl 8.6.10

Click on article to view all threads in comp.lang.tcl
Re: ISO a way to select programmatically an entry from a popup
Posted by greg <gregor.ebbing@gmx.de> 2 weeks 4 days ago

Am 13.09.24 um 01:31 schrieb Helmut Giese:
> Hello out there,
> it seems like as long as a popup is posted the app cannot do anything
> - in particular it cannot post any events. Consider this script:
> 	---
> package require Tk
> foreach ch [winfo children "."] {destroy $ch}
> 
> # Turn $x & $y into absolute coords
> proc mkAbsCoords {c x y} {
>      # get the canvas's coord relative to the toplevel
>      set xOfs [expr {[winfo rootx $c]}]
>      set yOfs [expr {[winfo rooty $c]}]
>      return [list [expr {$x + $xOfs}] [expr {$y + $yOfs}]]
> }
> 
> proc popupMenu {c x y} {
>      catch {destroy .popup}
>      set popup [menu .popup -tearoff false]
>      set inactiveBG #b2b2b2
>      $popup add command -label "Choose an op" \
>          -background  #b2b2b2 -activebackground  #b2b2b2 \
>          -activeforeground [$popup cget -fg]
>      $popup add command -label "Op 1" -command {puts "Op1 selected"}
>      $popup add command -label "Op 2" -command {puts "Op2 selected"}
>      lassign [mkAbsCoords $c $x $y] x y
>      tk_popup $popup $x $y
> }
> 
> set num [lindex $argv 0]
> set c [canvas .c -width 200 -height 200]
> pack $c
> set id [$c create rectangle 50 50 150 150 -fill lightyellow]
> $c bind $id <Button-3> [list popupMenu $c %x %y]
> update
> if {$num} {
>      set event Button
> } else {
>      set event ButtonPress
> }
> event generate $c <$event> -button 3 -x 100 -y 100 -warp 1
> puts "Back from '$event'"
> if {$num == 0} {
>      event generate $c <ButtonRelease> -button 3 -x 100 -y 100 -warp 1
>      puts "Back from 'ButtonRelease'"
> }
> 	---
> and this output:
> 	---
> Microsoft Windows [Version 10.0.19045.4894]
> (c) Microsoft Corporation. Alle Rechte vorbehalten.
> 
> d:\proj\_ToolsSE\Skeleton\TclTests>tclsh tst.tcl 1
> Back from 'Button'
> Op1 selected
> 
> d:\proj\_ToolsSE\Skeleton\TclTests>tclsh tst.tcl 0
> Back from 'ButtonPress'
> Back from 'ButtonRelease'
> Op1 selected
> 	---
> To me this seems to clearly indicate that the selection cannot be
> influenced by the controlling app: control only returns when the
> selection has happened - which is too bad.
> 
> Or is there a trick by which one can influence the selection from a
> popup?
> Any idea will be highly appreciated.
> Helmut
> Oh, this is on Windows 64 bit under Tcl 8.6.10


Hello
with event, invoke and unpost

https://www.tcl.tk/man/tcl8.6/TkCmd/menu.htm#M41



event generate $c <$event> -button 3 -x 100 -y 100 -warp 1
#num 1 or 2, 0 is the label
..popup invoke $num
..popup unpost

Click on article to view all threads in comp.lang.tcl
Re: ISO a way to select programmatically an entry from a popup
Posted by greg <gregor.ebbing@gmx.de> 2 weeks 4 days ago

Am 14.09.24 um 07:44 schrieb greg:
> Am 13.09.24 um 01:31 schrieb Helmut Giese:

>> Oh, this is on Windows 64 bit under Tcl 8.6.10
> 
> 
> Hello
> with event, invoke and unpost
> 
> https://www.tcl.tk/man/tcl8.6/TkCmd/menu.htm#M41
> 
> 
> 
> event generate $c <$event> -button 3 -x 100 -y 100 -warp 1
> #num 1 or 2, 0 is the label
> .popup invoke $num
> .popup unpost
> 
from manual
pathName unpost
     Unmap the window so that it is no longer displayed. If a 
lower-level cascaded menu is posted, unpost that menu. Returns an empty 
string. This subcommand does not work on Windows and the Macintosh, as 
those platforms have their own way of unposting menus.

My suggestion with unpost doesn't help with Windows.


Click on article to view all threads in comp.lang.tcl
Re: ISO a way to select programmatically an entry from a popup
Posted by greg <gregor.ebbing@gmx.de> 2 weeks 4 days ago

Am 14.09.24 um 07:44 schrieb greg:
> Am 13.09.24 um 01:31 schrieb Helmut Giese:

>> Oh, this is on Windows 64 bit under Tcl 8.6.10
> 
> 
> Hello
> with event, invoke and unpost
> 
> https://www.tcl.tk/man/tcl8.6/TkCmd/menu.htm#M41
> 
> 
> 
> event generate $c <$event> -button 3 -x 100 -y 100 -warp 1
> #num 1 or 2, 0 is the label
> .popup invoke $num
> .popup unpost
> 
from manual
pathName unpost
     Unmap the window so that it is no longer displayed. If a 
lower-level cascaded menu is posted, unpost that menu. Returns an empty 
string. This subcommand does not work on Windows and the Macintosh, as 
those platforms have their own way of unposting menus.

My suggestion with unpost doesn't help with Windows.


Click on article to view all threads in comp.lang.tcl
Re: ISO a way to select programmatically an entry from a popup
Posted by greg <gregor.ebbing@gmx.de> 2 weeks 3 days ago

Am 13.09.24 um 01:31 schrieb Helmut Giese:
> Hello out there,
> it seems like as long as a popup is posted the app cannot do anything
> - in particular it cannot post any events. Consider this script:
> 	---
> package require Tk
> foreach ch [winfo children "."] {destroy $ch}
> 
> # Turn $x & $y into absolute coords
> proc mkAbsCoords {c x y} {
>      # get the canvas's coord relative to the toplevel
>      set xOfs [expr {[winfo rootx $c]}]
>      set yOfs [expr {[winfo rooty $c]}]
>      return [list [expr {$x + $xOfs}] [expr {$y + $yOfs}]]
> }
> 
> proc popupMenu {c x y} {
>      catch {destroy .popup}
>      set popup [menu .popup -tearoff false]
>      set inactiveBG #b2b2b2
>      $popup add command -label "Choose an op" \
>          -background  #b2b2b2 -activebackground  #b2b2b2 \
>          -activeforeground [$popup cget -fg]
>      $popup add command -label "Op 1" -command {puts "Op1 selected"}
>      $popup add command -label "Op 2" -command {puts "Op2 selected"}
>      lassign [mkAbsCoords $c $x $y] x y
>      tk_popup $popup $x $y
> }
> 
> set num [lindex $argv 0]
> set c [canvas .c -width 200 -height 200]
> pack $c
> set id [$c create rectangle 50 50 150 150 -fill lightyellow]
> $c bind $id <Button-3> [list popupMenu $c %x %y]
> update
> if {$num} {
>      set event Button
> } else {
>      set event ButtonPress
> }
> event generate $c <$event> -button 3 -x 100 -y 100 -warp 1
> puts "Back from '$event'"
> if {$num == 0} {
>      event generate $c <ButtonRelease> -button 3 -x 100 -y 100 -warp 1
>      puts "Back from 'ButtonRelease'"
> }
> 	---
> and this output:
> 	---
> Microsoft Windows [Version 10.0.19045.4894]
> (c) Microsoft Corporation. Alle Rechte vorbehalten.
> 
> d:\proj\_ToolsSE\Skeleton\TclTests>tclsh tst.tcl 1
> Back from 'Button'
> Op1 selected
> 
> d:\proj\_ToolsSE\Skeleton\TclTests>tclsh tst.tcl 0
> Back from 'ButtonPress'
> Back from 'ButtonRelease'
> Op1 selected
> 	---
> To me this seems to clearly indicate that the selection cannot be
> influenced by the controlling app: control only returns when the
> selection has happened - which is too bad.
> 
> Or is there a trick by which one can influence the selection from a
> popup?
> Any idea will be highly appreciated.
> Helmut
> Oh, this is on Windows 64 bit under Tcl 8.6.10


Hello,
Windows 10 , Tcl/Tk 8.6.13

Without a change in the proc popupMenu the script is frozen.

list tk_popup $popup $x $y


# and invoke index for the selction 0, 1 and 2
#.popup invoke $num


package require Tk

foreach ch [winfo children "."] {destroy $ch}



# Turn $x & $y into absolute coords

proc mkAbsCoords {c x y} {

     # get the canvas's coord relative to the toplevel

     set xOfs [expr {[winfo rootx $c]}]

     set yOfs [expr {[winfo rooty $c]}]

     return [list [expr {$x + $xOfs}] [expr {$y + $yOfs}]]

}



proc popupMenu {c x y} {

     catch {destroy .popup}

     set popup [menu .popup -tearoff false]

     set inactiveBG #b2b2b2

     $popup add command -label "Choose an op" \

         -background  #b2b2b2 -activebackground  #b2b2b2 \

         -activeforeground [$popup cget -fg]

     $popup add command -label "Op 1" -command {puts "Op1 selected"}

     $popup add command -label "Op 2" -command {puts "Op2 selected"}

     lassign [mkAbsCoords $c $x $y] x y

     list tk_popup $popup $x $y

}



set num [lindex $argv 0]

set c [canvas .c -width 200 -height 200]

pack $c

set id [$c create rectangle 50 50 150 150 -fill lightyellow]

$c bind $id <Button-3> [list popupMenu $c %x %y]

update

if {$num} {

     set event Button

} else {

     set event ButtonPress

}

event generate $c <$event> -button 3 -x 100 -y 100 -warp 1

puts "Back from '$event'"

if {$num == 0} {

     event generate $c <ButtonRelease> -button 3 -x 100 -y 100 -warp 1

     puts "Back from 'ButtonRelease'"

}





..popup invoke $num





#Output

if {0} {

tclsh exahgnn.tcl 0

Back from 'ButtonPress'

Back from 'ButtonRelease'

^C



tclsh exahgnn.tcl 1

Back from 'Button'

Op1 selected



tk_popup>tclsh exahgnn.tcl 2

Back from 'Button'

Op2 selected

}



Click on article to view all threads in comp.lang.tcl
Re: ISO a way to select programmatically an entry from a popup
Posted by greg <gregor.ebbing@gmx.de> 2 weeks 3 days ago

Am 15.09.24 um 15:01 schrieb greg:

> 
>      list tk_popup $popup $x $y

> 
> .popup invoke $num
> 

Bad idea, after that the script will no longer work for normal use.

Click on article to view all threads in comp.lang.tcl
Re: ISO a way to select programmatically an entry from a popup
Posted by Helmut Giese <hgiese@ratiosoft.com> 2 weeks 2 days ago

Hello Greg,
many thanks for caring for my problem. It turned out that my question
was not precise enough: 
I am developping unit tests for my app and tried to simulate user
actions. In this course I found out that during a popup window the app
doesn't react to any 'event generate' commands, neither mouse nor
keyboard events - and this seems to be true.
Many thanks again
Helmut

Click on article to view all threads in comp.lang.tcl