widget 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. #!/bin/sh
  2. # the next line restarts using wish \
  3. exec wish "$0" ${1+"$@"}
  4. # widget --
  5. # This script demonstrates the various widgets provided by Tk, along with many
  6. # of the features of the Tk toolkit. This file only contains code to generate
  7. # the main window for the application, which invokes individual
  8. # demonstrations. The code for the actual demonstrations is contained in
  9. # separate ".tcl" files is this directory, which are sourced by this script as
  10. # needed.
  11. package require Tcl 8.5
  12. package require Tk 8.5
  13. package require msgcat
  14. package require Ttk
  15. eval destroy [winfo child .]
  16. set tk_demoDirectory [file join [pwd] [file dirname [info script]]]
  17. ::msgcat::mcload $tk_demoDirectory
  18. namespace import ::msgcat::mc
  19. wm title . [mc "Widget Demonstration"]
  20. if {[tk windowingsystem] eq "x11"} {
  21. # This won't work everywhere, but there's no other way in core Tk at the
  22. # moment to display a coloured icon.
  23. image create photo TclPowered \
  24. -file [file join $tk_library images logo64.gif]
  25. wm iconwindow . [toplevel ._iconWindow]
  26. pack [label ._iconWindow.i -image TclPowered]
  27. wm iconname . [mc "tkWidgetDemo"]
  28. }
  29. if {"defaultFont" ni [font names]} {
  30. # TIP #145 defines some standard named fonts
  31. if {"TkDefaultFont" in [font names] && "TkFixedFont" in [font names]} {
  32. # FIX ME: the following technique of cloning the font to copy it works
  33. # fine but means that if the system font is changed by Tk
  34. # cannot update the copied font. font alias might be useful
  35. # here -- or fix the app to use TkDefaultFont etc.
  36. font create mainFont {*}[font configure TkDefaultFont]
  37. font create fixedFont {*}[font configure TkFixedFont]
  38. font create boldFont {*}[font configure TkDefaultFont] -weight bold
  39. font create titleFont {*}[font configure TkDefaultFont] -weight bold
  40. font create statusFont {*}[font configure TkDefaultFont]
  41. font create varsFont {*}[font configure TkDefaultFont]
  42. if {[tk windowingsystem] eq "aqua"} {
  43. font configure titleFont -size 17
  44. }
  45. } else {
  46. font create mainFont -family Helvetica -size 12
  47. font create fixedFont -family Courier -size 10
  48. font create boldFont -family Helvetica -size 12 -weight bold
  49. font create titleFont -family Helvetica -size 18 -weight bold
  50. font create statusFont -family Helvetica -size 10
  51. font create varsFont -family Helvetica -size 14
  52. }
  53. }
  54. set widgetDemo 1
  55. set font mainFont
  56. image create photo ::img::refresh -format GIF -data {
  57. R0lGODlhEAAQAJEDAP///wAAACpnKv///yH5BAEAAAMALAAAAAAQABAAAAI63IKp
  58. xgcPH2ouwgBCw1HIxHCQ4F3hSJKmwZXqWrmWxj7lKJ2dndcon9EBUq+gz3brVXAR
  59. 2tICU0gXBQA7
  60. }
  61. image create photo ::img::view -format GIF -data {
  62. R0lGODlhEAAQAKIHAP///wwMDAAAAMDAwNnZ2SYmJmZmZv///yH5BAEAAAcALAAA
  63. AAAQABAAAANMKLos90+ASamDRxJCgw9YVnlDOXiQBgRDBRgHKE6sW8QR3doPKK27
  64. yg33q/GIOhdg6OsEJzeZykiBSUcs06e56Xx6np8ScIkFGuhQAgA7
  65. }
  66. image create photo ::img::delete -format GIF -data {
  67. R0lGODlhEAAQAIABAIQAAP///yH5BAEAAAEALAAAAAAQABAAAAIjjI+pmwAc3HGy
  68. PUSvqYpuvWQg40FfSVacBa5nN6JYDI3mzRQAOw==
  69. }
  70. image create photo ::img::print -format GIF -data {
  71. R0lGODlhEAAQALMKAAAAAP///52VunNkl8C82Yl+qldBgq+pyrOzs1fYAP///wAA
  72. AAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARGUMlJKwU4AztB+ODGeUiJ
  73. fGLlgeEYmGWQXmx7aXgmAUTv/74N4EAsGhOJg1DAbDqbwoJ0Sp0KB9isNis0eL/g
  74. ryhH5pgnEQA7
  75. }
  76. # Note that this is run through the message catalog! This is because this is
  77. # actually an image of a word.
  78. image create photo ::img::new -format GIF -data [mc {
  79. R0lGODlhHgAOALMPALMAANyIiOu7u8dEROaqqvru7sxVVeGZmbgREfXd3b0iItZ3
  80. d8IzM9FmZvDMzP///yH5BAEAAA8ALAAAAAAeAA4AAASa8MlJq7046827WVOCHEkw
  81. nANhUgJlEBIABJIwL3K+4IcUALCHjfbItYZDSgJgkBiYPmBMAUAkkLPKs/BAyLgM
  82. wAQwOAAY2ByCaw4QAFQSoDEePJ6DmU1xInYZTw5nOEFFdgVUelkVDTIMd3AKFGQ1
  83. MgI2AwEmQW8APZ0gdRONAks5nhIFVVxdAAkUAS2pAVwFl7ITB4UqHb0XEQA7
  84. }]
  85. #----------------------------------------------------------------
  86. # The code below create the main window, consisting of a menu bar and a text
  87. # widget that explains how to use the program, plus lists all of the demos as
  88. # hypertext items.
  89. #----------------------------------------------------------------
  90. menu .menuBar -tearoff 0
  91. if {[tk windowingsystem] ne "aqua"} {
  92. # This is a tk-internal procedure to make i18n easier
  93. ::tk::AmpMenuArgs .menuBar add cascade -label [mc "&File"] \
  94. -menu .menuBar.file
  95. menu .menuBar.file -tearoff 0
  96. ::tk::AmpMenuArgs .menuBar.file add command -label [mc "&About..."] \
  97. -command {tkAboutDialog} -accelerator [mc "<F1>"]
  98. bind . <F1> {tkAboutDialog}
  99. .menuBar.file add sep
  100. if {[string match win* [tk windowingsystem]]} {
  101. # Windows doesn't usually have a Meta key
  102. ::tk::AmpMenuArgs .menuBar.file add command -label [mc "&Quit"] \
  103. -command {exit} -accelerator [mc "Ctrl+Q"]
  104. bind . <[mc "Control-q"]> {exit}
  105. } else {
  106. ::tk::AmpMenuArgs .menuBar.file add command -label [mc "&Quit"] \
  107. -command {exit} -accelerator [mc "Meta-Q"]
  108. bind . <[mc "Meta-q"]> {exit}
  109. }
  110. }
  111. . configure -menu .menuBar
  112. ttk::frame .statusBar
  113. ttk::label .statusBar.lab -text " " -anchor w
  114. if {[tk windowingsystem] eq "aqua"} {
  115. ttk::separator .statusBar.sep
  116. pack .statusBar.sep -side top -expand yes -fill x -pady 0
  117. }
  118. pack .statusBar.lab -side left -padx 2 -expand yes -fill both
  119. if {[tk windowingsystem] ne "aqua"} {
  120. ttk::sizegrip .statusBar.foo
  121. pack .statusBar.foo -side left -padx 2
  122. }
  123. pack .statusBar -side bottom -fill x -pady 2
  124. set textheight 30
  125. catch {
  126. set textheight [expr {
  127. ([winfo screenheight .] * 0.7) /
  128. [font metrics mainFont -displayof . -linespace]
  129. }]
  130. }
  131. ttk::frame .textFrame
  132. scrollbar .s -orient vertical -command {.t yview} -takefocus 1
  133. pack .s -in .textFrame -side right -fill y
  134. text .t -yscrollcommand {.s set} -wrap word -width 70 -height $textheight \
  135. -font mainFont -setgrid 1 -highlightthickness 0 \
  136. -padx 4 -pady 2 -takefocus 0
  137. pack .t -in .textFrame -expand y -fill both -padx 1
  138. pack .textFrame -expand yes -fill both
  139. if {[tk windowingsystem] eq "aqua"} {
  140. pack configure .statusBar.lab -padx {10 18} -pady {4 6}
  141. pack configure .statusBar -pady 0
  142. .t configure -padx 10 -pady 0
  143. }
  144. # Create a bunch of tags to use in the text widget, such as those for section
  145. # titles and demo descriptions. Also define the bindings for tags.
  146. .t tag configure title -font titleFont
  147. .t tag configure subtitle -font titleFont
  148. .t tag configure bold -font boldFont
  149. if {[tk windowingsystem] eq "aqua"} {
  150. .t tag configure title -spacing1 8
  151. .t tag configure subtitle -spacing3 3
  152. }
  153. # We put some "space" characters to the left and right of each demo
  154. # description so that the descriptions are highlighted only when the mouse
  155. # cursor is right over them (but not when the cursor is to their left or
  156. # right).
  157. #
  158. .t tag configure demospace -lmargin1 1c -lmargin2 1c
  159. if {[winfo depth .] == 1} {
  160. .t tag configure demo -lmargin1 1c -lmargin2 1c \
  161. -underline 1
  162. .t tag configure visited -lmargin1 1c -lmargin2 1c \
  163. -underline 1
  164. .t tag configure hot -background black -foreground white
  165. } else {
  166. .t tag configure demo -lmargin1 1c -lmargin2 1c \
  167. -foreground blue -underline 1
  168. .t tag configure visited -lmargin1 1c -lmargin2 1c \
  169. -foreground #303080 -underline 1
  170. .t tag configure hot -foreground red -underline 1
  171. }
  172. .t tag bind demo <ButtonRelease-1> {
  173. invoke [.t index {@%x,%y}]
  174. }
  175. set lastLine ""
  176. .t tag bind demo <Enter> {
  177. set lastLine [.t index {@%x,%y linestart}]
  178. .t tag add hot "$lastLine +1 chars" "$lastLine lineend -1 chars"
  179. .t config -cursor [::ttk::cursor link]
  180. showStatus [.t index {@%x,%y}]
  181. }
  182. .t tag bind demo <Leave> {
  183. .t tag remove hot 1.0 end
  184. .t config -cursor [::ttk::cursor text]
  185. .statusBar.lab config -text ""
  186. }
  187. .t tag bind demo <Motion> {
  188. set newLine [.t index {@%x,%y linestart}]
  189. if {$newLine ne $lastLine} {
  190. .t tag remove hot 1.0 end
  191. set lastLine $newLine
  192. set tags [.t tag names {@%x,%y}]
  193. set i [lsearch -glob $tags demo-*]
  194. if {$i >= 0} {
  195. .t tag add hot "$lastLine +1 chars" "$lastLine lineend -1 chars"
  196. }
  197. }
  198. showStatus [.t index {@%x,%y}]
  199. }
  200. ##############################################################################
  201. # Create the text for the text widget.
  202. # addFormattedText --
  203. #
  204. # Add formatted text (but not hypertext) to the text widget after first
  205. # passing it through the message catalog to allow for localization.
  206. # Lines starting with @@ are formatting directives (insert title, insert
  207. # demo hyperlink, begin newline, or change style) and all other lines
  208. # are literal strings to be inserted. Substitutions are performed,
  209. # allowing processing pieces through the message catalog. Blank lines
  210. # are ignored.
  211. #
  212. proc addFormattedText {formattedText} {
  213. set style normal
  214. set isNL 1
  215. set demoCount 0
  216. set new 0
  217. foreach line [split $formattedText \n] {
  218. set line [string trim $line]
  219. if {$line eq ""} {
  220. continue
  221. }
  222. if {[string match @@* $line]} {
  223. set data [string range $line 2 end]
  224. set key [lindex $data 0]
  225. set values [lrange $data 1 end]
  226. switch -exact -- $key {
  227. title {
  228. .t insert end [mc $values]\n title \n normal
  229. }
  230. newline {
  231. .t insert end \n $style
  232. set isNL 1
  233. }
  234. subtitle {
  235. .t insert end "\n" {} [mc $values] subtitle \
  236. " \n " demospace
  237. set demoCount 0
  238. }
  239. demo {
  240. set description [lassign $values name]
  241. .t insert end "[incr demoCount]. [mc $description]" \
  242. [list demo demo-$name]
  243. if {$new} {
  244. .t image create end -image ::img::new -padx 5
  245. set new 0
  246. }
  247. .t insert end " \n " demospace
  248. }
  249. new {
  250. set new 1
  251. }
  252. default {
  253. set style $key
  254. }
  255. }
  256. continue
  257. }
  258. if {!$isNL} {
  259. .t insert end " " $style
  260. }
  261. set isNL 0
  262. .t insert end [mc $line] $style
  263. }
  264. }
  265. addFormattedText {
  266. @@title Tk Widget Demonstrations
  267. This application provides a front end for several short scripts
  268. that demonstrate what you can do with Tk widgets. Each of the
  269. numbered lines below describes a demonstration; you can click on
  270. it to invoke the demonstration. Once the demonstration window
  271. appears, you can click the
  272. @@bold
  273. See Code
  274. @@normal
  275. button to see the Tcl/Tk code that created the demonstration. If
  276. you wish, you can edit the code and click the
  277. @@bold
  278. Rerun Demo
  279. @@normal
  280. button in the code window to reinvoke the demonstration with the
  281. modified code.
  282. @@newline
  283. @@subtitle Labels, buttons, checkbuttons, and radiobuttons
  284. @@demo label Labels (text and bitmaps)
  285. @@demo unicodeout Labels and UNICODE text
  286. @@demo button Buttons
  287. @@demo check Check-buttons (select any of a group)
  288. @@demo radio Radio-buttons (select one of a group)
  289. @@demo puzzle A 15-puzzle game made out of buttons
  290. @@demo icon Iconic buttons that use bitmaps
  291. @@demo image1 Two labels displaying images
  292. @@demo image2 A simple user interface for viewing images
  293. @@demo labelframe Labelled frames
  294. @@new
  295. @@demo ttkbut The simple Themed Tk widgets
  296. @@subtitle Listboxes and Trees
  297. @@demo states The 50 states
  298. @@demo colors Colors: change the color scheme for the application
  299. @@demo sayings A collection of famous and infamous sayings
  300. @@new
  301. @@demo mclist A multi-column list of countries
  302. @@new
  303. @@demo tree A directory browser tree
  304. @@subtitle Entries, Spin-boxes and Combo-boxes
  305. @@demo entry1 Entries without scrollbars
  306. @@demo entry2 Entries with scrollbars
  307. @@demo entry3 Validated entries and password fields
  308. @@demo spin Spin-boxes
  309. @@new
  310. @@demo combo Combo-boxes
  311. @@demo form Simple Rolodex-like form
  312. @@subtitle Text
  313. @@demo text Basic editable text
  314. @@demo style Text display styles
  315. @@demo bind Hypertext (tag bindings)
  316. @@demo twind A text widget with embedded windows and other features
  317. @@demo search A search tool built with a text widget
  318. @@new
  319. @@demo textpeer Peering text widgets
  320. @@subtitle Canvases
  321. @@demo items The canvas item types
  322. @@demo plot A simple 2-D plot
  323. @@demo ctext Text items in canvases
  324. @@demo arrow An editor for arrowheads on canvas lines
  325. @@demo ruler A ruler with adjustable tab stops
  326. @@demo floor A building floor plan
  327. @@demo cscroll A simple scrollable canvas
  328. @@new
  329. @@demo knightstour A Knight's tour of the chess board
  330. @@subtitle Scales and Progress Bars
  331. @@demo hscale Horizontal scale
  332. @@demo vscale Vertical scale
  333. @@new
  334. @@demo ttkscale Themed scale linked to a label with traces
  335. @@new
  336. @@demo ttkprogress Progress bar
  337. @@subtitle Paned Windows and Notebooks
  338. @@demo paned1 Horizontal paned window
  339. @@demo paned2 Vertical paned window
  340. @@new
  341. @@demo ttkpane Themed nested panes
  342. @@new
  343. @@demo ttknote Notebook widget
  344. @@subtitle Menus and Toolbars
  345. @@demo menu Menus and cascades (sub-menus)
  346. @@demo menubu Menu-buttons
  347. @@new
  348. @@demo ttkmenu Themed menu buttons
  349. @@new
  350. @@demo toolbar Themed toolbar
  351. @@subtitle Common Dialogs
  352. @@demo msgbox Message boxes
  353. @@demo filebox File selection dialog
  354. @@demo clrpick Color picker
  355. @@subtitle Animation
  356. @@new
  357. @@demo anilabel Animated labels
  358. @@new
  359. @@demo aniwave Animated wave
  360. @@new
  361. @@demo pendulum Pendulum simulation
  362. @@new
  363. @@demo goldberg A celebration of Rube Goldberg
  364. @@subtitle Miscellaneous
  365. @@demo bitmap The built-in bitmaps
  366. @@demo dialog1 A dialog box with a local grab
  367. @@demo dialog2 A dialog box with a global grab
  368. }
  369. ##############################################################################
  370. .t configure -state disabled
  371. focus .s
  372. # addSeeDismiss --
  373. # Add "See Code" and "Dismiss" button frame, with optional "See Vars"
  374. #
  375. # Arguments:
  376. # w - The name of the frame to use.
  377. proc addSeeDismiss {w show {vars {}} {extra {}}} {
  378. ## See Code / Dismiss buttons
  379. ttk::frame $w
  380. ttk::separator $w.sep
  381. #ttk::frame $w.sep -height 2 -relief sunken
  382. grid $w.sep -columnspan 4 -row 0 -sticky ew -pady 2
  383. ttk::button $w.dismiss -text [mc "Dismiss"] \
  384. -image ::img::delete -compound left \
  385. -command [list destroy [winfo toplevel $w]]
  386. ttk::button $w.code -text [mc "See Code"] \
  387. -image ::img::view -compound left \
  388. -command [list showCode $show]
  389. set buttons [list x $w.code $w.dismiss]
  390. if {[llength $vars]} {
  391. ttk::button $w.vars -text [mc "See Variables"] \
  392. -image ::img::view -compound left \
  393. -command [concat [list showVars $w.dialog] $vars]
  394. set buttons [linsert $buttons 1 $w.vars]
  395. }
  396. if {$extra ne ""} {
  397. set buttons [linsert $buttons 1 [uplevel 1 $extra]]
  398. }
  399. grid {*}$buttons -padx 4 -pady 4
  400. grid columnconfigure $w 0 -weight 1
  401. if {[tk windowingsystem] eq "aqua"} {
  402. foreach b [lrange $buttons 1 end] {$b configure -takefocus 0}
  403. grid configure $w.sep -pady 0
  404. grid configure {*}$buttons -pady {10 12}
  405. grid configure [lindex $buttons 1] -padx {16 4}
  406. grid configure [lindex $buttons end] -padx {4 18}
  407. }
  408. return $w
  409. }
  410. # positionWindow --
  411. # This procedure is invoked by most of the demos to position a new demo
  412. # window.
  413. #
  414. # Arguments:
  415. # w - The name of the window to position.
  416. proc positionWindow w {
  417. wm geometry $w +300+300
  418. }
  419. # showVars --
  420. # Displays the values of one or more variables in a window, and updates the
  421. # display whenever any of the variables changes.
  422. #
  423. # Arguments:
  424. # w - Name of new window to create for display.
  425. # args - Any number of names of variables.
  426. proc showVars {w args} {
  427. catch {destroy $w}
  428. toplevel $w
  429. if {[tk windowingsystem] eq "x11"} {wm attributes $w -type dialog}
  430. wm title $w [mc "Variable values"]
  431. set b [ttk::frame $w.frame]
  432. grid $b -sticky news
  433. set f [ttk::labelframe $b.title -text [mc "Variable values:"]]
  434. foreach var $args {
  435. ttk::label $f.n$var -text "$var:" -anchor w
  436. ttk::label $f.v$var -textvariable $var -anchor w
  437. grid $f.n$var $f.v$var -padx 2 -pady 2 -sticky w
  438. }
  439. ttk::button $b.ok -text [mc "OK"] \
  440. -command [list destroy $w] -default active
  441. bind $w <Return> [list $b.ok invoke]
  442. bind $w <Escape> [list $b.ok invoke]
  443. grid $f -sticky news -padx 4
  444. grid $b.ok -sticky e -padx 4 -pady {6 4}
  445. if {[tk windowingsystem] eq "aqua"} {
  446. $b.ok configure -takefocus 0
  447. grid configure $b.ok -pady {10 12} -padx {16 18}
  448. grid configure $f -padx 10 -pady {10 0}
  449. }
  450. grid columnconfig $f 1 -weight 1
  451. grid rowconfigure $f 100 -weight 1
  452. grid columnconfig $b 0 -weight 1
  453. grid rowconfigure $b 0 -weight 1
  454. grid columnconfig $w 0 -weight 1
  455. grid rowconfigure $w 0 -weight 1
  456. }
  457. # invoke --
  458. # This procedure is called when the user clicks on a demo description. It is
  459. # responsible for invoking the demonstration.
  460. #
  461. # Arguments:
  462. # index - The index of the character that the user clicked on.
  463. proc invoke index {
  464. global tk_demoDirectory
  465. set tags [.t tag names $index]
  466. set i [lsearch -glob $tags demo-*]
  467. if {$i < 0} {
  468. return
  469. }
  470. set cursor [.t cget -cursor]
  471. .t configure -cursor [::ttk::cursor busy]
  472. update
  473. set demo [string range [lindex $tags $i] 5 end]
  474. uplevel 1 [list source [file join $tk_demoDirectory $demo.tcl]]
  475. update
  476. .t configure -cursor $cursor
  477. .t tag add visited "$index linestart +1 chars" "$index lineend -1 chars"
  478. }
  479. # showStatus --
  480. #
  481. # Show the name of the demo program in the status bar. This procedure is
  482. # called when the user moves the cursor over a demo description.
  483. #
  484. proc showStatus index {
  485. set tags [.t tag names $index]
  486. set i [lsearch -glob $tags demo-*]
  487. set cursor [.t cget -cursor]
  488. if {$i < 0} {
  489. .statusBar.lab config -text " "
  490. set newcursor [::ttk::cursor text]
  491. } else {
  492. set demo [string range [lindex $tags $i] 5 end]
  493. .statusBar.lab config -text [mc "Run the \"%s\" sample program" $demo]
  494. set newcursor [::ttk::cursor link]
  495. }
  496. if {$cursor ne $newcursor} {
  497. .t config -cursor $newcursor
  498. }
  499. }
  500. # evalShowCode --
  501. #
  502. # Arguments:
  503. # w - Name of text widget containing code to eval
  504. proc evalShowCode {w} {
  505. set code [$w get 1.0 end-1c]
  506. uplevel #0 $code
  507. }
  508. # showCode --
  509. # This procedure creates a toplevel window that displays the code for a
  510. # demonstration and allows it to be edited and reinvoked.
  511. #
  512. # Arguments:
  513. # w - The name of the demonstration's window, which can be used to
  514. # derive the name of the file containing its code.
  515. proc showCode w {
  516. global tk_demoDirectory
  517. set file [string range $w 1 end].tcl
  518. set top .code
  519. if {![winfo exists $top]} {
  520. toplevel $top
  521. if {[tk windowingsystem] eq "x11"} {wm attributes $top -type dialog}
  522. set t [frame $top.f]
  523. set text [text $t.text -font fixedFont -height 24 -wrap word \
  524. -xscrollcommand [list $t.xscroll set] \
  525. -yscrollcommand [list $t.yscroll set] \
  526. -setgrid 1 -highlightthickness 0 -pady 2 -padx 3]
  527. scrollbar $t.xscroll -command [list $t.text xview] -orient horizontal
  528. scrollbar $t.yscroll -command [list $t.text yview] -orient vertical
  529. grid $t.text $t.yscroll -sticky news
  530. #grid $t.xscroll
  531. grid rowconfigure $t 0 -weight 1
  532. grid columnconfig $t 0 -weight 1
  533. set btns [ttk::frame $top.btns]
  534. ttk::separator $btns.sep
  535. grid $btns.sep -columnspan 4 -row 0 -sticky ew -pady 2
  536. ttk::button $btns.dismiss -text [mc "Dismiss"] \
  537. -default active -command [list destroy $top] \
  538. -image ::img::delete -compound left
  539. ttk::button $btns.print -text [mc "Print Code"] \
  540. -command [list printCode $text $file] \
  541. -image ::img::print -compound left
  542. ttk::button $btns.rerun -text [mc "Rerun Demo"] \
  543. -command [list evalShowCode $text] \
  544. -image ::img::refresh -compound left
  545. set buttons [list x $btns.rerun $btns.print $btns.dismiss]
  546. grid {*}$buttons -padx 4 -pady 4
  547. grid columnconfigure $btns 0 -weight 1
  548. if {[tk windowingsystem] eq "aqua"} {
  549. foreach b [lrange $buttons 1 end] {$b configure -takefocus 0}
  550. grid configure $btns.sep -pady 0
  551. grid configure {*}$buttons -pady {10 12}
  552. grid configure [lindex $buttons 1] -padx {16 4}
  553. grid configure [lindex $buttons end] -padx {4 18}
  554. }
  555. grid $t -sticky news
  556. grid $btns -sticky ew
  557. grid rowconfigure $top 0 -weight 1
  558. grid columnconfig $top 0 -weight 1
  559. bind $top <Return> {
  560. if {[winfo class %W] ne "Text"} { .code.btns.dismiss invoke }
  561. }
  562. bind $top <Escape> [bind $top <Return>]
  563. } else {
  564. wm deiconify $top
  565. raise $top
  566. }
  567. wm title $top [mc "Demo code: %s" [file join $tk_demoDirectory $file]]
  568. wm iconname $top $file
  569. set id [open [file join $tk_demoDirectory $file]]
  570. $top.f.text delete 1.0 end
  571. $top.f.text insert 1.0 [read $id]
  572. $top.f.text mark set insert 1.0
  573. close $id
  574. }
  575. # printCode --
  576. # Prints the source code currently displayed in the See Code dialog. Much
  577. # thanks to Arjen Markus for this.
  578. #
  579. # Arguments:
  580. # w - Name of text widget containing code to print
  581. # file - Name of the original file (implicitly for title)
  582. proc printCode {w file} {
  583. set code [$w get 1.0 end-1c]
  584. set dir "."
  585. if {[info exists ::env(HOME)]} {
  586. set dir "$::env(HOME)"
  587. }
  588. if {[info exists ::env(TMP)]} {
  589. set dir $::env(TMP)
  590. }
  591. if {[info exists ::env(TEMP)]} {
  592. set dir $::env(TEMP)
  593. }
  594. set filename [file join $dir "tkdemo-$file"]
  595. set outfile [open $filename "w"]
  596. puts $outfile $code
  597. close $outfile
  598. switch -- $::tcl_platform(platform) {
  599. unix {
  600. if {[catch {exec lp -c $filename} msg]} {
  601. tk_messageBox -title "Print spooling failure" \
  602. -message "Print spooling probably failed: $msg"
  603. }
  604. }
  605. windows {
  606. if {[catch {PrintTextWin32 $filename} msg]} {
  607. tk_messageBox -title "Print spooling failure" \
  608. -message "Print spooling probably failed: $msg"
  609. }
  610. }
  611. default {
  612. tk_messageBox -title "Operation not Implemented" \
  613. -message "Wow! Unknown platform: $::tcl_platform(platform)"
  614. }
  615. }
  616. #
  617. # Be careful to throw away the temporary file in a gentle manner ...
  618. #
  619. if {[file exists $filename]} {
  620. catch {file delete $filename}
  621. }
  622. }
  623. # PrintTextWin32 --
  624. # Print a file under Windows using all the "intelligence" necessary
  625. #
  626. # Arguments:
  627. # filename - Name of the file
  628. #
  629. # Note:
  630. # Taken from the Wiki page by Keith Vetter, "Printing text files under
  631. # Windows".
  632. # Note:
  633. # Do not execute the command in the background: that way we can dispose of the
  634. # file smoothly.
  635. #
  636. proc PrintTextWin32 {filename} {
  637. package require registry
  638. set app [auto_execok notepad.exe]
  639. set pcmd "$app /p %1"
  640. catch {
  641. set app [registry get {HKEY_CLASSES_ROOT\.txt} {}]
  642. set pcmd [registry get \
  643. {HKEY_CLASSES_ROOT\\$app\\shell\\print\\command} {}]
  644. }
  645. regsub -all {%1} $pcmd $filename pcmd
  646. puts $pcmd
  647. regsub -all {\\} $pcmd {\\\\} pcmd
  648. set command "[auto_execok start] /min $pcmd"
  649. eval exec $command
  650. }
  651. # tkAboutDialog --
  652. #
  653. # Pops up a message box with an "about" message
  654. #
  655. proc tkAboutDialog {} {
  656. tk_messageBox -icon info -type ok -title [mc "About Widget Demo"] \
  657. -message [mc "Tk widget demonstration application"] -detail \
  658. "[mc {Copyright (c) %s} {1996-1997 Sun Microsystems, Inc.}]
  659. [mc {Copyright (c) %s} {1997-2000 Ajuba Solutions, Inc.}]
  660. [mc {Copyright (c) %s} {2001-2007 Donal K. Fellows}]
  661. [mc {Copyright (c) %s} {2002-2007 Daniel A. Steffen}]"
  662. }
  663. # Local Variables:
  664. # mode: tcl
  665. # End: