PageRenderTime 55ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/share/axis/tcl/dialog.tcl

https://github.com/narogon/linuxcnc
TCL | 261 lines | 147 code | 37 blank | 77 comment | 37 complexity | fc8c0a680c7e43cac950e6674af7622b MD5 | raw file
Possible License(s): 0BSD, LGPL-2.1, LGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. # Nf Screen designer for Tk toolkit
  2. # Copyright (C) 2004 Jeff Epler <jepler@unpythonic.net>
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. # dialog.tcl --
  18. #
  19. # This file defines the procedure nf_dialog, which creates a dialog
  20. # box containing an image, a message, and one or more buttons.
  21. #
  22. # RCS: @(#) $Id$
  23. #
  24. # Copyright (c) 1992-1993 The Regents of the University of California.
  25. # Copyright (c) 1994-1997 Sun Microsystems, Inc.
  26. #
  27. # See the file "license.terms" for information on usage and redistribution
  28. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  29. #
  30. proc patient_grab w {
  31. set ret [catch { grab $w } res]
  32. if {!$ret} { return }
  33. set sei $::errorInfo
  34. if {$res == "grab failed: another application has grab"
  35. || $res == "grab failed: window not viewable"} {
  36. after 100
  37. after idle patient_grab $w
  38. } else {
  39. error $ret $savedInfo
  40. }
  41. }
  42. #
  43. # nf_dialog:
  44. #
  45. # This procedure displays a dialog box, waits for a button in the dialog
  46. # to be invoked, then returns the index of the selected button. If the
  47. # dialog somehow gets destroyed, -1 is returned.
  48. #
  49. # Arguments:
  50. # w - Window to use for dialog top-level.
  51. #
  52. # If it is a list, then it is of the form {w args}
  53. # where args (different from the 'args' below) specify
  54. # extra keyword arguments:
  55. # -ext ...: show ... in a scrolling text area below the main
  56. # text
  57. # title - Title to display in dialog's decorative frame.
  58. # text - Message to display in dialog.
  59. # image - Image to display in dialog (empty string means none).
  60. # default - Index of button that is to display the default ring
  61. # (-1 means none).
  62. # args - One or more strings to display in buttons across the
  63. # bottom of the dialog box.
  64. proc nf_dialog_default {t n i} {
  65. for {set j 0} {$j < $n} {incr j} {
  66. if {$i == $j} {
  67. $t.button$j configure -default active
  68. } else {
  69. $t.button$j configure -default normal
  70. }
  71. }
  72. }
  73. proc nf_dialog {w title text image default args} {
  74. global tkPriv tcl_platform
  75. set pargs [lrange $w 1 end]
  76. set w [lindex $w 0]
  77. set ext {}
  78. foreach {k v} $pargs {
  79. switch -- $k {
  80. -ext { set ext $v }
  81. default { error "nf_dialog: unexpected positional argument $k $v" }
  82. }
  83. }
  84. if {[llength $default] != 1} {
  85. set accel $default
  86. set default [lsearch $accel -2]
  87. } else {
  88. set accel {}
  89. }
  90. # 1. Create the top-level window and divide it into top
  91. # and bottom parts.
  92. catch {destroy $w}
  93. toplevel $w -class Dialog
  94. wm title $w $title
  95. wm iconname $w Dialog
  96. wm protocol $w WM_DELETE_WINDOW { }
  97. wm resiz $w 0 0
  98. # The following command means that the dialog won't be posted if
  99. # [winfo parent $w] is iconified, but it's really needed; otherwise
  100. # the dialog can become obscured by other windows in the application,
  101. # even though its grab keeps the rest of the application from being used.
  102. wm transient $w [winfo toplevel [winfo parent $w]]
  103. if {![string compare $tcl_platform(platform) "macintosh"]} {
  104. unsupported1 style $w dBoxProc
  105. }
  106. frame $w.bot
  107. frame $w.top
  108. if {[llength $args] == 1} {
  109. pack $w.bot -side bottom -fill both
  110. } else {
  111. pack $w.bot -side bottom -fill none -anchor e -expand 1
  112. }
  113. pack $w.top -side top -fill both -expand 1
  114. # 2. Fill the top part with image and message (use the option
  115. # database for -wraplength and -font so that they can be
  116. # overridden by the caller).
  117. option add *Dialog.msg.wrapLength 3i widgetDefault
  118. if {![string compare $tcl_platform(platform) "macintosh"]} {
  119. option add *Dialog.msg.font system widgetDefault
  120. } else {
  121. option add *Dialog.msg.font {Times 12} widgetDefault
  122. }
  123. label $w.msg -justify left -text $text
  124. pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m
  125. if {[string compare $image ""]} {
  126. if {![string compare $tcl_platform(platform) "macintosh"] && ![string compare $image "error"]} {
  127. set image "stop"
  128. }
  129. label $w.image -image [load_image std_$image]
  130. pack $w.image -in $w.top -side left -padx 3m -pady 3m
  131. }
  132. if {$ext != {}} {
  133. frame $w.ext
  134. text $w.ext.t -yscrollcommand [list $w.ext.s set] -wrap word
  135. scrollbar $w.ext.s -command [list $w.ext.t yview] -orient v
  136. pack $w.ext.t -side left -fill both -expand 1
  137. pack $w.ext.s -side left -fill y
  138. $w.ext.t insert end $ext
  139. $w.ext.t configure -state disabled
  140. pack $w.ext -side top
  141. }
  142. # 3. Create a row of buttons at the bottom of the dialog.
  143. set i 0
  144. set l [llength $args]
  145. foreach but $args {
  146. button $w.button$i -text $but -command "set tkPriv(button) $i" \
  147. -width 10 -height 1 -padx 0 -pady .25
  148. set u [lindex $accel $i]
  149. bind $w.button$i <FocusIn> [list nf_dialog_default $w $l $i]
  150. if {$u == -3} {
  151. bind $w <Escape> "$w.button$i flash; set tkPriv(button) $i"
  152. }
  153. bind $w.button$i <Return> {%W flash; %W invoke}
  154. if {$u >= 0} {
  155. set c [string index $but $u]
  156. bind $w "[string tolower $c]" \
  157. "$w.button$i flash; set tkPriv(button) $i"
  158. $w.button$i configure -underline $u
  159. }
  160. grid $w.button$i -in $w.bot -column $i -row 0 -sticky ew -padx 3 -pady 3
  161. grid columnconfigure $w.bot $i
  162. set f [$w.button$i cget -font]
  163. set bwidth [expr 9 * [font measure $f "0"]]
  164. set twidth [font measure $f $but]
  165. if {$twidth > $bwidth} {
  166. $w.button$i configure -width 0 -padx .25m
  167. }
  168. incr i
  169. }
  170. # 4. Create a <Destroy> binding for the window that sets the
  171. # button variable to -1; this is needed in case something happens
  172. # that destroys the window, such as its parent window being destroyed.
  173. bind $w <Destroy> {set tkPriv(button) -1}
  174. # 5. Withdraw the window, then update all the geometry information
  175. # so we know how big it wants to be, then center the window in the
  176. # display and de-iconify it.
  177. wm withdraw $w
  178. update idletasks
  179. set parent [winfo parent $w]
  180. if {[winfo viewable $parent]} {
  181. set x [expr {[winfo rootx $parent]+([winfo reqwidth $parent]-[winfo reqwidth $w])/2}]
  182. set y [expr {[winfo rooty $parent]+([winfo reqheight $parent]-[winfo reqheight $w])/2}]
  183. } else {
  184. set x [expr {([winfo screenwidth $w]-[winfo reqwidth $w])/2}]
  185. set y [expr {([winfo screenheight $w]-[winfo reqheight $w])/2}]
  186. }
  187. wm geom $w +$x+$y
  188. wm deiconify $w
  189. # 6. Set a grab and claim the focus too.
  190. set oldFocus [focus]
  191. set oldGrab [grab current $w]
  192. if {[string compare $oldGrab ""]} {
  193. set grabStatus [grab status $oldGrab]
  194. }
  195. patient_grab $w
  196. if {$default >= 0} {
  197. focus $w.button$default
  198. } else {
  199. focus $w
  200. }
  201. # 7. Wait for the user to respond, then restore the focus and
  202. # return the index of the selected button. Restore the focus
  203. # before deleting the window, since otherwise the window manager
  204. # may take the focus away so we can't redirect it. Finally,
  205. # restore any grab that was in effect.
  206. tkwait variable tkPriv(button)
  207. catch {focus $oldFocus}
  208. catch {
  209. # It's possible that the window has already been destroyed,
  210. # hence this "catch". Delete the Destroy handler so that
  211. # tkPriv(button) doesn't get reset by it.
  212. bind $w <Destroy> {}
  213. destroy $w
  214. }
  215. if {[string compare $oldGrab ""]} {
  216. if {[string compare $grabStatus "global"]} {
  217. grab $oldGrab
  218. } else {
  219. grab -global $oldGrab
  220. }
  221. }
  222. return $tkPriv(button)
  223. }
  224. # vim:sw=4:sts=4: