PageRenderTime 51ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/FetchDICOM.vfs/lib/BWidget/listbox.tcl

http://github.com/dblezek/FetchDICOM
TCL | 1446 lines | 1031 code | 189 blank | 226 comment | 236 complexity | 2dae8571e61098a1291b96af066ca256 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. # ----------------------------------------------------------------------------
  2. # listbox.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # $Id: listbox.tcl,v 1.1 2003/11/11 18:16:57 blezek Exp $
  5. # ----------------------------------------------------------------------------
  6. # Index of commands:
  7. # - ListBox::create
  8. # - ListBox::configure
  9. # - ListBox::cget
  10. # - ListBox::insert
  11. # - ListBox::itemconfigure
  12. # - ListBox::itemcget
  13. # - ListBox::bindText
  14. # - ListBox::bindImage
  15. # - ListBox::delete
  16. # - ListBox::move
  17. # - ListBox::reorder
  18. # - ListBox::selection
  19. # - ListBox::exists
  20. # - ListBox::index
  21. # - ListBox::item - deprecated
  22. # - ListBox::items
  23. # - ListBox::see
  24. # - ListBox::edit
  25. # - ListBox::xview
  26. # - ListBox::yview
  27. # - ListBox::_update_edit_size
  28. # - ListBox::_destroy
  29. # - ListBox::_see
  30. # - ListBox::_update_scrollregion
  31. # - ListBox::_draw_item
  32. # - ListBox::_redraw_items
  33. # - ListBox::_redraw_selection
  34. # - ListBox::_redraw_listbox
  35. # - ListBox::_redraw_idle
  36. # - ListBox::_resize
  37. # - ListBox::_init_drag_cmd
  38. # - ListBox::_drop_cmd
  39. # - ListBox::_over_cmd
  40. # - ListBox::_auto_scroll
  41. # - ListBox::_scroll
  42. # ----------------------------------------------------------------------------
  43. # JDC: added -selectmode
  44. namespace eval ListBox {
  45. namespace eval Item {
  46. Widget::declare ListBox::Item {
  47. {-indent Int 0 0 "%d >= 0"}
  48. {-text String "" 0}
  49. {-font String "" 0}
  50. {-foreground String "" 0}
  51. {-image TkResource "" 0 label}
  52. {-window String "" 0}
  53. {-data String "" 0}
  54. {-fill Synonym -foreground}
  55. {-fg Synonym -foreground}
  56. }
  57. }
  58. DynamicHelp::include ListBox::Item balloon
  59. Widget::tkinclude ListBox canvas .c \
  60. remove {
  61. -insertwidth -insertbackground -insertborderwidth -insertofftime
  62. -insertontime -selectborderwidth -closeenough -confine -scrollregion
  63. -xscrollincrement -yscrollincrement -width -height
  64. } \
  65. initialize {
  66. -relief sunken -borderwidth 2 -takefocus 1
  67. -highlightthickness 1 -width 200
  68. }
  69. Widget::declare ListBox {
  70. {-deltax Int 10 0 "%d >= 0"}
  71. {-deltay Int 15 0 "%d >= 0"}
  72. {-padx Int 20 0 "%d >= 0"}
  73. {-foreground TkResource "" 0 listbox}
  74. {-background TkResource "" 0 listbox}
  75. {-selectbackground TkResource "" 0 listbox}
  76. {-selectforeground TkResource "" 0 listbox}
  77. {-font TkResource "" 0 listbox}
  78. {-width TkResource "" 0 listbox}
  79. {-height TkResource "" 0 listbox}
  80. {-redraw Boolean 1 0}
  81. {-multicolumn Boolean 0 0}
  82. {-dropovermode Flag "wpi" 0 "wpi"}
  83. {-selectmode Enum none 1 {none single multiple}}
  84. {-fg Synonym -foreground}
  85. {-bg Synonym -background}
  86. }
  87. DragSite::include ListBox "LISTBOX_ITEM" 1
  88. DropSite::include ListBox {
  89. LISTBOX_ITEM {copy {} move {}}
  90. }
  91. Widget::addmap ListBox "" .c {-deltay -yscrollincrement}
  92. proc ::ListBox { path args } { return [eval ListBox::create $path $args] }
  93. proc use {} {}
  94. variable _edit
  95. }
  96. # ----------------------------------------------------------------------------
  97. # Command ListBox::create
  98. # ----------------------------------------------------------------------------
  99. proc ListBox::create { path args } {
  100. Widget::init ListBox $path $args
  101. variable $path
  102. upvar 0 $path data
  103. Widget::getVariable $path autoIndex
  104. set autoIndex 0
  105. frame $path -class ListBox -bd 0 -highlightthickness 0 -relief flat
  106. # For 8.4+ we don't want to inherit the padding
  107. catch {$path configure -padx 0 -pady 0}
  108. # widget informations
  109. set data(nrows) -1
  110. # items informations
  111. set data(items) {}
  112. set data(selitems) {}
  113. # update informations
  114. set data(upd,level) 0
  115. set data(upd,afterid) ""
  116. set data(upd,level) 0
  117. set data(upd,delete) {}
  118. # drag and drop informations
  119. set data(dnd,scroll) ""
  120. set data(dnd,afterid) ""
  121. set data(dnd,item) ""
  122. eval canvas $path.c [Widget::subcget $path .c] -xscrollincrement 8
  123. pack $path.c -expand yes -fill both
  124. bind $path <Configure> "ListBox::_resize $path"
  125. bind $path <Destroy> "ListBox::_destroy $path"
  126. DragSite::setdrag $path $path.c ListBox::_init_drag_cmd \
  127. [Widget::cget $path -dragendcmd] 1
  128. DropSite::setdrop $path $path.c ListBox::_over_cmd ListBox::_drop_cmd 1
  129. rename $path ::$path:cmd
  130. proc ::$path { cmd args } "return \[eval ListBox::\$cmd $path \$args\]"
  131. set w [Widget::cget $path -width]
  132. set h [Widget::cget $path -height]
  133. set dy [Widget::cget $path -deltay]
  134. $path.c configure -width [expr {$w*8}] -height [expr {$h*$dy}]
  135. switch -exact -- [Widget::getoption $path -selectmode] {
  136. single {
  137. $path bindText <Button-1> [list $path selection set]
  138. $path bindImage <Button-1> [list $path selection set]
  139. }
  140. multiple {
  141. $path bindText <Button-1> [list ListBox::_multiple_select $path n %x %y]
  142. $path bindText <Control-Button-1> [list ListBox::_multiple_select $path c %x %y]
  143. $path bindText <Shift-Button-1> [list ListBox::_multiple_select $path s %x %y]
  144. $path bindImage <Button-1> [list ListBox::_multiple_select $path n %x %y]
  145. $path bindImage <Control-Button-1> [list ListBox::_multiple_select $path c %x %y]
  146. $path bindImage <Shift-Button-1> [list ListBox::_multiple_select $path s %x %y]
  147. }
  148. }
  149. return $path
  150. }
  151. # ----------------------------------------------------------------------------
  152. # Command ListBox::configure
  153. # ----------------------------------------------------------------------------
  154. proc ListBox::configure { path args } {
  155. set res [Widget::configure $path $args]
  156. set ch1 [expr {[Widget::hasChanged $path -deltay dy] |
  157. [Widget::hasChanged $path -padx val] |
  158. [Widget::hasChanged $path -multicolumn val]}]
  159. set ch2 [expr {[Widget::hasChanged $path -selectbackground val] |
  160. [Widget::hasChanged $path -selectforeground val]}]
  161. set redraw 0
  162. if { [Widget::hasChanged $path -height h] } {
  163. $path.c configure -height [expr {$h*$dy}]
  164. set redraw 1
  165. }
  166. if { [Widget::hasChanged $path -width w] } {
  167. $path.c configure -width [expr {$w*8}]
  168. set redraw 1
  169. }
  170. if { !$redraw } {
  171. if { $ch1 } {
  172. _redraw_idle $path 2
  173. } elseif { $ch2 } {
  174. _redraw_idle $path 1
  175. }
  176. }
  177. if { [Widget::hasChanged $path -redraw bool] && $bool } {
  178. variable $path
  179. upvar 0 $path data
  180. set lvl $data(upd,level)
  181. set data(upd,level) 0
  182. _redraw_idle $path $lvl
  183. }
  184. set force [Widget::hasChanged $path -dragendcmd dragend]
  185. DragSite::setdrag $path $path.c ListBox::_init_drag_cmd $dragend $force
  186. DropSite::setdrop $path $path.c ListBox::_over_cmd ListBox::_drop_cmd
  187. return $res
  188. }
  189. # ----------------------------------------------------------------------------
  190. # Command ListBox::cget
  191. # ----------------------------------------------------------------------------
  192. proc ListBox::cget { path option } {
  193. return [Widget::cget $path $option]
  194. }
  195. # ----------------------------------------------------------------------------
  196. # Command ListBox::insert
  197. # ----------------------------------------------------------------------------
  198. proc ListBox::insert { path index item args } {
  199. variable $path
  200. upvar 0 $path data
  201. Widget::getVariable $path autoIndex
  202. set item [string map [list #auto [incr autoIndex]] $item]
  203. if { [lsearch $data(items) $item] != -1 } {
  204. return -code error "item \"$item\" already exists"
  205. }
  206. Widget::init ListBox::Item $path.$item $args
  207. set data(items) [linsert $data(items) $index $item]
  208. set data(upd,create,$item) $item
  209. _redraw_idle $path 2
  210. return $item
  211. }
  212. # Bastien Chevreux (bach@mwgdna.com)
  213. # The multipleinsert command performs inserts several items at once into
  214. # the list. It is faster than calling insert multiple times as it uses the
  215. # Widget::copyinit command for initializing all items after the 1st. The
  216. # speedup factor is between 2 and 3 for typical usage, but could be higher
  217. # for inserts with many options.
  218. #
  219. # Syntax: path and index are as in the insert command
  220. # args is a list of even numbered elements where the 1st of each pair
  221. # corresponds to the item of 'insert' and the second to args of 'insert'.
  222. # ----------------------------------------------------------------------------
  223. # Command ListBox::multipleinsert
  224. # ----------------------------------------------------------------------------
  225. proc ListBox::multipleinsert { path index args } {
  226. variable $path
  227. upvar 0 $path data
  228. # If we got only one list as arg, take the first element as args
  229. # This enables callers to use
  230. # $list multipleinsert index $thelist
  231. # instead of
  232. # eval $list multipleinsert index $thelist
  233. if {[llength $args] == 1} {
  234. set args [lindex $args 0]
  235. }
  236. set count 0
  237. foreach {item iargs} $args {
  238. if { [lsearch $data(items) $item] != -1 } {
  239. return -code error "item \"$item\" already exists"
  240. }
  241. if {$count==0} {
  242. Widget::init ListBox::Item $path.$item $iargs
  243. set firstpath $path.$item
  244. } else {
  245. Widget::copyinit ListBox::Item $firstpath $path.$item $iargs
  246. }
  247. set data(items) [linsert $data(items) $index $item]
  248. set data(upd,create,$item) $item
  249. incr count
  250. }
  251. _redraw_idle $path 2
  252. return $item
  253. }
  254. # ----------------------------------------------------------------------------
  255. # Command ListBox::itemconfigure
  256. # ----------------------------------------------------------------------------
  257. proc ListBox::itemconfigure { path item args } {
  258. variable $path
  259. upvar 0 $path data
  260. if { [lsearch $data(items) $item] == -1 } {
  261. return -code error "item \"$item\" does not exist"
  262. }
  263. set oldind [Widget::getoption $path.$item -indent]
  264. set res [Widget::configure $path.$item $args]
  265. set chind [Widget::hasChanged $path.$item -indent indent]
  266. set chw [Widget::hasChanged $path.$item -window win]
  267. set chi [Widget::hasChanged $path.$item -image img]
  268. set cht [Widget::hasChanged $path.$item -text txt]
  269. set chf [Widget::hasChanged $path.$item -font fnt]
  270. set chfg [Widget::hasChanged $path.$item -foreground fg]
  271. set idn [$path.c find withtag n:$item]
  272. if { $idn == "" } {
  273. # item is not drawn yet
  274. _redraw_idle $path 2
  275. return $res
  276. }
  277. set oldb [$path.c bbox $idn]
  278. set coords [$path.c coords $idn]
  279. set padx [Widget::getoption $path -padx]
  280. set x0 [expr {[lindex $coords 0]-$padx-$oldind+$indent}]
  281. set y0 [lindex $coords 1]
  282. if { $chw || $chi } {
  283. # -window or -image modified
  284. set idi [$path.c find withtag i:$item]
  285. set type [lindex [$path.c gettags $idi] 0]
  286. if { [string length $win] } {
  287. if { ![string compare $type "win"] } {
  288. $path.c itemconfigure $idi -window $win
  289. } else {
  290. $path.c delete $idi
  291. $path.c create window $x0 $y0 -window $win -anchor w -tags "win i:$item"
  292. }
  293. } elseif { [string length $img] } {
  294. if { ![string compare $type "img"] } {
  295. $path.c itemconfigure $idi -image $img
  296. } else {
  297. $path.c delete $idi
  298. $path.c create image $x0 $y0 -image $img -anchor w -tags "img i:$item"
  299. }
  300. } else {
  301. $path.c delete $idi
  302. }
  303. }
  304. if { $cht || $chf || $chfg } {
  305. # -text or -font modified, or -foreground modified
  306. set fnt [_getoption $path $item -font]
  307. set fg [_getoption $path $item -foreground]
  308. $path.c itemconfigure $idn -text $txt -font $fnt -fill $fg
  309. _redraw_idle $path 1
  310. }
  311. if { $chind } {
  312. # -indent modified
  313. $path.c coords $idn [expr {$x0+$padx}] $y0
  314. $path.c coords i:$item $x0 $y0
  315. _redraw_idle $path 1
  316. }
  317. if { [Widget::getoption $path -multicolumn] && ($cht || $chf || $chind) } {
  318. set bbox [$path.c bbox $idn]
  319. if { [lindex $bbox 2] > [lindex $oldb 2] } {
  320. _redraw_idle $path 2
  321. }
  322. }
  323. _set_help $path $item
  324. return $res
  325. }
  326. # ----------------------------------------------------------------------------
  327. # Command ListBox::itemcget
  328. # ----------------------------------------------------------------------------
  329. proc ListBox::itemcget { path item option } {
  330. return [Widget::cget $path.$item $option]
  331. }
  332. # ----------------------------------------------------------------------------
  333. # Command ListBox::bindText
  334. # ----------------------------------------------------------------------------
  335. proc ListBox::bindText { path event script } {
  336. if { $script != "" } {
  337. $path.c bind "item" $event \
  338. "$script \[string range \[lindex \[$path.c gettags current\] 1\] 2 end\]"
  339. } else {
  340. $path.c bind "item" $event {}
  341. }
  342. }
  343. # ----------------------------------------------------------------------------
  344. # Command ListBox::bindImage
  345. # ----------------------------------------------------------------------------
  346. proc ListBox::bindImage { path event script } {
  347. if { $script != "" } {
  348. $path.c bind "img" $event \
  349. "$script \[string range \[lindex \[$path.c gettags current\] 1\] 2 end\]"
  350. } else {
  351. $path.c bind "img" $event {}
  352. }
  353. }
  354. # ----------------------------------------------------------------------------
  355. # Command ListBox::delete
  356. # ----------------------------------------------------------------------------
  357. proc ListBox::delete { path args } {
  358. variable $path
  359. upvar 0 $path data
  360. foreach litems $args {
  361. foreach item $litems {
  362. set idx [lsearch $data(items) $item]
  363. if { $idx != -1 } {
  364. set data(items) [lreplace $data(items) $idx $idx]
  365. Widget::destroy $path.$item
  366. if { [info exists data(upd,create,$item)] } {
  367. unset data(upd,create,$item)
  368. } else {
  369. lappend data(upd,delete) $item
  370. }
  371. }
  372. }
  373. }
  374. set sel $data(selitems)
  375. set data(selitems) {}
  376. eval selection $path set $sel
  377. _redraw_idle $path 2
  378. }
  379. # ----------------------------------------------------------------------------
  380. # Command ListBox::move
  381. # ----------------------------------------------------------------------------
  382. proc ListBox::move { path item index } {
  383. variable $path
  384. upvar 0 $path data
  385. if { [set idx [lsearch $data(items) $item]] == -1 } {
  386. return -code error "item \"$item\" does not exist"
  387. }
  388. set data(items) [linsert [lreplace $data(items) $idx $idx] $index $item]
  389. _redraw_idle $path 2
  390. }
  391. # ----------------------------------------------------------------------------
  392. # Command ListBox::reorder
  393. # ----------------------------------------------------------------------------
  394. proc ListBox::reorder { path neworder } {
  395. variable $path
  396. upvar 0 $path data
  397. set data(items) [BWidget::lreorder $data(items) $neworder]
  398. _redraw_idle $path 2
  399. }
  400. # ----------------------------------------------------------------------------
  401. # Command ListBox::selection
  402. # ----------------------------------------------------------------------------
  403. proc ListBox::selection { path cmd args } {
  404. variable $path
  405. upvar 0 $path data
  406. switch -- $cmd {
  407. set {
  408. set data(selitems) {}
  409. foreach item $args {
  410. if { [lsearch $data(selitems) $item] == -1 } {
  411. if { [lsearch $data(items) $item] != -1 } {
  412. lappend data(selitems) $item
  413. }
  414. }
  415. }
  416. }
  417. add {
  418. foreach item $args {
  419. if { [lsearch $data(selitems) $item] == -1 } {
  420. if { [lsearch $data(items) $item] != -1 } {
  421. lappend data(selitems) $item
  422. }
  423. }
  424. }
  425. }
  426. remove {
  427. foreach item $args {
  428. if { [set idx [lsearch $data(selitems) $item]] != -1 } {
  429. set data(selitems) [lreplace $data(selitems) $idx $idx]
  430. }
  431. }
  432. }
  433. clear {
  434. set data(selitems) {}
  435. }
  436. get {
  437. return $data(selitems)
  438. }
  439. includes {
  440. return [expr {[lsearch $data(selitems) $args] != -1}]
  441. }
  442. default {
  443. return
  444. }
  445. }
  446. _redraw_idle $path 1
  447. }
  448. # ----------------------------------------------------------------------------
  449. # Command ListBox::exists
  450. # ----------------------------------------------------------------------------
  451. proc ListBox::exists { path item } {
  452. variable $path
  453. upvar 0 $path data
  454. return [expr {[lsearch $data(items) $item] != -1}]
  455. }
  456. # ----------------------------------------------------------------------------
  457. # Command ListBox::index
  458. # ----------------------------------------------------------------------------
  459. proc ListBox::index { path item } {
  460. variable $path
  461. upvar 0 $path data
  462. return [lsearch $data(items) $item]
  463. }
  464. # ----------------------------------------------------------------------------
  465. # ListBox::find
  466. # Returns the item given a position.
  467. # findInfo @x,y ?confine?
  468. # lineNumber
  469. # ----------------------------------------------------------------------------
  470. proc ListBox::find {path findInfo {confine ""}} {
  471. variable $path
  472. upvar 0 $path widgetData
  473. if {[regexp -- {^@([0-9]+),([0-9]+)$} $findInfo match x y]} {
  474. set x [$path.c canvasx $x]
  475. set y [$path.c canvasy $y]
  476. } elseif {[regexp -- {^[0-9]+$} $findInfo lineNumber]} {
  477. set dy [Widget::getoption $path -deltay]
  478. set y [expr {$dy*($lineNumber+0.5)}]
  479. set confine ""
  480. } else {
  481. return -code error "invalid find spec \"$findInfo\""
  482. }
  483. set found 0
  484. set xi 0
  485. foreach xs $widgetData(xlist) {
  486. if {$x <= $xs} {
  487. foreach id [$path.c find overlapping $xi $y $xs $y] {
  488. set ltags [$path.c gettags $id]
  489. set item [lindex $ltags 0]
  490. if { ![string compare $item "item"] ||
  491. ![string compare $item "img"] ||
  492. ![string compare $item "win"] } {
  493. # item is the label or image/window of the node
  494. set item [string range [lindex $ltags 1] 2 end]
  495. set found 1
  496. break
  497. }
  498. }
  499. break
  500. }
  501. set xi $xs
  502. }
  503. if {$found} {
  504. if {![string compare $confine "confine"]} {
  505. # test if x stand inside node bbox
  506. set xi [expr {[lindex [$path.c coords n:$item] 0]-[Widget::getoption $path -padx]}]
  507. set xs [lindex [$path.c bbox n:$item] 2]
  508. if {$x >= $xi && $x <= $xs} {
  509. return $item
  510. }
  511. } else {
  512. return $item
  513. }
  514. }
  515. return ""
  516. }
  517. # ----------------------------------------------------------------------------
  518. # Command ListBox::item - deprecated
  519. # ----------------------------------------------------------------------------
  520. proc ListBox::item { path first {last ""} } {
  521. variable $path
  522. upvar 0 $path data
  523. if { ![string length $last] } {
  524. return [lindex $data(items) $first]
  525. } else {
  526. return [lrange $data(items) $first $last]
  527. }
  528. }
  529. # ----------------------------------------------------------------------------
  530. # Command ListBox::items
  531. # ----------------------------------------------------------------------------
  532. proc ListBox::items { path {first ""} {last ""}} {
  533. variable $path
  534. upvar 0 $path data
  535. if { ![string length $first] } {
  536. return $data(items)
  537. }
  538. if { ![string length $last] } {
  539. return [lindex $data(items) $first]
  540. } else {
  541. return [lrange $data(items) $first $last]
  542. }
  543. }
  544. # ----------------------------------------------------------------------------
  545. # Command ListBox::see
  546. # ----------------------------------------------------------------------------
  547. proc ListBox::see { path item } {
  548. variable $path
  549. upvar 0 $path data
  550. if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
  551. after cancel $data(upd,afterid)
  552. _redraw_listbox $path
  553. }
  554. set idn [$path.c find withtag n:$item]
  555. if { $idn != "" } {
  556. ListBox::_see $path $idn right
  557. ListBox::_see $path $idn left
  558. }
  559. }
  560. # ----------------------------------------------------------------------------
  561. # Command ListBox::edit
  562. # ----------------------------------------------------------------------------
  563. proc ListBox::edit { path item text {verifycmd ""} {clickres 0} {select 1}} {
  564. variable _edit
  565. variable $path
  566. upvar 0 $path data
  567. if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } {
  568. after cancel $data(upd,afterid)
  569. _redraw_listbox $path
  570. }
  571. set idn [$path.c find withtag n:$item]
  572. if { $idn != "" } {
  573. ListBox::_see $path $idn right
  574. ListBox::_see $path $idn left
  575. set oldfg [$path.c itemcget $idn -fill]
  576. set sbg [Widget::getoption $path -selectbackground]
  577. set coords [$path.c coords $idn]
  578. set x [lindex $coords 0]
  579. set y [lindex $coords 1]
  580. set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
  581. set w [expr {[winfo width $path] - 2*$bd}]
  582. set wmax [expr {[$path.c canvasx $w]-$x}]
  583. $path.c itemconfigure $idn -fill [Widget::getoption $path -background]
  584. $path.c itemconfigure s:$item -fill {} -outline {}
  585. set _edit(text) $text
  586. set _edit(wait) 0
  587. set frame [frame $path.edit \
  588. -relief flat -borderwidth 0 -highlightthickness 0 \
  589. -background [Widget::getoption $path -background]]
  590. set ent [entry $frame.edit \
  591. -width 0 \
  592. -relief solid \
  593. -borderwidth 1 \
  594. -highlightthickness 0 \
  595. -foreground [_getoption $path $item -foreground] \
  596. -background [Widget::getoption $path -background] \
  597. -selectforeground [Widget::getoption $path -selectforeground] \
  598. -selectbackground $sbg \
  599. -font [_getoption $path $item -font] \
  600. -textvariable ListBox::_edit(text)]
  601. pack $ent -ipadx 8 -anchor w
  602. set idw [$path.c create window $x $y -window $frame -anchor w]
  603. trace variable ListBox::_edit(text) w "ListBox::_update_edit_size $path $ent $idw $wmax"
  604. tkwait visibility $ent
  605. grab $frame
  606. BWidget::focus set $ent
  607. _update_edit_size $path $ent $idw $wmax
  608. update
  609. if { $select } {
  610. $ent selection range 0 end
  611. $ent icursor end
  612. $ent xview end
  613. }
  614. bindtags $ent [list $ent Entry]
  615. bind $ent <Escape> {set ListBox::_edit(wait) 0}
  616. bind $ent <Return> {set ListBox::_edit(wait) 1}
  617. if { $clickres == 0 || $clickres == 1 } {
  618. bind $frame <Button> "set ListBox::_edit(wait) $clickres"
  619. }
  620. set ok 0
  621. while { !$ok } {
  622. tkwait variable ListBox::_edit(wait)
  623. if { !$_edit(wait) || $verifycmd == "" ||
  624. [uplevel \#0 $verifycmd [list $_edit(text)]] } {
  625. set ok 1
  626. }
  627. }
  628. trace vdelete ListBox::_edit(text) w "ListBox::_update_edit_size $path $ent $idw $wmax"
  629. grab release $frame
  630. BWidget::focus release $ent
  631. destroy $frame
  632. $path.c delete $idw
  633. $path.c itemconfigure $idn -fill $oldfg
  634. $path.c itemconfigure s:$item -fill $sbg -outline $sbg
  635. if { $_edit(wait) } {
  636. return $_edit(text)
  637. }
  638. }
  639. return ""
  640. }
  641. # ----------------------------------------------------------------------------
  642. # Command ListBox::xview
  643. # ----------------------------------------------------------------------------
  644. proc ListBox::xview { path args } {
  645. return [eval $path.c xview $args]
  646. }
  647. # ----------------------------------------------------------------------------
  648. # Command ListBox::yview
  649. # ----------------------------------------------------------------------------
  650. proc ListBox::yview { path args } {
  651. return [eval $path.c yview $args]
  652. }
  653. # ----------------------------------------------------------------------------
  654. # Command ListBox::_update_edit_size
  655. # ----------------------------------------------------------------------------
  656. proc ListBox::_update_edit_size { path entry idw wmax args } {
  657. set entw [winfo reqwidth $entry]
  658. if { $entw >= $wmax } {
  659. $path.c itemconfigure $idw -width $wmax
  660. } else {
  661. $path.c itemconfigure $idw -width 0
  662. }
  663. }
  664. # ----------------------------------------------------------------------------
  665. # Command ListBox::_getoption
  666. # Returns the value of option for node. If empty, returned value is those
  667. # of the ListBox.
  668. # ----------------------------------------------------------------------------
  669. proc ListBox::_getoption { path item option } {
  670. set value [Widget::getoption $path.$item $option]
  671. if {![string length $value]} {
  672. set value [Widget::getoption $path $option]
  673. }
  674. return $value
  675. }
  676. # ----------------------------------------------------------------------------
  677. # Command ListBox::_destroy
  678. # ----------------------------------------------------------------------------
  679. proc ListBox::_destroy { path } {
  680. variable $path
  681. upvar 0 $path data
  682. if { $data(upd,afterid) != "" } {
  683. after cancel $data(upd,afterid)
  684. }
  685. if { $data(dnd,afterid) != "" } {
  686. after cancel $data(dnd,afterid)
  687. }
  688. foreach item $data(items) {
  689. Widget::destroy $path.$item
  690. }
  691. Widget::destroy $path
  692. unset data
  693. rename $path {}
  694. }
  695. # ----------------------------------------------------------------------------
  696. # Command ListBox::_see
  697. # ----------------------------------------------------------------------------
  698. proc ListBox::_see { path idn side } {
  699. set bbox [$path.c bbox $idn]
  700. set scrl [$path.c cget -scrollregion]
  701. set ymax [lindex $scrl 3]
  702. set dy [$path.c cget -yscrollincrement]
  703. set yv [$path.c yview]
  704. set yv0 [expr {round([lindex $yv 0]*$ymax/$dy)}]
  705. set yv1 [expr {round([lindex $yv 1]*$ymax/$dy)}]
  706. set y [expr {int([lindex [$path.c coords $idn] 1]/$dy)}]
  707. if { $y < $yv0 } {
  708. $path.c yview scroll [expr {$y-$yv0}] units
  709. } elseif { $y >= $yv1 } {
  710. $path.c yview scroll [expr {$y-$yv1+1}] units
  711. }
  712. set xmax [lindex $scrl 2]
  713. set dx [$path.c cget -xscrollincrement]
  714. set xv [$path.c xview]
  715. if { ![string compare $side "right"] } {
  716. set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}]
  717. set x1 [expr {int([lindex $bbox 2]/$dx)}]
  718. if { $x1 >= $xv1 } {
  719. $path.c xview scroll [expr {$x1-$xv1+1}] units
  720. }
  721. } else {
  722. set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}]
  723. set x0 [expr {int([lindex $bbox 0]/$dx)}]
  724. if { $x0 < $xv0 } {
  725. $path.c xview scroll [expr {$x0-$xv0}] units
  726. }
  727. }
  728. }
  729. # ----------------------------------------------------------------------------
  730. # Command ListBox::_update_scrollregion
  731. # ----------------------------------------------------------------------------
  732. proc ListBox::_update_scrollregion { path } {
  733. set bd [expr {2*([$path.c cget -borderwidth]+[$path.c cget -highlightthickness])}]
  734. set w [expr {[winfo width $path] - $bd}]
  735. set h [expr {[winfo height $path] - $bd}]
  736. set xinc [$path.c cget -xscrollincrement]
  737. set yinc [$path.c cget -yscrollincrement]
  738. set bbox [$path.c bbox all]
  739. if { [llength $bbox] } {
  740. set xs [lindex $bbox 2]
  741. set ys [lindex $bbox 3]
  742. if { $w < $xs } {
  743. set w [expr {int($xs)}]
  744. if { [set r [expr {$w % $xinc}]] } {
  745. set w [expr {$w+$xinc-$r}]
  746. }
  747. }
  748. if { $h < $ys } {
  749. set h [expr {int($ys)}]
  750. if { [set r [expr {$h % $yinc}]] } {
  751. set h [expr {$h+$yinc-$r}]
  752. }
  753. }
  754. }
  755. $path.c configure -scrollregion [list 0 0 $w $h]
  756. }
  757. # ----------------------------------------------------------------------------
  758. # Command ListBox::_draw_item
  759. # ----------------------------------------------------------------------------
  760. proc ListBox::_draw_item { path item x0 x1 y } {
  761. set indent [Widget::getoption $path.$item -indent]
  762. $path.c create text [expr {$x1+$indent}] $y \
  763. -text [Widget::getoption $path.$item -text] \
  764. -fill [_getoption $path $item -foreground] \
  765. -font [_getoption $path $item -font] \
  766. -anchor w \
  767. -tags "item n:$item"
  768. if { [set win [Widget::getoption $path.$item -window]] != "" } {
  769. $path.c create window [expr {$x0+$indent}] $y \
  770. -window $win -anchor w -tags "win i:$item"
  771. } elseif { [set img [Widget::getoption $path.$item -image]] != "" } {
  772. $path.c create image [expr {$x0+$indent}] $y \
  773. -image $img -anchor w -tags "img i:$item"
  774. }
  775. _set_help $path $item
  776. }
  777. # ----------------------------------------------------------------------------
  778. # Command ListBox::_redraw_items
  779. # ----------------------------------------------------------------------------
  780. proc ListBox::_redraw_items { path } {
  781. variable $path
  782. upvar 0 $path data
  783. set cursor [$path.c cget -cursor]
  784. $path.c configure -cursor watch
  785. set dx [Widget::getoption $path -deltax]
  786. set dy [Widget::getoption $path -deltay]
  787. set padx [Widget::getoption $path -padx]
  788. set y0 [expr {$dy/2}]
  789. set x0 4
  790. set x1 [expr {$x0+$padx}]
  791. set nitem 0
  792. set drawn {}
  793. set data(xlist) {}
  794. if { [Widget::getoption $path -multicolumn] } {
  795. set nrows $data(nrows)
  796. } else {
  797. set nrows [llength $data(items)]
  798. }
  799. foreach item $data(upd,delete) {
  800. $path.c delete i:$item n:$item s:$item
  801. }
  802. foreach item $data(items) {
  803. if { [info exists data(upd,create,$item)] } {
  804. _draw_item $path $item $x0 $x1 $y0
  805. unset data(upd,create,$item)
  806. } else {
  807. set indent [Widget::getoption $path.$item -indent]
  808. $path.c coords n:$item [expr {$x1+$indent}] $y0
  809. $path.c coords i:$item [expr {$x0+$indent}] $y0
  810. }
  811. incr y0 $dy
  812. incr nitem
  813. lappend drawn n:$item
  814. if { $nitem == $nrows } {
  815. set y0 [expr {$dy/2}]
  816. set bbox [eval $path.c bbox $drawn]
  817. set drawn {}
  818. set x0 [expr {[lindex $bbox 2]+$dx}]
  819. set x1 [expr {$x0+$padx}]
  820. set nitem 0
  821. lappend data(xlist) [lindex $bbox 2]
  822. }
  823. }
  824. if { $nitem && $nitem < $nrows } {
  825. set bbox [eval $path.c bbox $drawn]
  826. lappend data(xlist) [lindex $bbox 2]
  827. }
  828. set data(upd,delete) {}
  829. $path.c configure -cursor $cursor
  830. }
  831. # ----------------------------------------------------------------------------
  832. # Command ListBox::_redraw_selection
  833. # ----------------------------------------------------------------------------
  834. proc ListBox::_redraw_selection { path } {
  835. variable $path
  836. upvar 0 $path data
  837. set selbg [Widget::getoption $path -selectbackground]
  838. set selfg [Widget::getoption $path -selectforeground]
  839. foreach id [$path.c find withtag sel] {
  840. set item [string range [lindex [$path.c gettags $id] 1] 2 end]
  841. $path.c itemconfigure "n:$item" -fill [_getoption $path $item -foreground]
  842. }
  843. $path.c delete sel
  844. foreach item $data(selitems) {
  845. set bbox [$path.c bbox "n:$item"]
  846. if { [llength $bbox] } {
  847. set id [eval $path.c create rectangle $bbox \
  848. -fill $selbg -outline $selbg -tags [list "sel s:$item"]]
  849. $path.c itemconfigure "n:$item" -fill $selfg
  850. $path.c lower $id
  851. }
  852. }
  853. }
  854. # ----------------------------------------------------------------------------
  855. # Command ListBox::_redraw_listbox
  856. # ----------------------------------------------------------------------------
  857. proc ListBox::_redraw_listbox { path } {
  858. variable $path
  859. upvar 0 $path data
  860. if { [Widget::getoption $path -redraw] } {
  861. if { $data(upd,level) == 2 } {
  862. _redraw_items $path
  863. }
  864. _redraw_selection $path
  865. _update_scrollregion $path
  866. set data(upd,level) 0
  867. set data(upd,afterid) ""
  868. }
  869. }
  870. # ----------------------------------------------------------------------------
  871. # Command ListBox::_redraw_idle
  872. # ----------------------------------------------------------------------------
  873. proc ListBox::_redraw_idle { path level } {
  874. variable $path
  875. upvar 0 $path data
  876. if { $data(nrows) != -1 } {
  877. # widget is realized
  878. if { [Widget::getoption $path -redraw] && $data(upd,afterid) == "" } {
  879. set data(upd,afterid) [after idle ListBox::_redraw_listbox $path]
  880. }
  881. }
  882. if { $level > $data(upd,level) } {
  883. set data(upd,level) $level
  884. }
  885. return ""
  886. }
  887. # ----------------------------------------------------------------------------
  888. # Command ListBox::_resize
  889. # ----------------------------------------------------------------------------
  890. proc ListBox::_resize { path } {
  891. variable $path
  892. upvar 0 $path data
  893. if { [Widget::getoption $path -multicolumn] } {
  894. set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
  895. set h [expr {[winfo height $path] - 2*$bd}]
  896. set nrows [expr {$h/[$path.c cget -yscrollincrement]}]
  897. if { $nrows == 0 } {
  898. set nrows 1
  899. }
  900. if { $nrows != $data(nrows) } {
  901. set data(nrows) $nrows
  902. _redraw_idle $path 2
  903. } else {
  904. _update_scrollregion $path
  905. }
  906. } elseif { $data(nrows) == -1 } {
  907. # first Configure event
  908. set data(nrows) 0
  909. ListBox::_redraw_listbox $path
  910. } else {
  911. _update_scrollregion $path
  912. }
  913. }
  914. # ----------------------------------------------------------------------------
  915. # Command ListBox::_init_drag_cmd
  916. # ----------------------------------------------------------------------------
  917. proc ListBox::_init_drag_cmd { path X Y top } {
  918. set path [winfo parent $path]
  919. set ltags [$path.c gettags current]
  920. set item [lindex $ltags 0]
  921. if { ![string compare $item "item"] ||
  922. ![string compare $item "img"] ||
  923. ![string compare $item "win"] } {
  924. set item [string range [lindex $ltags 1] 2 end]
  925. if { [set cmd [Widget::getoption $path -draginitcmd]] != "" } {
  926. return [uplevel \#0 $cmd [list $path $item $top]]
  927. }
  928. if { [set type [Widget::getoption $path -dragtype]] == "" } {
  929. set type "LISTBOX_ITEM"
  930. }
  931. if { [set img [Widget::getoption $path.$item -image]] != "" } {
  932. pack [label $top.l -image $img -padx 0 -pady 0]
  933. }
  934. return [list $type {copy move link} $item]
  935. }
  936. return {}
  937. }
  938. # ----------------------------------------------------------------------------
  939. # Command ListBox::_drop_cmd
  940. # ----------------------------------------------------------------------------
  941. proc ListBox::_drop_cmd { path source X Y op type dnddata } {
  942. set path [winfo parent $path]
  943. variable $path
  944. upvar 0 $path data
  945. if { [string length $data(dnd,afterid)] } {
  946. after cancel $data(dnd,afterid)
  947. set data(dnd,afterid) ""
  948. }
  949. $path.c delete drop
  950. set data(dnd,scroll) ""
  951. if { [llength $data(dnd,item)] || ![llength $data(items)] } {
  952. if { [set cmd [Widget::getoption $path -dropcmd]] != "" } {
  953. return [uplevel \#0 $cmd [list $path $source $data(dnd,item) $op $type $dnddata]]
  954. }
  955. }
  956. return 0
  957. }
  958. # ----------------------------------------------------------------------------
  959. # Command ListBox::_over_cmd
  960. # ----------------------------------------------------------------------------
  961. proc ListBox::_over_cmd { path source event X Y op type dnddata } {
  962. set path [winfo parent $path]
  963. variable $path
  964. upvar 0 $path data
  965. if { ![string compare $event "leave"] } {
  966. # we leave the window listbox
  967. $path.c delete drop
  968. if { [string length $data(dnd,afterid)] } {
  969. after cancel $data(dnd,afterid)
  970. set data(dnd,afterid) ""
  971. }
  972. set data(dnd,scroll) ""
  973. return 0
  974. }
  975. if { ![string compare $event "enter"] } {
  976. # we enter the window listbox - dnd data initialization
  977. set mode [Widget::getoption $path -dropovermode]
  978. set data(dnd,mode) 0
  979. foreach c {w p i} {
  980. set data(dnd,mode) [expr {($data(dnd,mode) << 1) | ([string first $c $mode] != -1)}]
  981. }
  982. }
  983. set x [expr {$X-[winfo rootx $path]}]
  984. set y [expr {$Y-[winfo rooty $path]}]
  985. $path.c delete drop
  986. set data(dnd,item) ""
  987. # test for auto-scroll unless mode is widget only
  988. if { $data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != "" } {
  989. return 2
  990. }
  991. if { $data(dnd,mode) & 4 } {
  992. # dropovermode includes widget
  993. set target [list widget]
  994. set vmode 4
  995. } else {
  996. set target [list ""]
  997. set vmode 0
  998. }
  999. if { ($data(dnd,mode) & 2) && ![llength $data(items)] } {
  1000. # dropovermode includes position and listbox is empty
  1001. lappend target "" 0
  1002. set vmode [expr {$vmode | 2}]
  1003. }
  1004. if { ($data(dnd,mode) & 3) && [llength $data(items)]} {
  1005. # dropovermode includes item or position
  1006. # we extract the box (xi,yi,xs,ys) where we can find item around x,y
  1007. set len [llength $data(items)]
  1008. set xc [$path.c canvasx $x]
  1009. set yc [$path.c canvasy $y]
  1010. set dy [$path.c cget -yscrollincrement]
  1011. set line [expr {int($yc/$dy)}]
  1012. set yi [expr {$line*$dy}]
  1013. set ys [expr {$yi+$dy}]
  1014. set xi 0
  1015. set pos $line
  1016. if { [Widget::getoption $path -multicolumn] } {
  1017. set nrows $data(nrows)
  1018. } else {
  1019. set nrows $len
  1020. }
  1021. if { $line < $nrows } {
  1022. foreach xs $data(xlist) {
  1023. if { $xc <= $xs } {
  1024. break
  1025. }
  1026. set xi $xs
  1027. incr pos $nrows
  1028. }
  1029. if { $pos < $len } {
  1030. set item [lindex $data(items) $pos]
  1031. set xi [expr {[lindex [$path.c coords n:$item] 0]-[Widget::getoption $path -padx]-1}]
  1032. if { $data(dnd,mode) & 1 } {
  1033. # dropovermode includes item
  1034. lappend target $item
  1035. set vmode [expr {$vmode | 1}]
  1036. } else {
  1037. lappend target ""
  1038. }
  1039. if { $data(dnd,mode) & 2 } {
  1040. # dropovermode includes position
  1041. if { $yc >= $yi+$dy/2 } {
  1042. # position is after $item
  1043. incr pos
  1044. set yl $ys
  1045. } else {
  1046. # position is before $item
  1047. set yl $yi
  1048. }
  1049. lappend target $pos
  1050. set vmode [expr {$vmode | 2}]
  1051. } else {
  1052. lappend target ""
  1053. }
  1054. } else {
  1055. lappend target "" ""
  1056. }
  1057. } else {
  1058. lappend target "" ""
  1059. }
  1060. if { ($vmode & 3) == 3 } {
  1061. # result have both item and position
  1062. # we compute what is the preferred method
  1063. if { $yc-$yi <= 3 || $ys-$yc <= 3 } {
  1064. lappend target "position"
  1065. } else {
  1066. lappend target "item"
  1067. }
  1068. }
  1069. }
  1070. if { $vmode && [set cmd [Widget::getoption $path -dropovercmd]] != "" } {
  1071. # user-defined dropover command
  1072. set res [uplevel \#0 $cmd [list $source $target $op $type $dnddata]]
  1073. set code [lindex $res 0]
  1074. set vmode 0
  1075. if {$code & 1} {
  1076. # update vmode
  1077. switch -exact -- [lindex $res 1] {
  1078. item {set vmode 1}
  1079. position {set vmode 2}
  1080. widget {set vmode 4}
  1081. }
  1082. }
  1083. } else {
  1084. if { ($vmode & 3) == 3 } {
  1085. # result have both item and position
  1086. # we choose the preferred method
  1087. if { ![string compare [lindex $target 3] "position"] } {
  1088. set vmode [expr {$vmode & ~1}]
  1089. } else {
  1090. set vmode [expr {$vmode & ~2}]
  1091. }
  1092. }
  1093. if { $data(dnd,mode) == 4 || $data(dnd,mode) == 0 } {
  1094. # dropovermode is widget or empty - recall is not necessary
  1095. set code 1
  1096. } else {
  1097. set code 3
  1098. }
  1099. }
  1100. # draw dnd visual following vmode
  1101. if {[llength $data(items)]} {
  1102. if { $vmode & 1 } {
  1103. set data(dnd,item) [list "item" [lindex $target 1]]
  1104. $path.c create rectangle $xi $yi $xs $ys -tags drop
  1105. } elseif { $vmode & 2 } {
  1106. set data(dnd,item) [concat "position" [lindex $target 2]]
  1107. $path.c create line $xi $yl $xs $yl -tags drop
  1108. } elseif { $vmode & 4 } {
  1109. set data(dnd,item) [list "widget"]
  1110. } else {
  1111. set code [expr {$code & 2}]
  1112. }
  1113. }
  1114. if { $code & 1 } {
  1115. DropSite::setcursor based_arrow_down
  1116. } else {
  1117. DropSite::setcursor dot
  1118. }
  1119. return $code
  1120. }
  1121. # ----------------------------------------------------------------------------
  1122. # Command ListBox::_auto_scroll
  1123. # ----------------------------------------------------------------------------
  1124. proc ListBox::_auto_scroll { path x y } {
  1125. variable $path
  1126. upvar 0 $path data
  1127. set xmax [winfo width $path]
  1128. set ymax [winfo height $path]
  1129. set scroll {}
  1130. if { $y <= 6 } {
  1131. if { [lindex [$path.c yview] 0] > 0 } {
  1132. set scroll [list yview -1]
  1133. DropSite::setcursor sb_up_arrow
  1134. }
  1135. } elseif { $y >= $ymax-6 } {
  1136. if { [lindex [$path.c yview] 1] < 1 } {
  1137. set scroll [list yview 1]
  1138. DropSite::setcursor sb_down_arrow
  1139. }
  1140. } elseif { $x <= 6 } {
  1141. if { [lindex [$path.c xview] 0] > 0 } {
  1142. set scroll [list xview -1]
  1143. DropSite::setcursor sb_left_arrow
  1144. }
  1145. } elseif { $x >= $xmax-6 } {
  1146. if { [lindex [$path.c xview] 1] < 1 } {
  1147. set scroll [list xview 1]
  1148. DropSite::setcursor sb_right_arrow
  1149. }
  1150. }
  1151. if { [string length $data(dnd,afterid)] && [string compare $data(dnd,scroll) $scroll] } {
  1152. after cancel $data(dnd,afterid)
  1153. set data(dnd,afterid) ""
  1154. }
  1155. set data(dnd,scroll) $scroll
  1156. if { [llength $scroll] && ![string length $data(dnd,afterid)] } {
  1157. set data(dnd,afterid) [after 200 ListBox::_scroll $path $scroll]
  1158. }
  1159. return $data(dnd,afterid)
  1160. }
  1161. # -----------------------------------------------------------------------------
  1162. # Command ListBox::_multiple_select
  1163. # -----------------------------------------------------------------------------
  1164. proc ListBox::_multiple_select { path mode x y idx } {
  1165. variable $path
  1166. upvar 0 $path data
  1167. if { ![info exists data(anchor)] || ![info exists data(sel_anchor)] } {
  1168. set data(anchor) $idx
  1169. set data(sel_anchor) {}
  1170. }
  1171. switch -exact -- $mode {
  1172. n {
  1173. $path selection set $idx
  1174. set data(anchor) $idx
  1175. set data(sel_anchor) {}
  1176. }
  1177. c {
  1178. set l [$path selection get]
  1179. if { [lsearch -exact $l $idx] >= 0 } {
  1180. $path selection remove $idx
  1181. } else {
  1182. $path selection add $idx
  1183. }
  1184. set data(anchor) $idx
  1185. set data(sel_anchor) {}
  1186. }
  1187. s {
  1188. eval $path selection remove $data(sel_anchor)
  1189. if { $idx > $data(anchor) } {
  1190. set istart $data(anchor)
  1191. set iend $idx
  1192. } else {
  1193. set istart $idx
  1194. set iend $data(anchor)
  1195. }
  1196. for { set i $istart } { $i <= $iend } { incr i } {
  1197. set l [$path selection get]
  1198. set li [lsearch -exact $l $i]
  1199. if { $li < 0 } {
  1200. $path selection add $i
  1201. lappend data(sel_anchor) $i
  1202. }
  1203. }
  1204. }
  1205. }
  1206. }
  1207. # ----------------------------------------------------------------------------
  1208. # Command ListBox::_scroll
  1209. # ----------------------------------------------------------------------------
  1210. proc ListBox::_scroll { path cmd dir } {
  1211. variable $path
  1212. upvar 0 $path data
  1213. if { ($dir == -1 && [lindex [$path.c $cmd] 0] > 0) ||
  1214. ($dir == 1 && [lindex [$path.c $cmd] 1] < 1) } {
  1215. $path $cmd scroll $dir units
  1216. set data(dnd,afterid) [after 100 ListBox::_scroll $path $cmd $dir]
  1217. } else {
  1218. set data(dnd,afterid) ""
  1219. DropSite::setcursor dot
  1220. }
  1221. }
  1222. # ListBox::_set_help --
  1223. #
  1224. # Register dynamic help for an item in the listbox.
  1225. #
  1226. # Arguments:
  1227. # path ListBox to query
  1228. # item Item in the listbox
  1229. # force Optional argument to force a reset of the help
  1230. #
  1231. # Results:
  1232. # none
  1233. proc ListBox::_set_help { path node } {
  1234. Widget::getVariable $path help
  1235. set item $path.$node
  1236. set opts [list -helptype -helptext -helpvar]
  1237. foreach {cty ctx cv} [eval Widget::hasChangedX $item $opts] break
  1238. set text [Widget::getoption $item -helptext]
  1239. ## If we've never set help for this item before, and text is not blank,
  1240. ## we need to setup help. We also need to reset help if any of the
  1241. ## options have changed.
  1242. if { (![info exists help($node)] && $text != "") || $cty || $ctx || $cv } {
  1243. set help($node) 1
  1244. set type [Widget::getoption $item -helptype]
  1245. switch $type {
  1246. balloon {
  1247. DynamicHelp::register $path.c balloon n:$node $text
  1248. DynamicHelp::register $path.c balloon i:$node $text
  1249. }
  1250. variable {
  1251. set var [Widget::getoption $item -helpvar]
  1252. DynamicHelp::register $path.c variable n:$node $var $text
  1253. DynamicHelp::register $path.c variable i:$node $var $text
  1254. }
  1255. }
  1256. }
  1257. }