widget 23 KB

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