scale.tcl 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. # scale.tcl --
  2. #
  3. # This file defines the default bindings for Tk scale widgets and provides
  4. # procedures that help in implementing the bindings.
  5. #
  6. # Copyright (c) 1994 The Regents of the University of California.
  7. # Copyright (c) 1994-1995 Sun Microsystems, Inc.
  8. #
  9. # See the file "license.terms" for information on usage and redistribution
  10. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11. #
  12. #-------------------------------------------------------------------------
  13. # The code below creates the default class bindings for entries.
  14. #-------------------------------------------------------------------------
  15. # Standard Motif bindings:
  16. bind Scale <Enter> {
  17. if {$tk_strictMotif} {
  18. set tk::Priv(activeBg) [%W cget -activebackground]
  19. %W configure -activebackground [%W cget -background]
  20. }
  21. tk::ScaleActivate %W %x %y
  22. }
  23. bind Scale <Motion> {
  24. tk::ScaleActivate %W %x %y
  25. }
  26. bind Scale <Leave> {
  27. if {$tk_strictMotif} {
  28. %W configure -activebackground $tk::Priv(activeBg)
  29. }
  30. if {[%W cget -state] eq "active"} {
  31. %W configure -state normal
  32. }
  33. }
  34. bind Scale <1> {
  35. tk::ScaleButtonDown %W %x %y
  36. }
  37. bind Scale <B1-Motion> {
  38. tk::ScaleDrag %W %x %y
  39. }
  40. bind Scale <B1-Leave> { }
  41. bind Scale <B1-Enter> { }
  42. bind Scale <ButtonRelease-1> {
  43. tk::CancelRepeat
  44. tk::ScaleEndDrag %W
  45. tk::ScaleActivate %W %x %y
  46. }
  47. bind Scale <2> {
  48. tk::ScaleButton2Down %W %x %y
  49. }
  50. bind Scale <B2-Motion> {
  51. tk::ScaleDrag %W %x %y
  52. }
  53. bind Scale <B2-Leave> { }
  54. bind Scale <B2-Enter> { }
  55. bind Scale <ButtonRelease-2> {
  56. tk::CancelRepeat
  57. tk::ScaleEndDrag %W
  58. tk::ScaleActivate %W %x %y
  59. }
  60. if {[tk windowingsystem] eq "win32"} {
  61. # On Windows do the same with button 3, as that is the right mouse button
  62. bind Scale <3> [bind Scale <2>]
  63. bind Scale <B3-Motion> [bind Scale <B2-Motion>]
  64. bind Scale <B3-Leave> [bind Scale <B2-Leave>]
  65. bind Scale <B3-Enter> [bind Scale <B2-Enter>]
  66. bind Scale <ButtonRelease-3> [bind Scale <ButtonRelease-2>]
  67. }
  68. bind Scale <Control-1> {
  69. tk::ScaleControlPress %W %x %y
  70. }
  71. bind Scale <<PrevLine>> {
  72. tk::ScaleIncrement %W up little noRepeat
  73. }
  74. bind Scale <<NextLine>> {
  75. tk::ScaleIncrement %W down little noRepeat
  76. }
  77. bind Scale <<PrevChar>> {
  78. tk::ScaleIncrement %W up little noRepeat
  79. }
  80. bind Scale <<NextChar>> {
  81. tk::ScaleIncrement %W down little noRepeat
  82. }
  83. bind Scale <<PrevPara>> {
  84. tk::ScaleIncrement %W up big noRepeat
  85. }
  86. bind Scale <<NextPara>> {
  87. tk::ScaleIncrement %W down big noRepeat
  88. }
  89. bind Scale <<PrevWord>> {
  90. tk::ScaleIncrement %W up big noRepeat
  91. }
  92. bind Scale <<NextWord>> {
  93. tk::ScaleIncrement %W down big noRepeat
  94. }
  95. bind Scale <<LineStart>> {
  96. %W set [%W cget -from]
  97. }
  98. bind Scale <<LineEnd>> {
  99. %W set [%W cget -to]
  100. }
  101. # ::tk::ScaleActivate --
  102. # This procedure is invoked to check a given x-y position in the
  103. # scale and activate the slider if the x-y position falls within
  104. # the slider.
  105. #
  106. # Arguments:
  107. # w - The scale widget.
  108. # x, y - Mouse coordinates.
  109. proc ::tk::ScaleActivate {w x y} {
  110. if {[$w cget -state] eq "disabled"} {
  111. return
  112. }
  113. if {[$w identify $x $y] eq "slider"} {
  114. set state active
  115. } else {
  116. set state normal
  117. }
  118. if {[$w cget -state] ne $state} {
  119. $w configure -state $state
  120. }
  121. }
  122. # ::tk::ScaleButtonDown --
  123. # This procedure is invoked when a button is pressed in a scale. It
  124. # takes different actions depending on where the button was pressed.
  125. #
  126. # Arguments:
  127. # w - The scale widget.
  128. # x, y - Mouse coordinates of button press.
  129. proc ::tk::ScaleButtonDown {w x y} {
  130. variable ::tk::Priv
  131. set Priv(dragging) 0
  132. set el [$w identify $x $y]
  133. # save the relief
  134. set Priv($w,relief) [$w cget -sliderrelief]
  135. if {$el eq "trough1"} {
  136. ScaleIncrement $w up little initial
  137. } elseif {$el eq "trough2"} {
  138. ScaleIncrement $w down little initial
  139. } elseif {$el eq "slider"} {
  140. set Priv(dragging) 1
  141. set Priv(initValue) [$w get]
  142. set coords [$w coords]
  143. set Priv(deltaX) [expr {$x - [lindex $coords 0]}]
  144. set Priv(deltaY) [expr {$y - [lindex $coords 1]}]
  145. switch -exact -- $Priv($w,relief) {
  146. "raised" { $w configure -sliderrelief sunken }
  147. "ridge" { $w configure -sliderrelief groove }
  148. }
  149. }
  150. }
  151. # ::tk::ScaleDrag --
  152. # This procedure is called when the mouse is dragged with
  153. # mouse button 1 down. If the drag started inside the slider
  154. # (i.e. the scale is active) then the scale's value is adjusted
  155. # to reflect the mouse's position.
  156. #
  157. # Arguments:
  158. # w - The scale widget.
  159. # x, y - Mouse coordinates.
  160. proc ::tk::ScaleDrag {w x y} {
  161. variable ::tk::Priv
  162. if {!$Priv(dragging)} {
  163. return
  164. }
  165. $w set [$w get [expr {$x-$Priv(deltaX)}] [expr {$y-$Priv(deltaY)}]]
  166. }
  167. # ::tk::ScaleEndDrag --
  168. # This procedure is called to end an interactive drag of the
  169. # slider. It just marks the drag as over.
  170. #
  171. # Arguments:
  172. # w - The scale widget.
  173. proc ::tk::ScaleEndDrag {w} {
  174. variable ::tk::Priv
  175. set Priv(dragging) 0
  176. if {[info exists Priv($w,relief)]} {
  177. $w configure -sliderrelief $Priv($w,relief)
  178. unset Priv($w,relief)
  179. }
  180. }
  181. # ::tk::ScaleIncrement --
  182. # This procedure is invoked to increment the value of a scale and
  183. # to set up auto-repeating of the action if that is desired. The
  184. # way the value is incremented depends on the "dir" and "big"
  185. # arguments.
  186. #
  187. # Arguments:
  188. # w - The scale widget.
  189. # dir - "up" means move value towards -from, "down" means
  190. # move towards -to.
  191. # big - Size of increments: "big" or "little".
  192. # repeat - Whether and how to auto-repeat the action: "noRepeat"
  193. # means don't auto-repeat, "initial" means this is the
  194. # first action in an auto-repeat sequence, and "again"
  195. # means this is the second repetition or later.
  196. proc ::tk::ScaleIncrement {w dir big repeat} {
  197. variable ::tk::Priv
  198. if {![winfo exists $w]} return
  199. if {$big eq "big"} {
  200. set inc [$w cget -bigincrement]
  201. if {$inc == 0} {
  202. set inc [expr {abs([$w cget -to] - [$w cget -from])/10.0}]
  203. }
  204. if {$inc < [$w cget -resolution]} {
  205. set inc [$w cget -resolution]
  206. }
  207. } else {
  208. set inc [$w cget -resolution]
  209. }
  210. if {([$w cget -from] > [$w cget -to]) ^ ($dir eq "up")} {
  211. if {$inc > 0} {
  212. set inc [expr {-$inc}]
  213. }
  214. } else {
  215. if {$inc < 0} {
  216. set inc [expr {-$inc}]
  217. }
  218. }
  219. $w set [expr {[$w get] + $inc}]
  220. if {$repeat eq "again"} {
  221. set Priv(afterId) [after [$w cget -repeatinterval] \
  222. [list tk::ScaleIncrement $w $dir $big again]]
  223. } elseif {$repeat eq "initial"} {
  224. set delay [$w cget -repeatdelay]
  225. if {$delay > 0} {
  226. set Priv(afterId) [after $delay \
  227. [list tk::ScaleIncrement $w $dir $big again]]
  228. }
  229. }
  230. }
  231. # ::tk::ScaleControlPress --
  232. # This procedure handles button presses that are made with the Control
  233. # key down. Depending on the mouse position, it adjusts the scale
  234. # value to one end of the range or the other.
  235. #
  236. # Arguments:
  237. # w - The scale widget.
  238. # x, y - Mouse coordinates where the button was pressed.
  239. proc ::tk::ScaleControlPress {w x y} {
  240. set el [$w identify $x $y]
  241. if {$el eq "trough1"} {
  242. $w set [$w cget -from]
  243. } elseif {$el eq "trough2"} {
  244. $w set [$w cget -to]
  245. }
  246. }
  247. # ::tk::ScaleButton2Down
  248. # This procedure is invoked when button 2 is pressed over a scale.
  249. # It sets the value to correspond to the mouse position and starts
  250. # a slider drag.
  251. #
  252. # Arguments:
  253. # w - The scrollbar widget.
  254. # x, y - Mouse coordinates within the widget.
  255. proc ::tk::ScaleButton2Down {w x y} {
  256. variable ::tk::Priv
  257. if {[$w cget -state] eq "disabled"} {
  258. return
  259. }
  260. $w configure -state active
  261. $w set [$w get $x $y]
  262. set Priv(dragging) 1
  263. set Priv(initValue) [$w get]
  264. set Priv($w,relief) [$w cget -sliderrelief]
  265. set coords "$x $y"
  266. set Priv(deltaX) 0
  267. set Priv(deltaY) 0
  268. }