# -*- tcl -*-

slide "An Introduction to Tcl/Tk" {

    drawtitle $title

    centeritem 2 "Stephen Edwards"

    centeritem 3 "Berkeley CAD Group"

    centeritem 5 "CAD Seminar, 950118"

    centeritem 8 "Press the space bar to advance"

}

##############################

proc setpoints {} {
    global points inc
    global centerx centery r rmod go1 go2

    set c ""

    set o1 $go1
    set o2 $go2

    set r1 [expr $r + $rmod * cos($o2)]
    set r2 [expr $r - $rmod * cos($o2)]

    for {set i 0} { $i < $points } { incr i } {
	lappend c [expr $centerx + $r1 * cos($o1)] [expr $centery + $r1 * sin($o1)] [expr $centerx + $r2 * cos($o1 + $inc)] [expr $centery + $r2 * sin($o1 + $inc)]
	set o1 [expr $o1 + $inc * 2.0]
    }
    eval .c coords spinit $c
}

proc spin {} {
    global go1 go2
    if {[.c find withtag spinit]!=""} {
	set go1 [expr $go1 + 0.1]
	set go2 [expr $go2 + 0.1]
	setpoints
	after 50 spin
    }
}

slide "Thesis" {
    global go1 go2
    global points inc r rmod

    .c create polygon 10 10 20 20 40 10 -fill white -tags spinit

    centeritem 2 "Your programs can benefit from

the use of Tcl/Tk


You should use it"

    set points 10
    set inc [expr 3.141592653579323  / $points]
    set r 200
    set rmod 150

    set go1 0
    set go2 0

    spin

}

##############################

titledslide "All interesting programs interact with people or other programs"
part { starttext ; addtext {
Command-line interfaces:

{tt   ls -AFC /tmp}
{tt   find . -name espresso -print}
}}
part { addtext {
Command languages:

{ttred   vivaldi 101: }{tt gnuplot}
{ttred   gnuplot> }{tt set xrange [0:10]}
{ttred   gnuplot> }{tt set yrange [-1:1]}
{ttred   gnuplot> }{tt plot sin(x)}
}}
part { addtext {
Graphical User Interfaces (GUIs):

   Mosaic, netscape
   PowerPoint
   FrameMaker
}}
part { addtext {
GUIs with languages:

   Emacs
   Apple's Hypercard
   Cadence's framework
}}

##############################

titledslide "Tcl and Tk provide an easy way to build interactive programs"

part { starttext ; addtext "
{symbol \xb7} Tcl is an interpreted scripting language easily added to a program

"
addtext {{tt   set f [[open lindex $argv 1] r]
  while \{ [gets $f line] >= 0 \} \{ puts $line \}}

}
}

part {

addtext "
{symbol \xb7} Tk is collection of Tcl commands implementing widgets like menus, entries, and scrollbars for the X window system
"

global bigfont cursor
global cmd

set cmd "This is a text entry widget too large for its region"
frame .ex -cursor $cursor
place .ex -relx 0.5 -rely 0.75 -width 500 -anchor c

entry .ex.e -width 10 -relief sunken -bd 5 -font $bigfont \
  -scroll ".ex.sb set" -cursor $cursor -textvariable cmd


scrollbar .ex.sb -orient horiz -width 30 -cursor $cursor -command ".ex.e view"
pack .ex.sb -fill x -side bottom
pack .ex.e -fill x -side bottom

menubutton .ex.mb -text "File" -menu .ex.mb.m -font $bigfont -cursor $cursor
pack .ex.mb -side left -padx 20 -pady 20
menu .ex.mb.m -font $bigfont -cursor $cursor
.ex.mb.m add command -label "Open" -accelerator "C-o"
.ex.mb.m add command -label "Save" -accelerator "C-s"
.ex.mb.m add command -label "Save As..."
.ex.mb.m add command -label "Close" -accelerator "C-c"
.ex.mb.m add sep
.ex.mb.m add command -label "Quit" -accelerator "C-q"

menubutton .ex.mb2 -text "Edit" -font $bigfont -cursor $cursor
pack .ex.mb2 -side left -padx 20 -pady 20

}

