flashCards.tcl -A Simple FlashCard Teaching Utility


 # flashCards.tcl
 # Interactive language teaching tool.
 # Created by William J Giddings
 # 28-October-2007
 # Designed to run with gnocl-0.9.91
 # http://www.dr-baum.net/gnocl/index.html
 # Notes:
 # 1) Extensive use is made of variables in the global context, 
 #    I know its bad programming but its quick!
 # 2) gnocl::text widgets have been used to display text,
 #    gnocl::entries could have been used, but this gnocl version
 #    only supports the default font specified in the gnome theme.
 # 3) The font used to display Hanzi, (chinese text) is SimSun.
 #    In Linux This may need to be copied to the users fonts directory
 #    for the script to work. Alternatively, remove the -fontFamily
 #    option in line 69 to use Linux default font.
 # More Chinese fonts available at:
 # http://www.sino.uni-heidelberg.de/edv/sinopc/chinese_fonts.htm

 # the next line restarts using tclsh \
 exec tclsh "$0" "[email protected]"

 package require Gnocl

 # set a default pack of cards
 # to make a new pack simply edit the the values below and resave 
 set ::pack "Lesson 2) Introductions"     ;# also functions as window title
 set ::wordlist {
   {贵姓 {guìxìng} {May I ask your name?} }
   {姓 {xìng} {surname } }
   {来 {lái} {to come} }
   {介绍 {jièshào} {to introduce} }
   {一下 {yíxià} {(verbal measure word) time(s) }}
   {这 {zhè} {this} }
   {位 {wèi} {polite measure word for people} }
   {是 {shì} {to be, is, am} }
   {认识 {rènshi} {to know, to recognize} }
   {非常 {fēicháng} {very; extremely} }
   {夫人 {fūrén} {Lady; Madame; Mrs} }
   {高 {Gāo} {Gao (surname)} }
   {马 {Mǎ} {Ma (surname)} } 
   {老师 {lǎoshī} {teacher} }
   {同学 {tóngxué} {classmate; schoolmate} }
   {院长 {yuànzhǎng} {college/univerisity principal} }
   {同志 {tóngzhì} {comrade} }

 # set index and packsize
 set ::idx 0
 set ::max [llength $wordlist]
 incr ::max -1

 # main proc, builds the GUI
 proc main {} {
   # build main GUI
   # Step 1) text widgets and containter
   # 1a) Chinese characters
   set ::hanzi [gnocl::text -editable 0 -cursorVisible 0]
   set box(1) [gnocl::box -label Hanzi]
   $box(1) add $::hanzi -fill {1 1} -expand 1
   # make a formatting tag for the text..
   $::hanzi tag create txt -fontWeight bold -foreground blue -fontSize 48 -justification center -fontFamily SimSun

   # 1b) Hanyu Pinyin
   set ::pinyin [gnocl::text -editable 0 -cursorVisible 0]
   $::pinyin tag create txt -fontWeight bold -foreground red -fontSize 20 -justification center
   set box(2) [gnocl::expander -label "Hanyu Pinyin" -child $::pinyin]

   # 1c) English definitions
   set ::english [gnocl::text -editable 0 -cursorVisible 0]
   $::english tag create txt -foreground black -fontSize 16 -justification center
   set box(3) [gnocl::expander -label English -child $::english]

   # Step 2) create navigation controls
   set box(4) [gnocl::box]
   set first [gnocl::button -text "%#GotoFirst" -onButtonPress first ]
   set prev [gnocl::button -text "%#GoBack" -onButtonPress prev ]
   set next [gnocl::button -text "%#GoForward" -onButtonPress next ]  
   set quit [gnocl::button -text "%#Quit" -onButtonPress exit]
   $box(4) add "$first $prev $next $quit"

   # Step 3) Create a master container for the above elements
   set box1 [gnocl::box -orientation vertical -children "$box(1) $box(2) $box(3) $box(4)"]

   # Step 4) Create a toplevel window and add all widgets in one go
   set ::main [gnocl::window -height 200 -width 300 -child $box1 -onDestroy exit]

   # if you have an icon for this window then edit the following line
   catch { $::main configure -icon "%/./zhong.gif" }

   # Done, now display first card in the pack
   eval textUpdate [lindex $::wordlist 0]

   # and begin the input loop

 # perform the task of showing the active item
 proc textUpdate {hz py eng} {
   foreach {a b} "hanzi \{$hz\} pinyin \{$py\} english \{$eng\}" {
      # don't you just love it when Tcl lets you do this sort of thing.. :-)
      eval "[set ::$a] erase \{0 0\} end"
      eval "[set ::$a] insert end \{$b\} -tags txt"
   $::main configure -title "$::pack Card No:[expr ${::idx}+1]"

 # show first card
 proc first {} {
      set ::idx 0
      eval textUpdate [lindex $::wordlist $::idx ]

 # show next card
 proc next {} {
      incr ::idx
      if { $::idx > $::max} {set ::idx $::max}  
      eval textUpdate [lindex $::wordlist $::idx ] 

 # show previous card
 proc prev {} {
      incr ::idx -1
      if { $::idx < 0} {set ::idx 0}  
      eval textUpdate [lindex $::wordlist $::idx ] 

 # to run programme..