entry.tcl 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. # entry.tcl --
  2. #
  3. # This file defines the default bindings for Tk entry widgets and provides
  4. # procedures that help in implementing those bindings.
  5. #
  6. # Copyright © 1992-1994 The Regents of the University of California.
  7. # Copyright © 1994-1997 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. # Elements of tk::Priv that are used in this file:
  14. #
  15. # afterId - If non-null, it means that auto-scanning is underway
  16. # and it gives the "after" id for the next auto-scan
  17. # command to be executed.
  18. # mouseMoved - Non-zero means the mouse has moved a significant
  19. # amount since the button went down (so, for example,
  20. # start dragging out a selection).
  21. # pressX - X-coordinate at which the mouse button was pressed.
  22. # selectMode - The style of selection currently underway:
  23. # char, word, or line.
  24. # x, y - Last known mouse coordinates for scanning
  25. # and auto-scanning.
  26. # data - Used for Cut and Copy
  27. #-------------------------------------------------------------------------
  28. #-------------------------------------------------------------------------
  29. # The code below creates the default class bindings for entries.
  30. #-------------------------------------------------------------------------
  31. bind Entry <<Cut>> {
  32. if {![catch {tk::EntryGetSelection %W} tk::Priv(data)]} {
  33. clipboard clear -displayof %W
  34. clipboard append -displayof %W $tk::Priv(data)
  35. %W delete sel.first sel.last
  36. unset tk::Priv(data)
  37. }
  38. }
  39. bind Entry <<Copy>> {
  40. if {![catch {tk::EntryGetSelection %W} tk::Priv(data)]} {
  41. clipboard clear -displayof %W
  42. clipboard append -displayof %W $tk::Priv(data)
  43. unset tk::Priv(data)
  44. }
  45. }
  46. bind Entry <<Paste>> {
  47. catch {
  48. if {[tk windowingsystem] ne "x11"} {
  49. catch {
  50. %W delete sel.first sel.last
  51. }
  52. }
  53. %W insert insert [::tk::GetSelection %W CLIPBOARD]
  54. tk::EntrySeeInsert %W
  55. }
  56. }
  57. bind Entry <<Clear>> {
  58. # ignore if there is no selection
  59. catch {%W delete sel.first sel.last}
  60. }
  61. bind Entry <<PasteSelection>> {
  62. if {$tk_strictMotif || ![info exists tk::Priv(mouseMoved)]
  63. || !$tk::Priv(mouseMoved)} {
  64. tk::EntryPaste %W %x
  65. }
  66. }
  67. bind Entry <<TraverseIn>> {
  68. %W selection range 0 end
  69. %W icursor end
  70. }
  71. # Standard Motif bindings:
  72. bind Entry <Button-1> {
  73. tk::EntryButton1 %W %x
  74. %W selection clear
  75. }
  76. bind Entry <B1-Motion> {
  77. set tk::Priv(x) %x
  78. tk::EntryMouseSelect %W %x
  79. }
  80. bind Entry <Double-Button-1> {
  81. set tk::Priv(selectMode) word
  82. tk::EntryMouseSelect %W %x
  83. catch {%W icursor sel.last}
  84. }
  85. bind Entry <Triple-Button-1> {
  86. set tk::Priv(selectMode) line
  87. tk::EntryMouseSelect %W %x
  88. catch {%W icursor sel.last}
  89. }
  90. bind Entry <Shift-Button-1> {
  91. set tk::Priv(selectMode) char
  92. %W selection adjust @%x
  93. }
  94. bind Entry <Double-Shift-Button-1> {
  95. set tk::Priv(selectMode) word
  96. tk::EntryMouseSelect %W %x
  97. }
  98. bind Entry <Triple-Shift-Button-1> {
  99. set tk::Priv(selectMode) line
  100. tk::EntryMouseSelect %W %x
  101. }
  102. bind Entry <B1-Leave> {
  103. set tk::Priv(x) %x
  104. tk::EntryAutoScan %W
  105. }
  106. bind Entry <B1-Enter> {
  107. tk::CancelRepeat
  108. }
  109. bind Entry <ButtonRelease-1> {
  110. tk::CancelRepeat
  111. }
  112. bind Entry <Control-Button-1> {
  113. %W icursor @%x
  114. }
  115. bind Entry <<PrevChar>> {
  116. tk::EntrySetCursor %W [tk::EntryPreviousChar %W insert]
  117. }
  118. bind Entry <<NextChar>> {
  119. tk::EntrySetCursor %W [tk::EntryNextChar %W insert]
  120. }
  121. bind Entry <<SelectPrevChar>> {
  122. tk::EntryKeySelect %W [tk::EntryPreviousChar %W insert]
  123. tk::EntrySeeInsert %W
  124. }
  125. bind Entry <<SelectNextChar>> {
  126. tk::EntryKeySelect %W [tk::EntryNextChar %W insert]
  127. tk::EntrySeeInsert %W
  128. }
  129. bind Entry <<PrevWord>> {
  130. tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
  131. }
  132. bind Entry <<NextWord>> {
  133. tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
  134. }
  135. bind Entry <<SelectPrevWord>> {
  136. tk::EntryKeySelect %W [tk::EntryPreviousWord %W insert]
  137. tk::EntrySeeInsert %W
  138. }
  139. bind Entry <<SelectNextWord>> {
  140. tk::EntryKeySelect %W [tk::EntrySelectNextWord %W insert]
  141. tk::EntrySeeInsert %W
  142. }
  143. bind Entry <<LineStart>> {
  144. tk::EntrySetCursor %W 0
  145. }
  146. bind Entry <<SelectLineStart>> {
  147. tk::EntryKeySelect %W 0
  148. tk::EntrySeeInsert %W
  149. }
  150. bind Entry <<LineEnd>> {
  151. tk::EntrySetCursor %W end
  152. }
  153. bind Entry <<SelectLineEnd>> {
  154. tk::EntryKeySelect %W end
  155. tk::EntrySeeInsert %W
  156. }
  157. bind Entry <Delete> {
  158. if {[%W selection present]} {
  159. %W delete sel.first sel.last
  160. } else {
  161. %W delete [tk::startOfCluster [%W get] [%W index insert]] \
  162. [tk::endOfCluster [%W get] [%W index insert]]
  163. }
  164. }
  165. bind Entry <BackSpace> {
  166. tk::EntryBackspace %W
  167. }
  168. bind Entry <Control-space> {
  169. %W selection from insert
  170. }
  171. bind Entry <Select> {
  172. %W selection from insert
  173. }
  174. bind Entry <Control-Shift-space> {
  175. %W selection adjust insert
  176. }
  177. bind Entry <Shift-Select> {
  178. %W selection adjust insert
  179. }
  180. bind Entry <<SelectAll>> {
  181. %W selection range 0 end
  182. }
  183. bind Entry <<SelectNone>> {
  184. %W selection clear
  185. }
  186. bind Entry <Key> {
  187. tk::CancelRepeat
  188. tk::EntryInsert %W %A
  189. }
  190. # Ignore all Alt, Meta, Control, Command, and Fn keypresses unless explicitly bound.
  191. # Otherwise, if a widget binding for one of these is defined, the
  192. # <Key> class binding will also fire and insert the character,
  193. # which is wrong. Ditto for Escape, Return, and Tab.
  194. bind Entry <Alt-Key> {# nothing}
  195. bind Entry <Meta-Key> {# nothing}
  196. bind Entry <Control-Key> {# nothing}
  197. bind Entry <Escape> {# nothing}
  198. bind Entry <Return> {# nothing}
  199. bind Entry <KP_Enter> {# nothing}
  200. bind Entry <Tab> {# nothing}
  201. bind Entry <Prior> {# nothing}
  202. bind Entry <Next> {# nothing}
  203. bind Entry <Command-Key> {# nothing}
  204. bind Entry <Fn-Key> {# nothing}
  205. # Tk-on-Cocoa generates characters for these two keys. [Bug 2971663]
  206. bind Entry <<NextLine>> {# nothing}
  207. bind Entry <<PrevLine>> {# nothing}
  208. # On Windows, paste is done using Shift-Insert. Shift-Insert already
  209. # generates the <<Paste>> event, so we don't need to do anything here.
  210. if {[tk windowingsystem] ne "win32"} {
  211. bind Entry <Insert> {
  212. catch {tk::EntryInsert %W [::tk::GetSelection %W PRIMARY]}
  213. }
  214. }
  215. # Additional emacs-like bindings:
  216. bind Entry <Control-d> {
  217. if {!$tk_strictMotif} {
  218. %W delete insert
  219. }
  220. }
  221. bind Entry <Control-h> {
  222. if {!$tk_strictMotif} {
  223. tk::EntryBackspace %W
  224. }
  225. }
  226. bind Entry <Control-k> {
  227. if {!$tk_strictMotif} {
  228. %W delete insert end
  229. }
  230. }
  231. bind Entry <Control-t> {
  232. if {!$tk_strictMotif} {
  233. tk::EntryTranspose %W
  234. }
  235. }
  236. bind Entry <Meta-b> {
  237. if {!$tk_strictMotif} {
  238. tk::EntrySetCursor %W [tk::EntryPreviousWord %W insert]
  239. }
  240. }
  241. bind Entry <Meta-d> {
  242. if {!$tk_strictMotif} {
  243. %W delete insert [tk::EntryNextWord %W insert]
  244. }
  245. }
  246. bind Entry <Meta-f> {
  247. if {!$tk_strictMotif} {
  248. tk::EntrySetCursor %W [tk::EntryNextWord %W insert]
  249. }
  250. }
  251. bind Entry <Meta-BackSpace> {
  252. if {!$tk_strictMotif} {
  253. %W delete [tk::EntryPreviousWord %W insert] insert
  254. }
  255. }
  256. bind Entry <Meta-Delete> {
  257. if {!$tk_strictMotif} {
  258. %W delete [tk::EntryPreviousWord %W insert] insert
  259. }
  260. }
  261. # Bindings for IME text input and accents.
  262. bind Entry <<TkStartIMEMarkedText>> {
  263. dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
  264. }
  265. bind Entry <<TkEndIMEMarkedText>> {
  266. ::tk::EntryEndIMEMarkedText %W
  267. }
  268. bind Entry <<TkClearIMEMarkedText>> {
  269. %W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
  270. }
  271. bind Entry <<TkAccentBackspace>> {
  272. tk::EntryBackspace %W
  273. }
  274. # ::tk::EntryEndIMEMarkedText --
  275. # Handles input method text marking in an entry
  276. #
  277. # Arguments:
  278. # w - The entry window.
  279. proc ::tk::EntryEndIMEMarkedText {w} {
  280. variable Priv
  281. if {[catch {
  282. set mark [dict get $Priv(IMETextMark) $w]
  283. }]} {
  284. bell
  285. return
  286. }
  287. $w selection range $mark insert
  288. }
  289. # A few additional bindings of my own.
  290. bind Entry <Button-2> {
  291. if {!$tk_strictMotif} {
  292. ::tk::EntryScanMark %W %x
  293. }
  294. }
  295. bind Entry <B2-Motion> {
  296. if {!$tk_strictMotif} {
  297. ::tk::EntryScanDrag %W %x
  298. }
  299. }
  300. # ::tk::EntryClosestGap --
  301. # Given x and y coordinates, this procedure finds the closest boundary
  302. # between characters to the given coordinates and returns the index
  303. # of the character just after the boundary.
  304. #
  305. # Arguments:
  306. # w - The entry window.
  307. # x - X-coordinate within the window.
  308. proc ::tk::EntryClosestGap {w x} {
  309. set pos [$w index @$x]
  310. set bbox [$w bbox $pos]
  311. if {($x - [lindex $bbox 0]) < ([lindex $bbox 2]/2)} {
  312. return $pos
  313. }
  314. incr pos
  315. }
  316. # ::tk::EntryButton1 --
  317. # This procedure is invoked to handle button-1 presses in entry
  318. # widgets. It moves the insertion cursor, sets the selection anchor,
  319. # and claims the input focus.
  320. #
  321. # Arguments:
  322. # w - The entry window in which the button was pressed.
  323. # x - The x-coordinate of the button press.
  324. proc ::tk::EntryButton1 {w x} {
  325. variable ::tk::Priv
  326. set Priv(selectMode) char
  327. set Priv(mouseMoved) 0
  328. set Priv(pressX) $x
  329. $w icursor [EntryClosestGap $w $x]
  330. $w selection from insert
  331. if {"disabled" ne [$w cget -state]} {
  332. focus $w
  333. }
  334. }
  335. # ::tk::EntryMouseSelect --
  336. # This procedure is invoked when dragging out a selection with
  337. # the mouse. Depending on the selection mode (character, word,
  338. # line) it selects in different-sized units. This procedure
  339. # ignores mouse motions initially until the mouse has moved from
  340. # one character to another or until there have been multiple clicks.
  341. #
  342. # Arguments:
  343. # w - The entry window in which the button was pressed.
  344. # x - The x-coordinate of the mouse.
  345. proc ::tk::EntryMouseSelect {w x} {
  346. variable ::tk::Priv
  347. set cur [EntryClosestGap $w $x]
  348. set anchor [$w index anchor]
  349. if {($cur != $anchor) || (abs($Priv(pressX) - $x) >= 3)} {
  350. set Priv(mouseMoved) 1
  351. }
  352. switch $Priv(selectMode) {
  353. char {
  354. if {$Priv(mouseMoved)} {
  355. if {$cur < $anchor} {
  356. $w selection range $cur $anchor
  357. } elseif {$cur > $anchor} {
  358. $w selection range $anchor $cur
  359. } else {
  360. $w selection clear
  361. }
  362. }
  363. }
  364. word {
  365. if {$cur < $anchor} {
  366. set before [tk::wordBreakBefore [$w get] $cur]
  367. set after [tk::wordBreakAfter [$w get] $anchor-1]
  368. } elseif {$cur > $anchor} {
  369. set before [tk::wordBreakBefore [$w get] $anchor]
  370. set after [tk::wordBreakAfter [$w get] $cur-1]
  371. } else {
  372. if {[$w index @$Priv(pressX)] < $anchor} {
  373. incr anchor -1
  374. }
  375. set before [tk::wordBreakBefore [$w get] $anchor]
  376. set after [tk::wordBreakAfter [$w get] $anchor]
  377. }
  378. if {$before < 0} {
  379. set before 0
  380. }
  381. if {$after < 0} {
  382. set after end
  383. }
  384. $w selection range $before $after
  385. }
  386. line {
  387. $w selection range 0 end
  388. }
  389. }
  390. if {$Priv(mouseMoved)} {
  391. $w icursor $cur
  392. }
  393. update idletasks
  394. }
  395. # ::tk::EntryPaste --
  396. # This procedure sets the insertion cursor to the current mouse position,
  397. # pastes the selection there, and sets the focus to the window.
  398. #
  399. # Arguments:
  400. # w - The entry window.
  401. # x - X position of the mouse.
  402. proc ::tk::EntryPaste {w x} {
  403. $w icursor [EntryClosestGap $w $x]
  404. catch {$w insert insert [::tk::GetSelection $w PRIMARY]}
  405. if {"disabled" ne [$w cget -state]} {
  406. focus $w
  407. }
  408. }
  409. # ::tk::EntryAutoScan --
  410. # This procedure is invoked when the mouse leaves an entry window
  411. # with button 1 down. It scrolls the window left or right,
  412. # depending on where the mouse is, and reschedules itself as an
  413. # "after" command so that the window continues to scroll until the
  414. # mouse moves back into the window or the mouse button is released.
  415. #
  416. # Arguments:
  417. # w - The entry window.
  418. proc ::tk::EntryAutoScan {w} {
  419. variable ::tk::Priv
  420. set x $Priv(x)
  421. if {![winfo exists $w]} {
  422. return
  423. }
  424. if {$x >= [winfo width $w]} {
  425. $w xview scroll 2 units
  426. EntryMouseSelect $w $x
  427. } elseif {$x < 0} {
  428. $w xview scroll -2 units
  429. EntryMouseSelect $w $x
  430. }
  431. set Priv(afterId) [after 50 [list tk::EntryAutoScan $w]]
  432. }
  433. # ::tk::EntryKeySelect --
  434. # This procedure is invoked when stroking out selections using the
  435. # keyboard. It moves the cursor to a new position, then extends
  436. # the selection to that position.
  437. #
  438. # Arguments:
  439. # w - The entry window.
  440. # new - A new position for the insertion cursor (the cursor hasn't
  441. # actually been moved to this position yet).
  442. proc ::tk::EntryKeySelect {w new} {
  443. if {![$w selection present]} {
  444. $w selection from insert
  445. $w selection to $new
  446. } else {
  447. $w selection adjust $new
  448. }
  449. $w icursor $new
  450. }
  451. # ::tk::EntryInsert --
  452. # Insert a string into an entry at the point of the insertion cursor.
  453. # If there is a selection in the entry, and it covers the point of the
  454. # insertion cursor, then delete the selection before inserting.
  455. #
  456. # Arguments:
  457. # w - The entry window in which to insert the string
  458. # s - The string to insert (usually just a single character)
  459. proc ::tk::EntryInsert {w s} {
  460. if {$s eq ""} {
  461. return
  462. }
  463. catch {
  464. set insert [$w index insert]
  465. if {([$w index sel.first] <= $insert)
  466. && ([$w index sel.last] >= $insert)} {
  467. $w delete sel.first sel.last
  468. }
  469. }
  470. $w insert insert $s
  471. EntrySeeInsert $w
  472. }
  473. # ::tk::EntryBackspace --
  474. # Backspace over the character just before the insertion cursor.
  475. # If backspacing would move the cursor off the left edge of the
  476. # window, reposition the cursor at about the middle of the window.
  477. #
  478. # Arguments:
  479. # w - The entry window in which to backspace.
  480. proc ::tk::EntryBackspace w {
  481. if {[$w selection present]} {
  482. $w delete sel.first sel.last
  483. } else {
  484. set x [expr {[$w index insert] - 1}]
  485. if {$x >= 0} {
  486. $w delete [tk::startOfCluster [$w get] $x] \
  487. [tk::endOfCluster [$w get] $x]
  488. }
  489. if {[$w index @0] >= [$w index insert]} {
  490. set range [$w xview]
  491. set left [lindex $range 0]
  492. set right [lindex $range 1]
  493. $w xview moveto [expr {$left - ($right - $left)/2.0}]
  494. }
  495. }
  496. }
  497. # ::tk::EntrySeeInsert --
  498. # Make sure that the insertion cursor is visible in the entry window.
  499. # If not, adjust the view so that it is.
  500. #
  501. # Arguments:
  502. # w - The entry window.
  503. proc ::tk::EntrySeeInsert w {
  504. set c [$w index insert]
  505. if {($c < [$w index @0]) || ($c > [$w index @[winfo width $w]])} {
  506. $w xview $c
  507. }
  508. }
  509. # ::tk::EntrySetCursor -
  510. # Move the insertion cursor to a given position in an entry. Also
  511. # clears the selection, if there is one in the entry, and makes sure
  512. # that the insertion cursor is visible.
  513. #
  514. # Arguments:
  515. # w - The entry window.
  516. # pos - The desired new position for the cursor in the window.
  517. proc ::tk::EntrySetCursor {w pos} {
  518. $w icursor $pos
  519. $w selection clear
  520. EntrySeeInsert $w
  521. }
  522. # ::tk::EntryTranspose -
  523. # This procedure implements the "transpose" function for entry widgets.
  524. # It tranposes the characters on either side of the insertion cursor,
  525. # unless the cursor is at the end of the line. In this case it
  526. # transposes the two characters to the left of the cursor. In either
  527. # case, the cursor ends up to the right of the transposed characters.
  528. #
  529. # Arguments:
  530. # w - The entry window.
  531. proc ::tk::EntryTranspose w {
  532. set i [$w index insert]
  533. if {$i < [$w index end]} {
  534. incr i
  535. }
  536. if {$i < 2} {
  537. return
  538. }
  539. set first $i-2
  540. set data [$w get]
  541. set new [string index $data $i-1][string index $data $first]
  542. $w delete $first $i
  543. $w insert insert $new
  544. EntrySeeInsert $w
  545. }
  546. # ::tk::EntryNextWord --
  547. # Returns the index of the next start-of-word position after the next
  548. # end-of-word position after a given position in the text.
  549. #
  550. # Arguments:
  551. # w - The entry window in which the cursor is to move.
  552. # start - Position at which to start search.
  553. proc ::tk::EntryNextWord {w start} {
  554. # the check on [winfo class] is because the spinbox also uses this proc
  555. if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
  556. return end
  557. }
  558. set pos [tk::endOfWord [$w get] [$w index $start]]
  559. if {$pos >= 0} {
  560. set pos [tk::startOfNextWord [$w get] $pos]
  561. }
  562. if {$pos < 0} {
  563. return end
  564. }
  565. return $pos
  566. }
  567. # ::tk::EntrySelectNextWord --
  568. # Returns the index of the next end-of-word position after a given
  569. # position in the text.
  570. #
  571. # Arguments:
  572. # w - The entry window in which the cursor is to move.
  573. # start - Position at which to start search.
  574. proc ::tk::EntrySelectNextWord {w start} {
  575. # the check on [winfo class] is because the spinbox also uses this proc
  576. if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
  577. return end
  578. }
  579. set pos [tk::endOfWord [$w get] [$w index $start]]
  580. if {$pos < 0} {
  581. return end
  582. }
  583. return $pos
  584. }
  585. # ::tk::EntryPreviousWord --
  586. #
  587. # Returns the index of the previous word position before a given
  588. # position in the entry.
  589. #
  590. # Arguments:
  591. # w - The entry window in which the cursor is to move.
  592. # start - Position at which to start search.
  593. proc ::tk::EntryPreviousWord {w start} {
  594. # the check on [winfo class] is because the spinbox also uses this proc
  595. if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
  596. return 0
  597. }
  598. set pos [tk::startOfPreviousWord [$w get] [$w index $start]]
  599. if {$pos < 0} {
  600. return 0
  601. }
  602. return $pos
  603. }
  604. proc ::tk::EntryNextChar {w start} {
  605. set pos [tk::endOfCluster [$w get] [$w index $start]]
  606. if {$pos < 0} {
  607. return end
  608. }
  609. return $pos
  610. }
  611. proc ::tk::EntryPreviousChar {w start} {
  612. set pos [tk::startOfCluster [$w get] [expr {[$w index $start]-1}]]
  613. if {$pos < 0} {
  614. return 0
  615. }
  616. return $pos
  617. }
  618. # ::tk::EntryScanMark --
  619. #
  620. # Marks the start of a possible scan drag operation
  621. #
  622. # Arguments:
  623. # w - The entry window from which the text to get
  624. # x - x location on screen
  625. proc ::tk::EntryScanMark {w x} {
  626. $w scan mark $x
  627. set ::tk::Priv(x) $x
  628. set ::tk::Priv(y) 0 ; # not used
  629. set ::tk::Priv(mouseMoved) 0
  630. }
  631. # ::tk::EntryScanDrag --
  632. #
  633. # Marks the start of a possible scan drag operation
  634. #
  635. # Arguments:
  636. # w - The entry window from which the text to get
  637. # x - x location on screen
  638. proc ::tk::EntryScanDrag {w x} {
  639. # Make sure these exist, as some weird situations can trigger the
  640. # motion binding without the initial press. [Bug #220269]
  641. if {![info exists ::tk::Priv(x)]} {set ::tk::Priv(x) $x}
  642. # allow for a delta
  643. if {abs($x-$::tk::Priv(x)) > 2} {
  644. set ::tk::Priv(mouseMoved) 1
  645. }
  646. $w scan dragto $x
  647. }
  648. # ::tk::EntryGetSelection --
  649. #
  650. # Returns the selected text of the entry with respect to the -show option.
  651. #
  652. # Arguments:
  653. # w - The entry window from which the text to get
  654. proc ::tk::EntryGetSelection {w} {
  655. set entryString [string range [$w get] [$w index sel.first] \
  656. [$w index sel.last]-1]
  657. if {[$w cget -show] ne ""} {
  658. return [string repeat [string index [$w cget -show] 0] \
  659. [string length $entryString]]
  660. }
  661. return $entryString
  662. }