##############################

titledslide "One way to use Tcl/Tk is to write a script"

part { starttext ; addtext "
{symbol \xb7} Easiest way for small programs

{symbol \xb7} Like writing a script for {tt csh}, {tt awk}, {tt perl}, etc.

{symbol \xb7} Does not use Tcl's ability to be embedded

{symbol \xb7} No compile/link step necessary: development time reduced

{symbol \xb7} Run it using one of the standard shells:

   Tcl only {symbol \xae} use {tt tclsh}
   Tcl and Tk {symbol \xae} use {tt wish}

{symbol \xb7} Can be run on many platforms
"}

##############################

titledslide "A few lines of Tcl can do a lot"

part { starttext ; addtext {This Tcl script emulates {tt grep}:

{tt  #!/usr/local/bin/tclsh

 if \{ $argc != 2 \} \{
   error "Usage: tgrep pattern fileName"
 \}

 set f [open [lindex $argv 1] r]

 set pat [lindex $argv 0]

 while \{ [gets $f line ] >= 0 \} \{
   if [regexp $pat $line] \{ puts $line \}
 \}

 close $f

}}}

##############################

titledslide "A few lines of Tcl with Tk make a graphical application"

part { starttext ; addtext {
This creates buttons that, when pressed, repeat previously-entered commands:

{tt #!/usr/local/bin/wish -f

set id 0
entry .entry -width 30 -relief sunken \\
  -textvariable cmd
pack .entry -padx 1m -pady 1m
bind .entry <Return> \{
  incr id
  button .b$id -text $cmd \\
    -command "exec <@stdin >@stdout $cmd"
  pack .b$id -fill x -ipady 10
  .b$id invoke
  .entry delete 0 end
\}
}
}
}

part {
  global bigfont cursor
  global id
  global cmd

  set cmd ""

  set id 0
  toplevel .ex
  entry .ex.entry -width 30 -relief sunken -bd 5 -font $bigfont -textvariable cmd -cursor $cursor
  pack .ex.entry -padx 10 -pady 10
  bind .ex.entry <Control-c> {destroy .ex}
  bind .ex.entry <Return> {
    incr id
    button .ex.b$id -text $cmd -font $bigfont -bd 5 -cursor $cursor
    pack .ex.b$id -fill x -ipady 20
    .ex.entry delete 0 end
  }
  focus .ex.entry
  tkwait window .ex

}

##############################

titledslide "Tcl/Tk's real strength lies in extending these shells"

part { starttext ; addtext "
1.  Write, in C, new application-specific Tcl commands

2.  Link these with Tcl/Tk libraries to produce a custom shell

3.  Write a script for this shell
"}

part { addtext "

This framework produces interactive graphical applications easily.  The ideas:

{symbol \xb7} Interpreted scripts for user interface and ``glue''
  {symbol \xae} Rapid development with very high-level constructs

{symbol \xb7} Custom C code for speed-critical or data-intensive tasks
  {symbol \xae} Speed and power when you need it
"}

##############################

titledslide "Tcl's C interface is simple"

part { starttext ; addtext {This compares its two arguments for equality:

{tt int EqCmd( ClientData clientData,
  Tcl_Interp *interp,
  {ttred int argc, char *argv[]}) \{

  if ( argc != 3 ) \{
    interp->result = "wrong # args";
    return TCL_ERROR;
  \}

  if (strcmp(argv[1], argv[2]) == 0 ) \{
    interp->result = "1";
  \} else \{
    interp->result = "0";
  \}
  return TCL_OK;
 \}}
}}

##############################

titledslide "Examples of Tcl/Tk applications"

part { starttext ; addtext "
{symbol \xb7} These slides are a 1300-line {tt wish} script

{symbol \xb7} My {tt states} editor is a 2100-line {tt wish} script

{symbol \xb7} Ptolemy and Hyper both use Tcl/Tk

{symbol \xb7} {tt ical}, a Tcl/Tk C++ hybrid
   3100 lines of C++
   5200 lines of Tcl/Tk

{symbol \xb7} The commercial presentation package {i Perspecta Presents!}
   29k lines of C (one new widget, thirty new Tcl commands)
   11k lines of Tcl/Tk
"}

##############################

titledslide "Having an interpreted language around is useful"

part { starttext ; addtext "

{symbol \xb7} File formats are easy: save as a Tcl script.
   Execute this to reload.

{symbol \xb7} Undo/redo can be implemented by saving Tcl commands and reevaluating them as necessary

{symbol \xb7} Pass complex data through a Tcl script

"}

##############################

slide "Status" {

  outlinelist { "Introduction"
	"Details of the Tcl language"
	"Details of the Tk toolkit"
	"Conclusions" } 1
}

part { nextsection }

##############################

titledslide "Tcl is a shell language sporting many high-level constructs"

part { starttext ; addtext "
{symbol \xb7} Invoke commands with arguments separated by spaces:
{tti 
  commandName arg1 arg2 ... argn}
"}

part { addtext "
{symbol \xb7} Local and Global Variables:

    {symbol \xd7} local variables are created automatically when referred to
    {symbol \xd7} global variables must be declared, e.g., {tt global foo}
"}

part { addtext "
{symbol \xb7} Substitution Rules:
"
addtext {{tt 
  set a $b
  set a [expr $b + 2]
  if \{$a < 0\} \{ puts "a is negative" \}
}}}

part { addtext "
{symbol \xb7} Numeric Expressions:
"
addtext {{tt 
  expr 5 + 6
{ttred     11}
  expr sqrt(2)
{ttred     1.41421}
  expr $a < $b ? sin($a) : (cos($b) + 2.75)
}}}

part { addtext "
{symbol \xb7} Conditionals and Loops:

    {tt if else}
    {tt while}
    {tt switch}
    {tt for       } {i Like C's}
    {tt foreach   } {i Iterate through a list}
    {tt eval      } {i Execute a script in a string}
"}

part { addtext "
{symbol \xb7} Strings:

"
addtext {{tt  format "%s is %d years old" $name $age}
{ttred    Stephen is 5 years old}
{tt  scan $s "%d units %f" a b
 regexp \{^[Ff]oo\} $s}
}
}

part { addtext "
{symbol \xb7} Lists:

"
addtext { {tt  lindex \{a \{b \{a b\} c\} \{d e\} f\} 2}
{ttred    \{d e\}}
}
}

part { addtext "
{symbol \xb7} File Access:
"
addtext { {tt 
  set f [open /tmp/foo w]
  puts $f "To foo"
  close $f
}}
}

part { addtext "
{symbol \xb7} Subprocesses:
"
addtext { {tt 
  exec rm /tmp/foo
  exec make clean &
}}}

##############################

titledslide "The string is Tcl's universal data type"

part { starttext ; addtext "
{symbol \xb7} Arguments to commands are strings

{symbol \xb7} Commands return a string as their result

{symbol \xb7} Variables store strings

{symbol \xb7} Strings may be interpreted as

   Character strings
   Floating point numbers
   Lists
   Filenames
   Tcl scripts

   Type conversion is implicit
"}

##############################

titledslide "Tcl procedures allow defaults and a variable number of arguments"

part { starttext ; addtext {
Simple procedure:

{tt   proc plus \{a b\} \{expr $a + $b\}

  plus 5 6
    {ttred 11}
}}}

part { addtext {
Procedure with defaults:

{tt   proc inc \{a \{b 1\}\} \{expr $a + $b\}

  inc 7
    {ttred 8}
  inc 7 2
    {ttred 9}
}}}

part { addtext {
Procedure with variable arguments:

{tt   proc sum args \{
    set s 0
    foreach i $args \{ incr s $i \}
    return $s
  \}

  sum 1 2 3 4 5
    {ttred 15}
}}}

##############################

titledslide "Tcl supports associative arrays"

part { starttext ; addtext {
Arrays may be indexed by arbitrary strings:
{tt 
  set foo(bar) true

  set foo(5) false

  puts $foo(bar)
    {ttred true}

  puts $foo(5)
    {ttred false}
}
}}

##############################

titledslide "Tcl supports ``variable traces''"

part { starttext ; addtext {
These invoke the command {tti varProc} whenever the variable is read, written, or unset (deleted):
{tt 
trace variable {tti variableName} r {tti varProc}
trace variable {tti variableName} w {tti varProc}
trace variable {tti variableName} u {tti varProc}}

This facility is useful for imposing constraints among things
}}

##############################

slide "Status" {

  outlinelist { "Introduction"
	"Details of the Tcl language"
	"Details of the Tk toolkit"
	"Conclusions" } 2
}

part { nextsection }

##############################

titledslide "Tk is a set of Tcl commands for manipulating ``widgets''"

part { starttext ; addtext {
Widgets, such as buttons, are given a name when created:

{tt  button .b -text "Press Me" -command "destroy ."}

and then must be ``packed'' to become visible:

{tt  pack .b}

}}

part {
global bigfont cursor

toplevel .ex

button .ex.b -text "Press Me" -font $bigfont -cursor $cursor -bd 10 -command "destroy .ex"
pack .ex.b -ipadx 20 -ipady 20

}

##############################

titledslide "Tk has many widgets"

part {
starttext ; addtext {
{i Create a top-level window (widget) named }{tt .ex}:
{tt   toplevel .ex}
}
  global bigfont cursor

  toplevel .ex -geometry 100x100 -cursor $cursor

  button .ex.b -text "A button" -font $bigfont -bd 5 -cursor $cursor
  scrollbar .ex.s -width 30 -orient horiz -command ".ex.e view" -cursor $cursor
  entry .ex.e -width 10 -relief sunken -bd 5 -font $bigfont \
	-scroll ".ex.s set" -cursor $cursor

  canvas .ex.c -relief raised -bd 5 -cursor $cursor
  .ex.c create polygon 10 10 100 100 200 10 \
	200 200 75 100
  .ex.c create text 50 200 -text "wow" -font $bigfont -fill red

}

part {
global bigfont
addtext {
{i Create a button:}
{tt   button .ex.b -text "A button"
  pack .ex.b}
}
  pack .ex.b -ipadx 10 -ipady 5 -padx 20 -pady 5
}

part { addtext {
{i Create an entry for entering text:}
{tt   entry .ex.e -scroll ".ex.s set"
  pack .ex.e}
}
  pack .ex.e -padx 5 -pady 5 -ipadx 5 -ipady 5
}

part { addtext {
{i Create a scrollbar controlling the entry widget:}
{tt   scrollbar .ex.s -command ".ex.e view"
  pack .ex.s}
}
  pack .ex.s -padx 5 -pady 5 -fill x
}

part { addtext {
{i Create a canvas and draw a polygon and some text on it:}
{tt   canvas .ex.c
  .ex.c create polygon 10 10 100 100 200 10 \\
     200 200 75 100
  .ex.c create text 50 200 -text "wow" -fill red
  pack .ex.c
}}

pack .ex.c -padx 5 -pady 5

}

##############################

titledslide "A Tk application has initialization code and event handlers"

part { starttext ; addtext "
{symbol \xb7} Initialization code builds windows by assembling widgets:

{tt   button .b -text \"Press Me\"
  menu .m
  scrollbar .sb -orient horiz
  pack .b .m .sb}

{symbol \xb7} Event handlers are Tcl scripts {i bound} to events - invoked because of an event

{tt   bind .m <B1-Motion> \\\{puts \"what a drag\"\\\}

  bind . <Control-c> \"destroy .\"

  button .b -text \"Press Me\"
    -command \\\{puts \"Ouch!\"\\\}}
"}

##############################

titledslide "Widgets are arranged hierarchically"

part { starttext ; addtext "
Each widget has a name like {tt .b}, {tt .top.button}, etc.

The names are like unix filenames, but with periods instead of slashes.
"}

part {
global courierfont cursor
toplevel .ex -background black
wm minsize .ex 20 20
wm geometry .ex 400x200

label .ex.dot -text "." -font $courierfont -cursor $cursor
label .ex.a -text ".a" -font $courierfont -cursor $cursor
label .ex.b -text ".b" -font $courierfont -cursor $cursor

pack .ex.dot -padx 10 -pady 10 -ipadx 10 -ipady 10 -fill both -expand y
}

part {
destroy .ex.dot
pack .ex.a -padx 10 -pady 10 -ipadx 10 -ipady 10 -fill both -expand y
pack .ex.b -side bottom -padx 10 -pady 10 -ipadx 10 -ipady 10 -fill both -expand y
}

part {
global courierfont cursor
destroy .ex.a
frame .ex.a
pack .ex.a -padx 10 -pady 10 -fill both -expand y

label .ex.a.a -text ".a.a" -font $courierfont -cursor $cursor -background red
label .ex.a.b -text ".a.b" -font $courierfont -cursor $cursor -background red
pack .ex.a.a -side left -padx 10 -pady 5 -ipadx 10 -ipady 10 -fill both -expand y
pack .ex.a.b -side left -padx 10 -pady 5 -ipadx 10 -ipady 10 -fill both -expand y
}

##############################

titledslide "Widgets have defaults overridable with arguments"
part { starttext ; addtext {
A simple button

{tt  button .b -text "Press Me"}

An elaborate button

{tt  button .b -text "Press Me" \\    {i button's label}
   -bd 10 \\                      {i size of border}
   -padx 5 -pady 5 \\             {i space between}
                                  {i label and border}
   -command "buttonPressed pm" \\ {i executed when}
                                  {i button is pressed}
   -cursor hand1                 {i cursor to display}
                                  {i when pointer}
                                  {i inside button}}
}}

##############################

titledslide "Widgets have an object-oriented interface"

part { starttext ; addtext {
Once defined, methods can be invoked on a widget:

{i Create it}

{tt   button .b -text "Button's First Label"

{i Change its label}

  .b config -text "Button's New Label"

{i Cause a button press}

  .b invoke

{i Prevent a button from being pressed}

  .b deactivate
}
}}

##############################

titledslide "Tk arranges widgets using the packer"

part { starttext ; addtext "
{symbol \xb7} Widgets know how to draw themselves, but don't know where to draw themselves.

{symbol \xb7} The packer controls where groups of widgets are drawn

{symbol \xb7} Slave widgets are placed within their master, starting from the outside in

"
}

part {
addtext "By default, the widget is packed onto the top
{tt  pack .a}

"
toplevel .ex -background black
wm minsize .ex 20 20
wm geometry .ex 400x400+50+20

frame .ex.a -background red -geometry 200x50
pack .ex.a
}

part {
addtext "The fill option makes the widget consume the available space
{tt  pack .b -fill x}

"
frame .ex.b -background slateblue -geometry 200x50
pack .ex.b -fill x
}

part {
addtext "The anchor option sets where the widget touches its boundary
{tt  pack .c -anchor w}

"
frame .ex.c -background yellow -geometry 200x50
pack .ex.c -anchor w
}

part {
addtext "The side option controls where the widget takes its space
{tt  pack .d -side left}

"
frame .ex.d -background slateblue -geometry 50x200
pack .ex.d -side left
}

part {
addtext "These options can be combined
{tt  pack .e -side left -anchor s}

"
frame .ex.e -background green -geometry 50x200
pack .ex.e -side left -anchor s
}

part {
addtext "The expand option allows the widget to consume extra space
{tt  pack .f -fill both -expand y}

"
frame .ex.f -background grey
pack .ex.f -fill both -expand y
}

part {
addtext "The packer can handle multiple levels of hierarchy
{tt   pack .f.a
  pack .f.b -fill x
  pack .f.c -anchor w
  pack .f.d -side left
  pack .f.e -side left -anchor s
  pack .f.f -fill both -expand y}
"

frame .ex.f.a -background red -geometry 100x25
frame .ex.f.b -background slateblue -geometry 100x25
frame .ex.f.c -background yellow -geometry 100x25
frame .ex.f.d -background slateblue -geometry 25x100
frame .ex.f.e -background green -geometry 25x100
frame .ex.f.f -background white

pack .ex.f.a
pack .ex.f.b -fill x
pack .ex.f.c -anchor w
pack .ex.f.d -side left
pack .ex.f.e -side left -anchor s
pack .ex.f.f -fill both -expand y

}

##############################

titledslide "The text widget is a full-fledged text editor"
part {
  global cursor bigfont

 starttext ; addtext {
This window is a bare text widget:

{tt text .t -wrap word
pack .t}
}

  toplevel .ex -cursor $cursor
  wm geometry .ex +470+260

  text .ex.t -font $bigfont -height 10 -width 20 -wrap word -cursor $cursor
  pack .ex.t
  focus .ex.t
}

##############################

titledslide "The canvas widget is almost a drawing program"
part {

  starttext ; addtext {This window is a canvas widget with two bindings
}

  global cursor

  toplevel .ex -cursor $cursor
  wm geometry .ex +480+220

  canvas .ex.c -cursor $cursor -height 400 -width 400
  pack .ex.c

  bind .ex.c <1> { set lastx %x ; set lasty %y
      if { [.ex.c find withtag current] == "" } {
	  .ex.c create oval %x %y \
	      [expr %x + 40] [expr %y + 40] \
	      -fill red -outline black -width 5
      }
  }

  bind .ex.c <B1-Motion> {
    .ex.c move current [expr %x - $lastx] [expr %y - $lasty]
    set lastx %x ; set lasty %y
  }
}

part { destroy .ex ; addtext {
{tt   canvas .c
  pack .c

  bind .c <1> \{ set lastx %x ; set lasty %y
      if \{ [.c find withtag current] == "" \} \{
	  .c create oval %x %y \\
	      [expr %x + 40] [expr %y + 40] \\
	      -fill red -outline black
      \}
  \}

  bind .c <B1-Motion> \{
    .c move current [expr %x - $lastx] \\
          [expr %y - $lasty]
    set lastx %x ; set lasty %y
  \}
}
}}

##############################

titledslide "Tk's ``send'' command supports interapplication communication"

part { starttext ; addtext "
{symbol \xb7} This sends a command to another Tcl interpreter (shell), which executes it:

{tt   send }{tti appName command}

{symbol \xb7} Limited, but a step in the right direction

{symbol \xb7} This sort of thing can be a gigantic security hole.  E.g., anybody could send

{tt   send foo \"exec rm -rf ~\"}

  Some security exists (i.e., xauth), but is a blunt instrument

"}

##############################

slide "Status" {

  outlinelist { "Introduction"
	"Details of the Tcl language"
	"Details of the Tk toolkit"
	"Conclusions" } 3
}

part { nextsection }

##############################

titledslide "Tcl/Tk is better than other approaches"

part { starttext ; addtext "
{symbol \xb7} {i Motif} under X

  {i C-based library with many widgets}

  + Attractive, thoughtfully-designed widgets
  + Very flexible
  - Low-level, requires many lines of code
  - Compile/link paradigm, no interpreter
  - Expensive, proprietary
"}

part { addtext "
{symbol \xb7} {i Visual BASIC} on Windows

  {i Direct-manipulation interface assembles widgets with attached BASIC code }

  + Has many of the same widgets
  - Does not have a canvas widget
  - No ``packer'' for geometry management
  - Underlying language is BASIC, no interpreter
  - Affordable, but from that company in Redmond, WA
"}

part { addtext "
{symbol \xb7} {i Hypercard} on the Mac

  {i Page-based direct manipulation interface with hypertext facilities}

  + Card metaphor simple"
addtext "
  - Few ``widgets''
  - Few different applications possible
  - Scripting language weak
  + Widely available
"}


##############################

titledslide "Tcl and Tk are not perfect, but are the best so far"

part { starttext ; addtext "
Problems:

  {symbol \xb7} Typeless variables and parameters enables bugs

  {symbol \xb7} Missing important high-level widgets (file dialogs, printing)

  {symbol \xb7} Not enough standardization

  {symbol \xb7} {tt send} a good idea, but too primitive to be very useful

  {symbol \xb7} Simple data types make large programs infeasible
      {tt \[incr Tcl\]} extension some help

  {symbol \xb7} It's too tempting to turn little programs into big ones

"}

##############################

titledslide "Recap"

part { starttext ; addtext "

{symbol \xb7} Tcl is an embeddable scripting language

{symbol \xb7} Tk is a set of object-oriented user-interface widgets accessible from Tcl

{symbol \xb7} One way to use Tcl/Tk is to write a script for a standard shell: {tt tclsh} or {tt wish}

{symbol \xb7} Tcl can easily be embedded into a program and extended

{symbol \xb7} Having an interpreted language around is helpful
"}

##############################

titledslide "We should consider writing a Tcl interface to the MDD package"

part { starttext ; addtext "

{symbol \xb7} Our algorithms are well-described by high-level operations

{symbol \xb7} Developing and testing algorithms would be faster

   {symbol \xd7} no compile/link cycle

   {symbol \xd7} smaller programs; fewer lines to debug
"}

##############################

titledslide "We should consider adding Tcl/Tk to HSIS"

part { starttext ; addtext "

{symbol \xb7} The existing command language is primitive

{symbol \xb7} Tcl's C interface is similar to the existing one

{symbol \xb7} Many new functions could be implemented as scripts, saving development time
"}

##############################

titledslide "To learn more, mimic examples and read Ousterhout's book"

part { starttext ; addtext "
The widget demo, part of the Tk distribution, has examples of nearly everything

{tt /usr/sww/tcl/lib/tk/demos/widget}

Ousterhout's book, {i Tcl and the Tk Toolkit} (Addison-Wesley, 1994), is a necessity.  It's well-written and widely available.

Detailed information about each widget is available from the man pages supplied with Tk.
"}

##############################

titledslide "The best way to learn Tcl/Tk is to pick a little problem and solve it using Tcl/Tk"

part { starttext ; addtext "
{symbol \xb7} I believe this applies to learning any programming language

{symbol \xb7} Think of some little utility you need - something that would make your life easier - and write it using {tt wish}
"}

##############################

titledslide "Tcl/Tk is in the public domain, and has a rapidly-growing user community"

part { starttext ; addtext "
{symbol \xb7} There is a large WWW-accessible archive of many Tcl/Tk programs and extensions

{symbol \xb7} We will be seeing many more Tcl/Tk applications in the future
"}

##############################

titledslide "Your programs can benefit from the use of Tcl/Tk; you should use it"

part { starttext ; addtext "
{symbol \xb7} In the future, most things will have graphical user interfaces.

    Tcl/Tk makes them easy to build

{symbol \xb7} Shifting toward higher-level languages like Tcl accelerates development and makes for more intelligent programs
"}

