dynhelp.tcl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. # ------------------------------------------------------------------------------
  2. # dynhelp.tcl
  3. # This file is part of Unifix BWidget Toolkit
  4. # $Id$
  5. # ------------------------------------------------------------------------------
  6. # Index of commands:
  7. # - DynamicHelp::configure
  8. # - DynamicHelp::include
  9. # - DynamicHelp::sethelp
  10. # - DynamicHelp::register
  11. # - DynamicHelp::_motion_balloon
  12. # - DynamicHelp::_motion_info
  13. # - DynamicHelp::_leave_info
  14. # - DynamicHelp::_menu_info
  15. # - DynamicHelp::_show_help
  16. # - DynamicHelp::_init
  17. # ------------------------------------------------------------------------------
  18. namespace eval DynamicHelp {
  19. Widget::declare DynamicHelp {
  20. {-foreground TkResource black 0 label}
  21. {-background TkResource "#FFFFC0" 0 label}
  22. {-borderwidth TkResource 1 0 label}
  23. {-justify TkResource left 0 label}
  24. {-font TkResource "helvetica 8" 0 label}
  25. {-delay Int 600 0 {=100 =2000}}
  26. {-bd Synonym -borderwidth}
  27. {-bg Synonym -background}
  28. {-fg Synonym -foreground}
  29. }
  30. proc use {} {}
  31. variable _registered
  32. variable _top ".help_shell"
  33. variable _id ""
  34. variable _delay 600
  35. variable _current ""
  36. variable _saved
  37. Widget::init DynamicHelp $_top {}
  38. bind BwHelpBalloon <Enter> {DynamicHelp::_motion_balloon enter %W %X %Y}
  39. bind BwHelpBalloon <Motion> {DynamicHelp::_motion_balloon motion %W %X %Y}
  40. bind BwHelpBalloon <Leave> {DynamicHelp::_motion_balloon leave %W %X %Y}
  41. bind BwHelpBalloon <Button> {DynamicHelp::_motion_balloon button %W %X %Y}
  42. bind BwHelpBalloon <Destroy> {catch {unset DynamicHelp::_registered(%W)}}
  43. bind BwHelpVariable <Enter> {DynamicHelp::_motion_info %W}
  44. bind BwHelpVariable <Motion> {DynamicHelp::_motion_info %W}
  45. bind BwHelpVariable <Leave> {DynamicHelp::_leave_info %W}
  46. bind BwHelpVariable <Destroy> {catch {unset DynamicHelp::_registered(%W)}}
  47. bind BwHelpMenu <<MenuSelect>> {DynamicHelp::_menu_info select %W}
  48. bind BwHelpMenu <Unmap> {DynamicHelp::_menu_info unmap %W}
  49. bind BwHelpMenu <Destroy> {catch {unset DynamicHelp::_registered(%W)}}
  50. }
  51. # ------------------------------------------------------------------------------
  52. # Command DynamicHelp::configure
  53. # ------------------------------------------------------------------------------
  54. proc DynamicHelp::configure { args } {
  55. variable _top
  56. variable _delay
  57. set res [Widget::configure $_top $args]
  58. if { [Widget::hasChanged $_top -delay val] } {
  59. set _delay $val
  60. }
  61. return $res
  62. }
  63. # ------------------------------------------------------------------------------
  64. # Command DynamicHelp::include
  65. # ------------------------------------------------------------------------------
  66. proc DynamicHelp::include { class type } {
  67. set helpoptions {
  68. {-helptext String "" 0}
  69. {-helpvar String "" 0}}
  70. lappend helpoptions [list -helptype Enum $type 0 {balloon variable}]
  71. Widget::declare $class $helpoptions
  72. }
  73. # ------------------------------------------------------------------------------
  74. # Command DynamicHelp::sethelp
  75. # ------------------------------------------------------------------------------
  76. proc DynamicHelp::sethelp { path subpath {force 0}} {
  77. set ctype [Widget::hasChanged $path -helptype htype]
  78. set ctext [Widget::hasChanged $path -helptext htext]
  79. set cvar [Widget::hasChanged $path -helpvar hvar]
  80. if { $force || $ctype || $ctext || $cvar } {
  81. switch $htype {
  82. balloon {
  83. return [register $subpath balloon $htext]
  84. }
  85. variable {
  86. return [register $subpath variable $hvar $htext]
  87. }
  88. }
  89. return [register $subpath $htype]
  90. }
  91. }
  92. # ------------------------------------------------------------------------------
  93. # Command DynamicHelp::register
  94. # ------------------------------------------------------------------------------
  95. proc DynamicHelp::register { path type args } {
  96. variable _registered
  97. if { [winfo exists $path] } {
  98. set evt [bindtags $path]
  99. set idx [lsearch $evt "BwHelp*"]
  100. set evt [lreplace $evt $idx $idx]
  101. switch $type {
  102. balloon {
  103. set text [lindex $args 0]
  104. if { $text != "" } {
  105. set _registered($path) $text
  106. lappend evt BwHelpBalloon
  107. } else {
  108. catch {unset _registered($path)}
  109. }
  110. bindtags $path $evt
  111. return 1
  112. }
  113. variable {
  114. set var [lindex $args 0]
  115. set text [lindex $args 1]
  116. if { $text != "" && $var != "" } {
  117. set _registered($path) [list $var $text]
  118. lappend evt BwHelpVariable
  119. } else {
  120. catch {unset _registered($path)}
  121. }
  122. bindtags $path $evt
  123. return 1
  124. }
  125. menu {
  126. set cpath [BWidget::clonename $path]
  127. if { [winfo exists $cpath] } {
  128. set path $cpath
  129. }
  130. set var [lindex $args 0]
  131. if { $var != "" } {
  132. set _registered($path) [list $var]
  133. lappend evt BwHelpMenu
  134. } else {
  135. catch {unset _registered($path)}
  136. }
  137. bindtags $path $evt
  138. return 1
  139. }
  140. menuentry {
  141. set cpath [BWidget::clonename $path]
  142. if { [winfo exists $cpath] } {
  143. set path $cpath
  144. }
  145. if { [info exists _registered($path)] } {
  146. if { [set index [lindex $args 0]] != "" } {
  147. set text [lindex $args 1]
  148. set idx [lsearch $_registered($path) [list $index *]]
  149. if { $text != "" } {
  150. if { $idx == -1 } {
  151. lappend _registered($path) [list $index $text]
  152. } else {
  153. set _registered($path) [lreplace $_registered($path) $idx $idx [list $index $text]]
  154. }
  155. } else {
  156. set _registered($path) [lreplace $_registered($path) $idx $idx]
  157. }
  158. }
  159. return 1
  160. }
  161. return 0
  162. }
  163. }
  164. catch {unset _registered($path)}
  165. bindtags $path $evt
  166. return 1
  167. } else {
  168. catch {unset _registered($path)}
  169. return 0
  170. }
  171. }
  172. # ------------------------------------------------------------------------------
  173. # Command DynamicHelp::_motion_balloon
  174. # ------------------------------------------------------------------------------
  175. proc DynamicHelp::_motion_balloon { type path x y } {
  176. variable _top
  177. variable _id
  178. variable _delay
  179. variable _current
  180. if { $_current != $path && $type == "enter" } {
  181. set _current $path
  182. set type "motion"
  183. destroy $_top
  184. }
  185. if { $_current == $path } {
  186. if { $_id != "" } {
  187. after cancel $_id
  188. set _id ""
  189. }
  190. if { $type == "motion" } {
  191. if { ![winfo exists $_top] } {
  192. set _id [after $_delay "DynamicHelp::_show_help $path $x $y"]
  193. }
  194. } else {
  195. destroy $_top
  196. set _current ""
  197. }
  198. }
  199. }
  200. # ------------------------------------------------------------------------------
  201. # Command DynamicHelp::_motion_info
  202. # ------------------------------------------------------------------------------
  203. proc DynamicHelp::_motion_info { path } {
  204. variable _registered
  205. variable _current
  206. variable _saved
  207. if { $_current != $path && [info exists _registered($path)] } {
  208. if { ![info exists _saved] } {
  209. set _saved [GlobalVar::getvar [lindex $_registered($path) 0]]
  210. }
  211. GlobalVar::setvar [lindex $_registered($path) 0] [lindex $_registered($path) 1]
  212. set _current $path
  213. }
  214. }
  215. # ------------------------------------------------------------------------------
  216. # Command DynamicHelp::_leave_info
  217. # ------------------------------------------------------------------------------
  218. proc DynamicHelp::_leave_info { path } {
  219. variable _registered
  220. variable _current
  221. variable _saved
  222. if { [info exists _registered($path)] } {
  223. GlobalVar::setvar [lindex $_registered($path) 0] $_saved
  224. }
  225. unset _saved
  226. set _current ""
  227. }
  228. # ------------------------------------------------------------------------------
  229. # Command DynamicHelp::_menu_info
  230. # Version of R1v1 restored, due to lack of [winfo ismapped] and <Unmap>
  231. # under windows for menu.
  232. # ------------------------------------------------------------------------------
  233. proc DynamicHelp::_menu_info { event path } {
  234. variable _registered
  235. if { [info exists _registered($path)] } {
  236. set index [$path index active]
  237. if { [string compare $index "none"] &&
  238. [set idx [lsearch $_registered($path) [list $index *]]] != -1 } {
  239. GlobalVar::setvar [lindex $_registered($path) 0] \
  240. [lindex [lindex $_registered($path) $idx] 1]
  241. } else {
  242. GlobalVar::setvar [lindex $_registered($path) 0] ""
  243. }
  244. }
  245. }
  246. # ------------------------------------------------------------------------------
  247. # Command DynamicHelp::_show_help
  248. # ------------------------------------------------------------------------------
  249. proc DynamicHelp::_show_help { path x y } {
  250. variable _top
  251. variable _registered
  252. variable _id
  253. variable _delay
  254. if { [info exists _registered($path)] } {
  255. destroy $_top
  256. toplevel $_top -relief flat \
  257. -bg [Widget::getoption $_top -foreground] \
  258. -bd [Widget::getoption $_top -borderwidth]
  259. wm overrideredirect $_top 1
  260. wm transient $_top
  261. wm withdraw $_top
  262. label $_top.label -text $_registered($path) \
  263. -relief flat -bd 0 -highlightthickness 0 \
  264. -foreground [Widget::getoption $_top -foreground] \
  265. -background [Widget::getoption $_top -background] \
  266. -font [Widget::getoption $_top -font] \
  267. -justify [Widget::getoption $_top -justify]
  268. pack $_top.label -side left
  269. update idletasks
  270. set scrwidth [winfo vrootwidth .]
  271. set scrheight [winfo vrootheight .]
  272. set width [winfo reqwidth $_top]
  273. set height [winfo reqheight $_top]
  274. incr y 12
  275. incr x 8
  276. if { $x+$width > $scrwidth } {
  277. set x [expr $scrwidth - $width]
  278. }
  279. if { $y+$height > $scrheight } {
  280. set y [expr $y - 12 - $height]
  281. }
  282. wm geometry $_top "+$x+$y"
  283. update idletasks
  284. wm deiconify $_top
  285. }
  286. }