|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bind Menubutton <FocusIn> {} |
|
bind Menubutton <Enter> { |
|
tk::MbEnter %W |
|
} |
|
bind Menubutton <Leave> { |
|
tk::MbLeave %W |
|
} |
|
bind Menubutton <1> { |
|
if {$tk::Priv(inMenubutton) ne ""} { |
|
tk::MbPost $tk::Priv(inMenubutton) %X %Y |
|
} |
|
} |
|
bind Menubutton <Motion> { |
|
tk::MbMotion %W up %X %Y |
|
} |
|
bind Menubutton <B1-Motion> { |
|
tk::MbMotion %W down %X %Y |
|
} |
|
bind Menubutton <ButtonRelease-1> { |
|
tk::MbButtonUp %W |
|
} |
|
bind Menubutton <space> { |
|
tk::MbPost %W |
|
tk::MenuFirstEntry [%W cget -menu] |
|
} |
|
bind Menubutton <<Invoke>> { |
|
tk::MbPost %W |
|
tk::MenuFirstEntry [%W cget -menu] |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bind Menu <FocusIn> {} |
|
|
|
bind Menu <Enter> { |
|
set tk::Priv(window) %W |
|
if {[%W cget -type] eq "tearoff"} { |
|
if {"%m" ne "NotifyUngrab"} { |
|
if {[tk windowingsystem] eq "x11"} { |
|
tk_menuSetFocus %W |
|
} |
|
} |
|
} |
|
tk::MenuMotion %W %x %y %s |
|
} |
|
|
|
bind Menu <Leave> { |
|
tk::MenuLeave %W %X %Y %s |
|
} |
|
bind Menu <Motion> { |
|
tk::MenuMotion %W %x %y %s |
|
} |
|
bind Menu <ButtonPress> { |
|
tk::MenuButtonDown %W |
|
} |
|
bind Menu <ButtonRelease> { |
|
tk::MenuInvoke %W 1 |
|
} |
|
bind Menu <space> { |
|
tk::MenuInvoke %W 0 |
|
} |
|
bind Menu <<Invoke>> { |
|
tk::MenuInvoke %W 0 |
|
} |
|
bind Menu <Return> { |
|
tk::MenuInvoke %W 0 |
|
} |
|
bind Menu <Escape> { |
|
tk::MenuEscape %W |
|
} |
|
bind Menu <<PrevChar>> { |
|
tk::MenuLeftArrow %W |
|
} |
|
bind Menu <<NextChar>> { |
|
tk::MenuRightArrow %W |
|
} |
|
bind Menu <<PrevLine>> { |
|
tk::MenuUpArrow %W |
|
} |
|
bind Menu <<NextLine>> { |
|
tk::MenuDownArrow %W |
|
} |
|
bind Menu <KeyPress> { |
|
tk::TraverseWithinMenu %W %A |
|
break |
|
} |
|
|
|
|
|
|
|
|
|
if {[tk windowingsystem] eq "x11"} { |
|
bind all <Alt-KeyPress> { |
|
tk::TraverseToMenu %W %A |
|
} |
|
|
|
bind all <F10> { |
|
tk::FirstMenu %W |
|
} |
|
} else { |
|
bind Menubutton <Alt-KeyPress> { |
|
tk::TraverseToMenu %W %A |
|
} |
|
|
|
bind Menubutton <F10> { |
|
tk::FirstMenu %W |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MbEnter w { |
|
variable ::tk::Priv |
|
|
|
if {$Priv(inMenubutton) ne ""} { |
|
MbLeave $Priv(inMenubutton) |
|
} |
|
set Priv(inMenubutton) $w |
|
if {[$w cget -state] ne "disabled" && [tk windowingsystem] ne "aqua"} { |
|
$w configure -state active |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MbLeave w { |
|
variable ::tk::Priv |
|
|
|
set Priv(inMenubutton) {} |
|
if {![winfo exists $w]} { |
|
return |
|
} |
|
if {[$w cget -state] eq "active" && [tk windowingsystem] ne "aqua"} { |
|
$w configure -state normal |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MbPost {w {x {}} {y {}}} { |
|
global errorInfo |
|
variable ::tk::Priv |
|
|
|
if {[$w cget -state] eq "disabled" || $w eq $Priv(postedMb)} { |
|
return |
|
} |
|
set menu [$w cget -menu] |
|
if {$menu eq ""} { |
|
return |
|
} |
|
set tearoff [expr {[tk windowingsystem] eq "x11" \ |
|
|| [$menu cget -type] eq "tearoff"}] |
|
if {[string first $w $menu] != 0} { |
|
return -code error -errorcode {TK MENUBUTTON POST_NONCHILD} \ |
|
"can't post $menu: it isn't a descendant of $w" |
|
} |
|
set cur $Priv(postedMb) |
|
if {$cur ne ""} { |
|
MenuUnpost {} |
|
} |
|
if {$::tk_strictMotif} { |
|
set Priv(cursor) [$w cget -cursor] |
|
$w configure -cursor arrow |
|
} |
|
if {[tk windowingsystem] ne "aqua"} { |
|
set Priv(relief) [$w cget -relief] |
|
$w configure -relief raised |
|
} else { |
|
$w configure -state active |
|
} |
|
|
|
set Priv(postedMb) $w |
|
set Priv(focus) [focus] |
|
$menu activate none |
|
GenerateMenuSelect $menu |
|
|
|
|
|
|
|
|
|
|
|
update idletasks |
|
if {[catch { |
|
switch [$w cget -direction] { |
|
above { |
|
set x [winfo rootx $w] |
|
set y [expr {[winfo rooty $w] - [winfo reqheight $menu]}] |
|
|
|
if {$y < [winfo vrooty $w]} { |
|
set y [expr {[winfo vrooty $w] + [winfo rooty $w] + [winfo reqheight $w]}] |
|
} |
|
PostOverPoint $menu $x $y |
|
} |
|
below { |
|
set x [winfo rootx $w] |
|
set y [expr {[winfo rooty $w] + [winfo height $w]}] |
|
|
|
set mh [winfo reqheight $menu] |
|
if {($y + $mh) > ([winfo vrooty $w] + [winfo vrootheight $w])} { |
|
set y [expr {[winfo vrooty $w] + [winfo vrootheight $w] + [winfo rooty $w] - $mh}] |
|
} |
|
PostOverPoint $menu $x $y |
|
} |
|
left { |
|
set x [expr {[winfo rootx $w] - [winfo reqwidth $menu]}] |
|
set y [expr {(2 * [winfo rooty $w] + [winfo height $w]) / 2}] |
|
set entry [MenuFindName $menu [$w cget -text]] |
|
if {$entry eq ""} { |
|
set entry 0 |
|
} |
|
if {[$w cget -indicatoron]} { |
|
if {$entry == [$menu index last]} { |
|
incr y [expr {-([$menu yposition $entry] \ |
|
+ [winfo reqheight $menu])/2}] |
|
} else { |
|
incr y [expr {-([$menu yposition $entry] \ |
|
+ [$menu yposition [expr {$entry+1}]])/2}] |
|
} |
|
} |
|
PostOverPoint $menu $x $y |
|
if {$entry ne "" \ |
|
&& [$menu entrycget $entry -state] ne "disabled"} { |
|
$menu activate $entry |
|
GenerateMenuSelect $menu |
|
} |
|
} |
|
right { |
|
set x [expr {[winfo rootx $w] + [winfo width $w]}] |
|
set y [expr {(2 * [winfo rooty $w] + [winfo height $w]) / 2}] |
|
set entry [MenuFindName $menu [$w cget -text]] |
|
if {$entry eq ""} { |
|
set entry 0 |
|
} |
|
if {[$w cget -indicatoron]} { |
|
if {$entry == [$menu index last]} { |
|
incr y [expr {-([$menu yposition $entry] \ |
|
+ [winfo reqheight $menu])/2}] |
|
} else { |
|
incr y [expr {-([$menu yposition $entry] \ |
|
+ [$menu yposition [expr {$entry+1}]])/2}] |
|
} |
|
} |
|
PostOverPoint $menu $x $y |
|
if {$entry ne "" \ |
|
&& [$menu entrycget $entry -state] ne "disabled"} { |
|
$menu activate $entry |
|
GenerateMenuSelect $menu |
|
} |
|
} |
|
default { |
|
if {[$w cget -indicatoron]} { |
|
if {$y eq ""} { |
|
set x [expr {[winfo rootx $w] + [winfo width $w]/2}] |
|
set y [expr {[winfo rooty $w] + [winfo height $w]/2}] |
|
} |
|
PostOverPoint $menu $x $y [MenuFindName $menu [$w cget -text]] |
|
} else { |
|
PostOverPoint $menu [winfo rootx $w] [expr {[winfo rooty $w]+[winfo height $w]}] |
|
} |
|
} |
|
} |
|
} msg opt]} { |
|
|
|
|
|
|
|
MenuUnpost {} |
|
return -options $opt $msg |
|
} |
|
|
|
set Priv(tearoff) $tearoff |
|
if {$tearoff != 0} { |
|
focus $menu |
|
if {[winfo viewable $w]} { |
|
SaveGrabInfo $w |
|
grab -global $w |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuUnpost menu { |
|
variable ::tk::Priv |
|
set mb $Priv(postedMb) |
|
|
|
|
|
|
|
|
|
|
|
catch {focus $Priv(focus)} |
|
set Priv(focus) "" |
|
|
|
|
|
|
|
|
|
after cancel [array get Priv menuActivatedTimer] |
|
unset -nocomplain Priv(menuActivated) |
|
after cancel [array get Priv menuDeactivatedTimer] |
|
unset -nocomplain Priv(menuDeactivated) |
|
|
|
catch { |
|
if {$mb ne ""} { |
|
set menu [$mb cget -menu] |
|
$menu unpost |
|
set Priv(postedMb) {} |
|
if {$::tk_strictMotif} { |
|
$mb configure -cursor $Priv(cursor) |
|
} |
|
if {[tk windowingsystem] ne "aqua"} { |
|
$mb configure -relief $Priv(relief) |
|
} else { |
|
$mb configure -state normal |
|
} |
|
} elseif {$Priv(popup) ne ""} { |
|
$Priv(popup) unpost |
|
set Priv(popup) {} |
|
} elseif {[$menu cget -type] ne "menubar" && [$menu cget -type] ne "tearoff"} { |
|
|
|
|
|
|
|
|
|
|
|
while {1} { |
|
set parent [winfo parent $menu] |
|
if {[winfo class $parent] ne "Menu" || ![winfo ismapped $parent]} { |
|
break |
|
} |
|
$parent activate none |
|
$parent postcascade none |
|
GenerateMenuSelect $parent |
|
set type [$parent cget -type] |
|
if {$type eq "menubar" || $type eq "tearoff"} { |
|
break |
|
} |
|
set menu $parent |
|
} |
|
if {[$menu cget -type] ne "menubar"} { |
|
$menu unpost |
|
} |
|
} |
|
} |
|
|
|
if {($Priv(tearoff) != 0) || $Priv(menuBar) ne ""} { |
|
|
|
|
|
if {$menu ne ""} { |
|
set grab [grab current $menu] |
|
if {$grab ne ""} { |
|
grab release $grab |
|
} |
|
} |
|
RestoreOldGrab |
|
if {$Priv(menuBar) ne ""} { |
|
if {$::tk_strictMotif} { |
|
$Priv(menuBar) configure -cursor $Priv(cursor) |
|
} |
|
set Priv(menuBar) {} |
|
} |
|
if {[tk windowingsystem] ne "x11"} { |
|
set Priv(tearoff) 0 |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MbMotion {w upDown rootx rooty} { |
|
variable ::tk::Priv |
|
|
|
if {$Priv(inMenubutton) eq $w} { |
|
return |
|
} |
|
set new [winfo containing $rootx $rooty] |
|
if {$new ne $Priv(inMenubutton) \ |
|
&& ($new eq "" || [winfo toplevel $new] eq [winfo toplevel $w])} { |
|
if {$Priv(inMenubutton) ne ""} { |
|
MbLeave $Priv(inMenubutton) |
|
} |
|
if {$new ne "" \ |
|
&& [winfo class $new] eq "Menubutton" \ |
|
&& ([$new cget -indicatoron] == 0) \ |
|
&& ([$w cget -indicatoron] == 0)} { |
|
if {$upDown eq "down"} { |
|
MbPost $new $rootx $rooty |
|
} else { |
|
MbEnter $new |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MbButtonUp w { |
|
variable ::tk::Priv |
|
|
|
set menu [$w cget -menu] |
|
set tearoff [expr {[tk windowingsystem] eq "x11" || \ |
|
($menu ne "" && [$menu cget -type] eq "tearoff")}] |
|
if {($tearoff != 0) && $Priv(postedMb) eq $w \ |
|
&& $Priv(inMenubutton) eq $w} { |
|
MenuFirstEntry [$Priv(postedMb) cget -menu] |
|
} else { |
|
MenuUnpost {} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuMotion {menu x y state} { |
|
variable ::tk::Priv |
|
if {$menu eq $Priv(window)} { |
|
set activeindex [$menu index active] |
|
if {[$menu cget -type] eq "menubar"} { |
|
if {[info exists Priv(focus)] && $menu ne $Priv(focus)} { |
|
$menu activate @$x,$y |
|
GenerateMenuSelect $menu |
|
} |
|
} else { |
|
$menu activate @$x,$y |
|
GenerateMenuSelect $menu |
|
} |
|
set index [$menu index @$x,$y] |
|
if {[info exists Priv(menuActivated)] \ |
|
&& $index ne "none" \ |
|
&& $index ne $activeindex} { |
|
set mode [option get $menu clickToFocus ClickToFocus] |
|
if {[string is false $mode]} { |
|
set delay [expr {[$menu cget -type] eq "menubar" ? 0 : 50}] |
|
if {[$menu type $index] eq "cascade"} { |
|
set Priv(menuActivatedTimer) \ |
|
[after $delay [list $menu postcascade active]] |
|
} else { |
|
set Priv(menuDeactivatedTimer) \ |
|
[after $delay [list $menu postcascade none]] |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuButtonDown menu { |
|
variable ::tk::Priv |
|
|
|
if {![winfo viewable $menu]} { |
|
return |
|
} |
|
if {[$menu index active] eq "none"} { |
|
if {[$menu cget -type] ne "menubar" } { |
|
set Priv(window) {} |
|
} |
|
return |
|
} |
|
$menu postcascade active |
|
if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} { |
|
grab -global $Priv(postedMb) |
|
} else { |
|
while {[$menu cget -type] eq "normal" \ |
|
&& [winfo class [winfo parent $menu]] eq "Menu" \ |
|
&& [winfo ismapped [winfo parent $menu]]} { |
|
set menu [winfo parent $menu] |
|
} |
|
|
|
if {$Priv(menuBar) eq {}} { |
|
set Priv(menuBar) $menu |
|
if {$::tk_strictMotif} { |
|
set Priv(cursor) [$menu cget -cursor] |
|
$menu configure -cursor arrow |
|
} |
|
if {[$menu type active] eq "cascade"} { |
|
set Priv(menuActivated) 1 |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
if {$menu ne [grab current $menu]} { |
|
SaveGrabInfo $menu |
|
} |
|
|
|
|
|
|
|
|
|
if {[tk windowingsystem] eq "x11"} { |
|
grab -global $menu |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuLeave {menu rootx rooty state} { |
|
variable ::tk::Priv |
|
set Priv(window) {} |
|
if {[$menu index active] eq "none"} { |
|
return |
|
} |
|
if {[$menu type active] eq "cascade" \ |
|
&& [winfo containing $rootx $rooty] eq \ |
|
[$menu entrycget active -menu]} { |
|
return |
|
} |
|
$menu activate none |
|
GenerateMenuSelect $menu |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuInvoke {w buttonRelease} { |
|
variable ::tk::Priv |
|
|
|
if {$buttonRelease && $Priv(window) eq ""} { |
|
|
|
|
|
|
|
|
|
$w postcascade none |
|
$w activate none |
|
event generate $w <<MenuSelect>> |
|
MenuUnpost $w |
|
return |
|
} |
|
if {[$w type active] eq "cascade"} { |
|
$w postcascade active |
|
set menu [$w entrycget active -menu] |
|
MenuFirstEntry $menu |
|
} elseif {[$w type active] eq "tearoff"} { |
|
::tk::TearOffMenu $w |
|
MenuUnpost $w |
|
} elseif {[$w cget -type] eq "menubar"} { |
|
$w postcascade none |
|
set active [$w index active] |
|
set isCascade [string equal [$w type $active] "cascade"] |
|
|
|
|
|
|
|
|
|
|
|
if { $isCascade } { |
|
$w activate none |
|
event generate $w <<MenuSelect>> |
|
} |
|
|
|
MenuUnpost $w |
|
|
|
|
|
|
|
|
|
|
|
if { !$isCascade } { |
|
uplevel #0 [list $w invoke $active] |
|
} |
|
} else { |
|
set active [$w index active] |
|
if {$Priv(popup) eq "" || $active ne "none"} { |
|
MenuUnpost $w |
|
} |
|
uplevel #0 [list $w invoke active] |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuEscape menu { |
|
set parent [winfo parent $menu] |
|
if {[winfo class $parent] ne "Menu"} { |
|
MenuUnpost $menu |
|
} elseif {[$parent cget -type] eq "menubar"} { |
|
MenuUnpost $menu |
|
RestoreOldGrab |
|
} else { |
|
MenuNextMenu $menu left |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
proc ::tk::MenuUpArrow {menu} { |
|
if {[$menu cget -type] eq "menubar"} { |
|
MenuNextMenu $menu left |
|
} else { |
|
MenuNextEntry $menu -1 |
|
} |
|
} |
|
|
|
proc ::tk::MenuDownArrow {menu} { |
|
if {[$menu cget -type] eq "menubar"} { |
|
MenuNextMenu $menu right |
|
} else { |
|
MenuNextEntry $menu 1 |
|
} |
|
} |
|
|
|
proc ::tk::MenuLeftArrow {menu} { |
|
if {[$menu cget -type] eq "menubar"} { |
|
MenuNextEntry $menu -1 |
|
} else { |
|
MenuNextMenu $menu left |
|
} |
|
} |
|
|
|
proc ::tk::MenuRightArrow {menu} { |
|
if {[$menu cget -type] eq "menubar"} { |
|
MenuNextEntry $menu 1 |
|
} else { |
|
MenuNextMenu $menu right |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuNextMenu {menu direction} { |
|
variable ::tk::Priv |
|
|
|
|
|
|
|
if {$direction eq "right"} { |
|
set count 1 |
|
set parent [winfo parent $menu] |
|
set class [winfo class $parent] |
|
if {[$menu type active] eq "cascade"} { |
|
$menu postcascade active |
|
set m2 [$menu entrycget active -menu] |
|
if {$m2 ne ""} { |
|
MenuFirstEntry $m2 |
|
} |
|
return |
|
} else { |
|
set parent [winfo parent $menu] |
|
while {$parent ne "."} { |
|
if {[winfo class $parent] eq "Menu" \ |
|
&& [$parent cget -type] eq "menubar"} { |
|
tk_menuSetFocus $parent |
|
MenuNextEntry $parent 1 |
|
return |
|
} |
|
set parent [winfo parent $parent] |
|
} |
|
} |
|
} else { |
|
set count -1 |
|
set m2 [winfo parent $menu] |
|
if {[winfo class $m2] eq "Menu"} { |
|
$menu activate none |
|
GenerateMenuSelect $menu |
|
tk_menuSetFocus $m2 |
|
|
|
$m2 postcascade none |
|
|
|
if {[$m2 cget -type] ne "menubar"} { |
|
return |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
set m2 [winfo parent $menu] |
|
if {[winfo class $m2] eq "Menu" && [$m2 cget -type] eq "menubar"} { |
|
tk_menuSetFocus $m2 |
|
MenuNextEntry $m2 -1 |
|
return |
|
} |
|
|
|
set w $Priv(postedMb) |
|
if {$w eq ""} { |
|
return |
|
} |
|
set buttons [winfo children [winfo parent $w]] |
|
set length [llength $buttons] |
|
set i [expr {[lsearch -exact $buttons $w] + $count}] |
|
while {1} { |
|
while {$i < 0} { |
|
incr i $length |
|
} |
|
while {$i >= $length} { |
|
incr i -$length |
|
} |
|
set mb [lindex $buttons $i] |
|
if {[winfo class $mb] eq "Menubutton" \ |
|
&& [$mb cget -state] ne "disabled" \ |
|
&& [$mb cget -menu] ne "" \ |
|
&& [[$mb cget -menu] index last] ne "none"} { |
|
break |
|
} |
|
if {$mb eq $w} { |
|
return |
|
} |
|
incr i $count |
|
} |
|
MbPost $mb |
|
MenuFirstEntry [$mb cget -menu] |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuNextEntry {menu count} { |
|
if {[$menu index last] eq "none"} { |
|
return |
|
} |
|
set length [expr {[$menu index last]+1}] |
|
set quitAfter $length |
|
set active [$menu index active] |
|
if {$active eq "none"} { |
|
set i 0 |
|
} else { |
|
set i [expr {$active + $count}] |
|
} |
|
while {1} { |
|
if {$quitAfter <= 0} { |
|
|
|
|
|
|
|
return |
|
} |
|
while {$i < 0} { |
|
incr i $length |
|
} |
|
while {$i >= $length} { |
|
incr i -$length |
|
} |
|
if {[catch {$menu entrycget $i -state} state] == 0} { |
|
if {$state ne "disabled" && \ |
|
($i!=0 || [$menu cget -type] ne "tearoff" \ |
|
|| [$menu type 0] ne "tearoff")} { |
|
break |
|
} |
|
} |
|
if {$i == $active} { |
|
return |
|
} |
|
incr i $count |
|
incr quitAfter -1 |
|
} |
|
$menu activate $i |
|
GenerateMenuSelect $menu |
|
|
|
if {[$menu type $i] eq "cascade" && [$menu cget -type] eq "menubar"} { |
|
set cascade [$menu entrycget $i -menu] |
|
if {$cascade ne ""} { |
|
|
|
|
|
|
|
$menu postcascade $i |
|
MenuFirstEntry $cascade |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuFind {w char} { |
|
set char [string tolower $char] |
|
set windowlist [winfo child $w] |
|
|
|
foreach child $windowlist { |
|
|
|
if {[winfo toplevel $w] ne [winfo toplevel $child]} { |
|
continue |
|
} |
|
if {[winfo class $child] eq "Menu" && \ |
|
[$child cget -type] eq "menubar"} { |
|
if {$char eq ""} { |
|
return $child |
|
} |
|
set last [$child index last] |
|
for {set i [$child cget -tearoff]} {$i <= $last} {incr i} { |
|
if {[$child type $i] eq "separator"} { |
|
continue |
|
} |
|
set char2 [string index [$child entrycget $i -label] \ |
|
[$child entrycget $i -underline]] |
|
if {$char eq [string tolower $char2] || $char eq ""} { |
|
if {[$child entrycget $i -state] ne "disabled"} { |
|
return $child |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
foreach child $windowlist { |
|
|
|
if {[winfo toplevel $w] ne [winfo toplevel $child]} { |
|
continue |
|
} |
|
switch -- [winfo class $child] { |
|
Menubutton { |
|
set char2 [string index [$child cget -text] \ |
|
[$child cget -underline]] |
|
if {$char eq [string tolower $char2] || $char eq ""} { |
|
if {[$child cget -state] ne "disabled"} { |
|
return $child |
|
} |
|
} |
|
} |
|
|
|
default { |
|
set match [MenuFind $child $char] |
|
if {$match ne ""} { |
|
return $match |
|
} |
|
} |
|
} |
|
} |
|
return {} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::TraverseToMenu {w char} { |
|
variable ::tk::Priv |
|
if {![winfo exists $w] || $char eq ""} { |
|
return |
|
} |
|
while {[winfo class $w] eq "Menu"} { |
|
if {[$w cget -type] eq "menubar"} { |
|
break |
|
} elseif {$Priv(postedMb) eq ""} { |
|
return |
|
} |
|
set w [winfo parent $w] |
|
} |
|
set w [MenuFind [winfo toplevel $w] $char] |
|
if {$w ne ""} { |
|
if {[winfo class $w] eq "Menu"} { |
|
tk_menuSetFocus $w |
|
set Priv(window) $w |
|
SaveGrabInfo $w |
|
grab -global $w |
|
TraverseWithinMenu $w $char |
|
} else { |
|
MbPost $w |
|
MenuFirstEntry [$w cget -menu] |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::FirstMenu w { |
|
variable ::tk::Priv |
|
set w [MenuFind [winfo toplevel $w] ""] |
|
if {$w ne ""} { |
|
if {[winfo class $w] eq "Menu"} { |
|
tk_menuSetFocus $w |
|
set Priv(window) $w |
|
SaveGrabInfo $w |
|
grab -global $w |
|
MenuFirstEntry $w |
|
} else { |
|
MbPost $w |
|
MenuFirstEntry [$w cget -menu] |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::TraverseWithinMenu {w char} { |
|
if {$char eq ""} { |
|
return |
|
} |
|
set char [string tolower $char] |
|
set last [$w index last] |
|
if {$last eq "none"} { |
|
return |
|
} |
|
for {set i 0} {$i <= $last} {incr i} { |
|
if {[catch {set char2 [string index \ |
|
[$w entrycget $i -label] [$w entrycget $i -underline]]}]} { |
|
continue |
|
} |
|
if {$char eq [string tolower $char2]} { |
|
if {[$w type $i] eq "cascade"} { |
|
$w activate $i |
|
$w postcascade active |
|
event generate $w <<MenuSelect>> |
|
set m2 [$w entrycget $i -menu] |
|
if {$m2 ne ""} { |
|
MenuFirstEntry $m2 |
|
} |
|
} else { |
|
MenuUnpost $w |
|
uplevel #0 [list $w invoke $i] |
|
} |
|
return |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuFirstEntry menu { |
|
if {$menu eq ""} { |
|
return |
|
} |
|
tk_menuSetFocus $menu |
|
if {[$menu index active] ne "none"} { |
|
return |
|
} |
|
set last [$menu index last] |
|
if {$last eq "none"} { |
|
return |
|
} |
|
for {set i 0} {$i <= $last} {incr i} { |
|
if {([catch {set state [$menu entrycget $i -state]}] == 0) \ |
|
&& $state ne "disabled" && [$menu type $i] ne "tearoff"} { |
|
$menu activate $i |
|
GenerateMenuSelect $menu |
|
|
|
|
|
|
|
|
|
if {[$menu type $i] eq "cascade" && [$menu cget -type] eq "menubar"} { |
|
set cascade [$menu entrycget $i -menu] |
|
if {$cascade ne ""} { |
|
$menu postcascade $i |
|
MenuFirstEntry $cascade |
|
} |
|
} |
|
return |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::MenuFindName {menu s} { |
|
set i "" |
|
if {![regexp {^active$|^last$|^none$|^[0-9]|^@} $s]} { |
|
catch {set i [$menu index $s]} |
|
return $i |
|
} |
|
set last [$menu index last] |
|
if {$last eq "none"} { |
|
return |
|
} |
|
for {set i 0} {$i <= $last} {incr i} { |
|
if {![catch {$menu entrycget $i -label} label]} { |
|
if {$label eq $s} { |
|
return $i |
|
} |
|
} |
|
} |
|
return "" |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::PostOverPoint {menu x y {entry {}}} { |
|
if {$entry ne ""} { |
|
if {$entry == [$menu index last]} { |
|
incr y [expr {-([$menu yposition $entry] \ |
|
+ [winfo reqheight $menu])/2}] |
|
} else { |
|
incr y [expr {-([$menu yposition $entry] \ |
|
+ [$menu yposition [expr {$entry+1}]])/2}] |
|
} |
|
incr x [expr {-[winfo reqwidth $menu]/2}] |
|
} |
|
|
|
if {[tk windowingsystem] eq "win32"} { |
|
|
|
set ver 5 |
|
if {[info exists ::tcl_platform(osVersion)]} { |
|
scan $::tcl_platform(osVersion) %d ver |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if {$ver < 6} { |
|
set yoffset [expr {[winfo screenheight $menu] \ |
|
- $y - [winfo reqheight $menu] - 10}] |
|
if {$yoffset < [winfo vrooty $menu]} { |
|
|
|
incr y [expr {$yoffset - [winfo vrooty $menu]}] |
|
} |
|
|
|
|
|
|
|
if {$y < [winfo vrooty $menu]} { |
|
set y [winfo vrooty $menu] |
|
} |
|
} |
|
} |
|
$menu post $x $y |
|
if {$entry ne "" && [$menu entrycget $entry -state] ne "disabled"} { |
|
$menu activate $entry |
|
GenerateMenuSelect $menu |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc tk::SaveGrabInfo w { |
|
variable ::tk::Priv |
|
set Priv(oldGrab) [grab current $w] |
|
if {$Priv(oldGrab) ne ""} { |
|
set Priv(grabStatus) [grab status $Priv(oldGrab)] |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
proc ::tk::RestoreOldGrab {} { |
|
variable ::tk::Priv |
|
|
|
if {$Priv(oldGrab) ne ""} { |
|
|
|
|
|
|
|
catch { |
|
if {$Priv(grabStatus) eq "global"} { |
|
grab set -global $Priv(oldGrab) |
|
} else { |
|
grab set $Priv(oldGrab) |
|
} |
|
} |
|
set Priv(oldGrab) "" |
|
} |
|
} |
|
|
|
proc ::tk_menuSetFocus {menu} { |
|
variable ::tk::Priv |
|
if {![info exists Priv(focus)] || $Priv(focus) eq ""} { |
|
set Priv(focus) [focus] |
|
} |
|
focus $menu |
|
} |
|
|
|
proc ::tk::GenerateMenuSelect {menu} { |
|
variable ::tk::Priv |
|
|
|
if {$Priv(activeMenu) eq $menu \ |
|
&& $Priv(activeItem) eq [$menu index active]} { |
|
return |
|
} |
|
|
|
set Priv(activeMenu) $menu |
|
set Priv(activeItem) [$menu index active] |
|
event generate $menu <<MenuSelect>> |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc ::tk_popup {menu x y {entry {}}} { |
|
variable ::tk::Priv |
|
if {$Priv(popup) ne "" || $Priv(postedMb) ne ""} { |
|
tk::MenuUnpost {} |
|
} |
|
tk::PostOverPoint $menu $x $y $entry |
|
if {[tk windowingsystem] eq "x11" && [winfo viewable $menu]} { |
|
tk::SaveGrabInfo $menu |
|
grab -global $menu |
|
set Priv(popup) $menu |
|
set Priv(window) $menu |
|
set Priv(menuActivated) 1 |
|
tk_menuSetFocus $menu |
|
} |
|
} |
|
|