button.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:16k
源码类别:

通讯编程

开发平台:

Visual C++

  1. # button.tcl --
  2. #
  3. # This file defines the default bindings for Tk label, button,
  4. # checkbutton, and radiobutton widgets and provides procedures
  5. # that help in implementing those bindings.
  6. #
  7. # RCS: @(#) $Id: button.tcl,v 1.17.2.1 2006/01/25 18:21:41 dgp Exp $
  8. #
  9. # Copyright (c) 1992-1994 The Regents of the University of California.
  10. # Copyright (c) 1994-1996 Sun Microsystems, Inc.
  11. # Copyright (c) 2002 ActiveState Corporation.
  12. #
  13. # See the file "license.terms" for information on usage and redistribution
  14. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15. #
  16. #-------------------------------------------------------------------------
  17. # The code below creates the default class bindings for buttons.
  18. #-------------------------------------------------------------------------
  19. if {[tk windowingsystem] eq "classic" || [tk windowingsystem] eq "aqua"} {
  20.     bind Radiobutton <Enter> {
  21. tk::ButtonEnter %W
  22.     }
  23.     bind Radiobutton <1> {
  24. tk::ButtonDown %W
  25.     }
  26.     bind Radiobutton <ButtonRelease-1> {
  27. tk::ButtonUp %W
  28.     }
  29.     bind Checkbutton <Enter> {
  30. tk::ButtonEnter %W
  31.     }
  32.     bind Checkbutton <1> {
  33. tk::ButtonDown %W
  34.     }
  35.     bind Checkbutton <ButtonRelease-1> {
  36. tk::ButtonUp %W
  37.     }
  38. }
  39. if {"windows" eq $tcl_platform(platform)} {
  40.     bind Checkbutton <equal> {
  41. tk::CheckRadioInvoke %W select
  42.     }
  43.     bind Checkbutton <plus> {
  44. tk::CheckRadioInvoke %W select
  45.     }
  46.     bind Checkbutton <minus> {
  47. tk::CheckRadioInvoke %W deselect
  48.     }
  49.     bind Checkbutton <1> {
  50. tk::CheckRadioDown %W
  51.     }
  52.     bind Checkbutton <ButtonRelease-1> {
  53. tk::ButtonUp %W
  54.     }
  55.     bind Checkbutton <Enter> {
  56. tk::CheckRadioEnter %W
  57.     }
  58.     bind Radiobutton <1> {
  59. tk::CheckRadioDown %W
  60.     }
  61.     bind Radiobutton <ButtonRelease-1> {
  62. tk::ButtonUp %W
  63.     }
  64.     bind Radiobutton <Enter> {
  65. tk::CheckRadioEnter %W
  66.     }
  67. }
  68. if {"x11" eq [tk windowingsystem]} {
  69.     bind Checkbutton <Return> {
  70. if {!$tk_strictMotif} {
  71.     tk::CheckRadioInvoke %W
  72. }
  73.     }
  74.     bind Radiobutton <Return> {
  75. if {!$tk_strictMotif} {
  76.     tk::CheckRadioInvoke %W
  77. }
  78.     }
  79.     bind Checkbutton <1> {
  80. tk::CheckRadioInvoke %W
  81.     }
  82.     bind Radiobutton <1> {
  83. tk::CheckRadioInvoke %W
  84.     }
  85.     bind Checkbutton <Enter> {
  86. tk::ButtonEnter %W
  87.     }
  88.     bind Radiobutton <Enter> {
  89. tk::ButtonEnter %W
  90.     }
  91. }
  92. bind Button <space> {
  93.     tk::ButtonInvoke %W
  94. }
  95. bind Checkbutton <space> {
  96.     tk::CheckRadioInvoke %W
  97. }
  98. bind Radiobutton <space> {
  99.     tk::CheckRadioInvoke %W
  100. }
  101. bind Button <FocusIn> {}
  102. bind Button <Enter> {
  103.     tk::ButtonEnter %W
  104. }
  105. bind Button <Leave> {
  106.     tk::ButtonLeave %W
  107. }
  108. bind Button <1> {
  109.     tk::ButtonDown %W
  110. }
  111. bind Button <ButtonRelease-1> {
  112.     tk::ButtonUp %W
  113. }
  114. bind Checkbutton <FocusIn> {}
  115. bind Checkbutton <Leave> {
  116.     tk::ButtonLeave %W
  117. }
  118. bind Radiobutton <FocusIn> {}
  119. bind Radiobutton <Leave> {
  120.     tk::ButtonLeave %W
  121. }
  122. if {"windows" eq $tcl_platform(platform)} {
  123. #########################
  124. # Windows implementation 
  125. #########################
  126. # ::tk::ButtonEnter --
  127. # The procedure below is invoked when the mouse pointer enters a
  128. # button widget.  It records the button we're in and changes the
  129. # state of the button to active unless the button is disabled.
  130. #
  131. # Arguments:
  132. # w - The name of the widget.
  133. proc ::tk::ButtonEnter w {
  134.     variable ::tk::Priv
  135.     if {[$w cget -state] ne "disabled"} {
  136. # If the mouse button is down, set the relief to sunken on entry.
  137. # Overwise, if there's an -overrelief value, set the relief to that.
  138. set Priv($w,relief) [$w cget -relief]
  139. if {$Priv(buttonWindow) eq $w} {
  140.     $w configure -relief sunken -state active
  141.     set Priv($w,prelief) sunken
  142. } elseif {[set over [$w cget -overrelief]] ne ""} {
  143.     $w configure -relief $over
  144.     set Priv($w,prelief) $over
  145. }
  146.     }
  147.     set Priv(window) $w
  148. }
  149. # ::tk::ButtonLeave --
  150. # The procedure below is invoked when the mouse pointer leaves a
  151. # button widget.  It changes the state of the button back to inactive.
  152. # Restore any modified relief too.
  153. #
  154. # Arguments:
  155. # w - The name of the widget.
  156. proc ::tk::ButtonLeave w {
  157.     variable ::tk::Priv
  158.     if {[$w cget -state] ne "disabled"} {
  159. $w configure -state normal
  160.     }
  161.     # Restore the original button relief if it was changed by Tk.
  162.     # That is signaled by the existence of Priv($w,prelief).
  163.     if {[info exists Priv($w,relief)]} {
  164. if {[info exists Priv($w,prelief)] && 
  165. $Priv($w,prelief) eq [$w cget -relief]} {
  166.     $w configure -relief $Priv($w,relief)
  167. }
  168. unset -nocomplain Priv($w,relief) Priv($w,prelief)
  169.     }
  170.     set Priv(window) ""
  171. }
  172. # ::tk::ButtonDown --
  173. # The procedure below is invoked when the mouse button is pressed in
  174. # a button widget.  It records the fact that the mouse is in the button,
  175. # saves the button's relief so it can be restored later, and changes
  176. # the relief to sunken.
  177. #
  178. # Arguments:
  179. # w - The name of the widget.
  180. proc ::tk::ButtonDown w {
  181.     variable ::tk::Priv
  182.     # Only save the button's relief if it does not yet exist.  If there
  183.     # is an overrelief setting, Priv($w,relief) will already have been set,
  184.     # and the current value of the -relief option will be incorrect.
  185.     if {![info exists Priv($w,relief)]} {
  186. set Priv($w,relief) [$w cget -relief]
  187.     }
  188.     if {[$w cget -state] ne "disabled"} {
  189. set Priv(buttonWindow) $w
  190. $w configure -relief sunken -state active
  191. set Priv($w,prelief) sunken
  192. # If this button has a repeatdelay set up, get it going with an after
  193. after cancel $Priv(afterId)
  194. set delay [$w cget -repeatdelay]
  195. set Priv(repeated) 0
  196. if {$delay > 0} {
  197.     set Priv(afterId) [after $delay [list tk::ButtonAutoInvoke $w]]
  198. }
  199.     }
  200. }
  201. # ::tk::ButtonUp --
  202. # The procedure below is invoked when the mouse button is released
  203. # in a button widget.  It restores the button's relief and invokes
  204. # the command as long as the mouse hasn't left the button.
  205. #
  206. # Arguments:
  207. # w - The name of the widget.
  208. proc ::tk::ButtonUp w {
  209.     variable ::tk::Priv
  210.     if {$Priv(buttonWindow) eq $w} {
  211. set Priv(buttonWindow) ""
  212. # Restore the button's relief if it was cached.
  213. if {[info exists Priv($w,relief)]} {
  214.     if {[info exists Priv($w,prelief)] && 
  215.     $Priv($w,prelief) eq [$w cget -relief]} {
  216. $w configure -relief $Priv($w,relief)
  217.     }
  218.     unset -nocomplain Priv($w,relief) Priv($w,prelief)
  219. }
  220. # Clean up the after event from the auto-repeater
  221. after cancel $Priv(afterId)
  222. if {$Priv(window) eq $w && [$w cget -state] ne "disabled"} {
  223.     $w configure -state normal
  224.     # Only invoke the command if it wasn't already invoked by the
  225.     # auto-repeater functionality
  226.     if { $Priv(repeated) == 0 } {
  227. uplevel #0 [list $w invoke]
  228.     }
  229. }
  230.     }
  231. }
  232. # ::tk::CheckRadioEnter --
  233. # The procedure below is invoked when the mouse pointer enters a
  234. # checkbutton or radiobutton widget.  It records the button we're in
  235. # and changes the state of the button to active unless the button is
  236. # disabled.
  237. #
  238. # Arguments:
  239. # w - The name of the widget.
  240. proc ::tk::CheckRadioEnter w {
  241.     variable ::tk::Priv
  242.     if {[$w cget -state] ne "disabled"} {
  243. if {$Priv(buttonWindow) eq $w} {
  244.     $w configure -state active
  245. }
  246. if {[set over [$w cget -overrelief]] ne ""} {
  247.     set Priv($w,relief)  [$w cget -relief]
  248.     set Priv($w,prelief) $over
  249.     $w configure -relief $over
  250. }
  251.     }
  252.     set Priv(window) $w
  253. }
  254. # ::tk::CheckRadioDown --
  255. # The procedure below is invoked when the mouse button is pressed in
  256. # a button widget.  It records the fact that the mouse is in the button,
  257. # saves the button's relief so it can be restored later, and changes
  258. # the relief to sunken.
  259. #
  260. # Arguments:
  261. # w - The name of the widget.
  262. proc ::tk::CheckRadioDown w {
  263.     variable ::tk::Priv
  264.     if {![info exists Priv($w,relief)]} {
  265. set Priv($w,relief) [$w cget -relief]
  266.     }
  267.     if {[$w cget -state] ne "disabled"} {
  268. set Priv(buttonWindow) $w
  269. set Priv(repeated) 0
  270. $w configure -state active
  271.     }
  272. }
  273. }
  274. if {"x11" eq [tk windowingsystem]} {
  275. #####################
  276. # Unix implementation
  277. #####################
  278. # ::tk::ButtonEnter --
  279. # The procedure below is invoked when the mouse pointer enters a
  280. # button widget.  It records the button we're in and changes the
  281. # state of the button to active unless the button is disabled.
  282. #
  283. # Arguments:
  284. # w - The name of the widget.
  285. proc ::tk::ButtonEnter {w} {
  286.     variable ::tk::Priv
  287.     if {[$w cget -state] ne "disabled"} {
  288. # On unix the state is active just with mouse-over
  289. $w configure -state active
  290. # If the mouse button is down, set the relief to sunken on entry.
  291. # Overwise, if there's an -overrelief value, set the relief to that.
  292. set Priv($w,relief) [$w cget -relief]
  293. if {$Priv(buttonWindow) eq $w} {
  294.     $w configure -relief sunken
  295.     set Priv($w,prelief) sunken
  296. } elseif {[set over [$w cget -overrelief]] ne ""} {
  297.     $w configure -relief $over
  298.     set Priv($w,prelief) $over
  299. }
  300.     }
  301.     set Priv(window) $w
  302. }
  303. # ::tk::ButtonLeave --
  304. # The procedure below is invoked when the mouse pointer leaves a
  305. # button widget.  It changes the state of the button back to inactive.
  306. # Restore any modified relief too.
  307. #
  308. # Arguments:
  309. # w - The name of the widget.
  310. proc ::tk::ButtonLeave w {
  311.     variable ::tk::Priv
  312.     if {[$w cget -state] ne "disabled"} {
  313. $w configure -state normal
  314.     }
  315.     # Restore the original button relief if it was changed by Tk.
  316.     # That is signaled by the existence of Priv($w,prelief).
  317.     if {[info exists Priv($w,relief)]} {
  318. if {[info exists Priv($w,prelief)] && 
  319. $Priv($w,prelief) eq [$w cget -relief]} {
  320.     $w configure -relief $Priv($w,relief)
  321. }
  322. unset -nocomplain Priv($w,relief) Priv($w,prelief)
  323.     }
  324.     set Priv(window) ""
  325. }
  326. # ::tk::ButtonDown --
  327. # The procedure below is invoked when the mouse button is pressed in
  328. # a button widget.  It records the fact that the mouse is in the button,
  329. # saves the button's relief so it can be restored later, and changes
  330. # the relief to sunken.
  331. #
  332. # Arguments:
  333. # w - The name of the widget.
  334. proc ::tk::ButtonDown w {
  335.     variable ::tk::Priv
  336.     # Only save the button's relief if it does not yet exist.  If there
  337.     # is an overrelief setting, Priv($w,relief) will already have been set,
  338.     # and the current value of the -relief option will be incorrect.
  339.     if {![info exists Priv($w,relief)]} {
  340. set Priv($w,relief) [$w cget -relief]
  341.     }
  342.     if {[$w cget -state] ne "disabled"} {
  343. set Priv(buttonWindow) $w
  344. $w configure -relief sunken
  345. set Priv($w,prelief) sunken
  346. # If this button has a repeatdelay set up, get it going with an after
  347. after cancel $Priv(afterId)
  348. set delay [$w cget -repeatdelay]
  349. set Priv(repeated) 0
  350. if {$delay > 0} {
  351.     set Priv(afterId) [after $delay [list tk::ButtonAutoInvoke $w]]
  352. }
  353.     }
  354. }
  355. # ::tk::ButtonUp --
  356. # The procedure below is invoked when the mouse button is released
  357. # in a button widget.  It restores the button's relief and invokes
  358. # the command as long as the mouse hasn't left the button.
  359. #
  360. # Arguments:
  361. # w - The name of the widget.
  362. proc ::tk::ButtonUp w {
  363.     variable ::tk::Priv
  364.     if {$w eq $Priv(buttonWindow)} {
  365. set Priv(buttonWindow) ""
  366. # Restore the button's relief if it was cached.
  367. if {[info exists Priv($w,relief)]} {
  368.     if {[info exists Priv($w,prelief)] && 
  369.     $Priv($w,prelief) eq [$w cget -relief]} {
  370. $w configure -relief $Priv($w,relief)
  371.     }
  372.     unset -nocomplain Priv($w,relief) Priv($w,prelief)
  373. }
  374. # Clean up the after event from the auto-repeater
  375. after cancel $Priv(afterId)
  376. if {$Priv(window) eq $w && [$w cget -state] ne "disabled"} {
  377.     # Only invoke the command if it wasn't already invoked by the
  378.     # auto-repeater functionality
  379.     if { $Priv(repeated) == 0 } {
  380. uplevel #0 [list $w invoke]
  381.     }
  382. }
  383.     }
  384. }
  385. }
  386. if {[tk windowingsystem] eq "classic" || [tk windowingsystem] eq "aqua"} {
  387. ####################
  388. # Mac implementation
  389. ####################
  390. # ::tk::ButtonEnter --
  391. # The procedure below is invoked when the mouse pointer enters a
  392. # button widget.  It records the button we're in and changes the
  393. # state of the button to active unless the button is disabled.
  394. #
  395. # Arguments:
  396. # w - The name of the widget.
  397. proc ::tk::ButtonEnter {w} {
  398.     variable ::tk::Priv
  399.     if {[$w cget -state] ne "disabled"} {
  400. # If there's an -overrelief value, set the relief to that.
  401. if {$Priv(buttonWindow) eq $w} {
  402.     $w configure -state active
  403. } elseif {[set over [$w cget -overrelief]] ne ""} {
  404.     set Priv($w,relief)  [$w cget -relief]
  405.     set Priv($w,prelief) $over
  406.     $w configure -relief $over
  407. }
  408.     }
  409.     set Priv(window) $w
  410. }
  411. # ::tk::ButtonLeave --
  412. # The procedure below is invoked when the mouse pointer leaves a
  413. # button widget.  It changes the state of the button back to
  414. # inactive.  If we're leaving the button window with a mouse button
  415. # pressed (Priv(buttonWindow) == $w), restore the relief of the
  416. # button too.
  417. #
  418. # Arguments:
  419. # w - The name of the widget.
  420. proc ::tk::ButtonLeave w {
  421.     variable ::tk::Priv
  422.     if {$w eq $Priv(buttonWindow)} {
  423. $w configure -state normal
  424.     }
  425.     # Restore the original button relief if it was changed by Tk.
  426.     # That is signaled by the existence of Priv($w,prelief).
  427.     if {[info exists Priv($w,relief)]} {
  428. if {[info exists Priv($w,prelief)] && 
  429. $Priv($w,prelief) eq [$w cget -relief]} {
  430.     $w configure -relief $Priv($w,relief)
  431. }
  432. unset -nocomplain Priv($w,relief) Priv($w,prelief)
  433.     }
  434.     set Priv(window) ""
  435. }
  436. # ::tk::ButtonDown --
  437. # The procedure below is invoked when the mouse button is pressed in
  438. # a button widget.  It records the fact that the mouse is in the button,
  439. # saves the button's relief so it can be restored later, and changes
  440. # the relief to sunken.
  441. #
  442. # Arguments:
  443. # w - The name of the widget.
  444. proc ::tk::ButtonDown w {
  445.     variable ::tk::Priv
  446.     if {[$w cget -state] ne "disabled"} {
  447. set Priv(buttonWindow) $w
  448. $w configure -state active
  449. # If this button has a repeatdelay set up, get it going with an after
  450. after cancel $Priv(afterId)
  451. set Priv(repeated) 0
  452. if { ![catch {$w cget -repeatdelay} delay] } {
  453.     if {$delay > 0} {
  454. set Priv(afterId) [after $delay [list tk::ButtonAutoInvoke $w]]
  455.     }
  456. }
  457.     }
  458. }
  459. # ::tk::ButtonUp --
  460. # The procedure below is invoked when the mouse button is released
  461. # in a button widget.  It restores the button's relief and invokes
  462. # the command as long as the mouse hasn't left the button.
  463. #
  464. # Arguments:
  465. # w - The name of the widget.
  466. proc ::tk::ButtonUp w {
  467.     variable ::tk::Priv
  468.     if {$Priv(buttonWindow) eq $w} {
  469. set Priv(buttonWindow) ""
  470. $w configure -state normal
  471. # Restore the button's relief if it was cached.
  472. if {[info exists Priv($w,relief)]} {
  473.     if {[info exists Priv($w,prelief)] && 
  474.     $Priv($w,prelief) eq [$w cget -relief]} {
  475. $w configure -relief $Priv($w,relief)
  476.     }
  477.     unset -nocomplain Priv($w,relief) Priv($w,prelief)
  478. }
  479. # Clean up the after event from the auto-repeater
  480. after cancel $Priv(afterId)
  481. if {$Priv(window) eq $w && [$w cget -state] ne "disabled"} {
  482.     # Only invoke the command if it wasn't already invoked by the
  483.     # auto-repeater functionality
  484.     if { $Priv(repeated) == 0 } {
  485. uplevel #0 [list $w invoke]
  486.     }
  487. }
  488.     }
  489. }
  490. }
  491. ##################
  492. # Shared routines
  493. ##################
  494. # ::tk::ButtonInvoke --
  495. # The procedure below is called when a button is invoked through
  496. # the keyboard.  It simulate a press of the button via the mouse.
  497. #
  498. # Arguments:
  499. # w - The name of the widget.
  500. proc ::tk::ButtonInvoke w {
  501.     if {[$w cget -state] ne "disabled"} {
  502. set oldRelief [$w cget -relief]
  503. set oldState [$w cget -state]
  504. $w configure -state active -relief sunken
  505. update idletasks
  506. after 100
  507. $w configure -state $oldState -relief $oldRelief
  508. uplevel #0 [list $w invoke]
  509.     }
  510. }
  511. # ::tk::ButtonAutoInvoke --
  512. #
  513. # Invoke an auto-repeating button, and set it up to continue to repeat.
  514. #
  515. # Arguments:
  516. # w button to invoke.
  517. #
  518. # Results:
  519. # None.
  520. #
  521. # Side effects:
  522. # May create an after event to call ::tk::ButtonAutoInvoke.
  523. proc ::tk::ButtonAutoInvoke {w} {
  524.     variable ::tk::Priv
  525.     after cancel $Priv(afterId)
  526.     set delay [$w cget -repeatinterval]
  527.     if {$Priv(window) eq $w} {
  528. incr Priv(repeated)
  529. uplevel #0 [list $w invoke]
  530.     }
  531.     if {$delay > 0} {
  532. set Priv(afterId) [after $delay [list tk::ButtonAutoInvoke $w]]
  533.     }
  534. }
  535. # ::tk::CheckRadioInvoke --
  536. # The procedure below is invoked when the mouse button is pressed in
  537. # a checkbutton or radiobutton widget, or when the widget is invoked
  538. # through the keyboard.  It invokes the widget if it
  539. # isn't disabled.
  540. #
  541. # Arguments:
  542. # w - The name of the widget.
  543. # cmd - The subcommand to invoke (one of invoke, select, or deselect).
  544. proc ::tk::CheckRadioInvoke {w {cmd invoke}} {
  545.     if {[$w cget -state] ne "disabled"} {
  546. uplevel #0 [list $w $cmd]
  547.     }
  548. }