summaryrefslogtreecommitdiff
path: root/ext/tk/sample/tkextlib/tktable
diff options
context:
space:
mode:
Diffstat (limited to 'ext/tk/sample/tkextlib/tktable')
-rw-r--r--ext/tk/sample/tkextlib/tktable/LICENSE.orig52
-rw-r--r--ext/tk/sample/tkextlib/tktable/basic.rb60
-rw-r--r--ext/tk/sample/tkextlib/tktable/buttons.rb76
-rw-r--r--ext/tk/sample/tkextlib/tktable/command.rb89
-rw-r--r--ext/tk/sample/tkextlib/tktable/debug.rb101
-rw-r--r--ext/tk/sample/tkextlib/tktable/dynarows.rb99
-rw-r--r--ext/tk/sample/tkextlib/tktable/maxsize.rb67
-rwxr-xr-xext/tk/sample/tkextlib/tktable/tcllogo.gifbin0 -> 2341 bytes
-rw-r--r--ext/tk/sample/tkextlib/tktable/valid.rb88
9 files changed, 632 insertions, 0 deletions
diff --git a/ext/tk/sample/tkextlib/tktable/LICENSE.orig b/ext/tk/sample/tkextlib/tktable/LICENSE.orig
new file mode 100644
index 0000000000..dd176a7ccf
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/LICENSE.orig
@@ -0,0 +1,52 @@
+
+ #######################################################################
+ ### The following text is the original 'license.txt' of tktable ###
+ ### extension. ###
+ ### Original Tcl source files are not include in this directry, ###
+ ### because of all of them are rewrited to Ruby files. ###
+ ### However, the image data file is quoted from iwidgets source ###
+ ### archive. ###
+ #######################################################################
+
+
+ * COPYRIGHT AND LICENSE TERMS *
+
+(This file blatantly stolen from Tcl/Tk license and adapted - thus assume
+it falls under similar license terms).
+
+This software is copyrighted by Jeffrey Hobbs <jeff.hobbs@acm.org>. The
+following terms apply to all files associated with the software unless
+explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute, and
+license this software and its documentation for any purpose, provided that
+existing copyright notices are retained in all copies and that this notice
+is included verbatim in any distributions. No written agreement, license,
+or royalty fee is required for any of the authorized uses.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
+EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS
+PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
+OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+RESTRICTED RIGHTS: Use, duplication or disclosure by the U.S. government
+is subject to the restrictions as set forth in subparagraph (c) (1) (ii)
+of the Rights in Technical Data and Computer Software Clause as DFARS
+252.227-7013 and FAR 52.227-19.
+
+SPECIAL NOTES:
+
+This software also falls under the bourbon_ware clause:
+
+ Should you find this software useful in your daily work, you should
+ feel obliged to take the author out for a drink if the opportunity
+ presents itself. The user may feel exempt from this clause if they
+ are under 21 or think the author has already partaken of too many
+ drinks.
diff --git a/ext/tk/sample/tkextlib/tktable/basic.rb b/ext/tk/sample/tkextlib/tktable/basic.rb
new file mode 100644
index 0000000000..a7dfe2a789
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/basic.rb
@@ -0,0 +1,60 @@
+#!/usr/bin/env ruby
+##
+## basic.rb
+##
+## This demo shows the basic use of the table widget
+##
+## ( based on 'basic.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+ary = TkVariable.new_hash
+rows = 8
+cols = 8
+
+# fill table variable
+((-(rows))..rows).each{|x|
+ ((-(cols))..cols).each{|y|
+ ary[x,y] = "r#{x},c#{y}"
+ }
+}
+
+lbl = TkLabel.new(:text=>"TkTable v1 Example")
+
+table = Tk::TkTable.new(:rows=>rows, :cols=>cols, :variable=>ary,
+ :width=>6, :height=>6,
+ :titlerows=>1, :titlecols=>2,
+ :roworigin=>-1, :colorigin=>-2,
+ :rowstretchmode=>:last, :colstretchmode=>:last,
+ :rowtagcommand=>proc{|row|
+ row = Integer(row)
+ return 'OddRow' if row>0 && row%2 == 1
+ },
+ :coltagcommand=>proc{|col|
+ col = Integer(col)
+ return 'OddCol' if col>0 && col%2 == 1
+ },
+ :selectmode=>:extended, :sparsearray=>false)
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+btn = TkButton.new(:text=>'Exit', :command=>proc{exit})
+
+Tk.grid(lbl, '-', :sticky=>:ew)
+Tk.grid(table, sy, :sticky=>:news)
+Tk.grid(sx, :sticky=>:ew)
+Tk.grid(btn, :sticky=>:ew, :columnspan=>2)
+
+Tk.root.grid_columnconfig(0, :weight=>1)
+Tk.root.grid_rowconfig(1, :weight=>1)
+
+table.tag_configure('OddRow', :bg=>'orange', :fg=>'purple')
+table.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')
+
+table.set_width([-2, 7], [-1, 7], [1, 5], [2, 8], [4, 14])
+
+puts "Table is #{table.path} with array #{(table['variable'])}"
+
+Tk.mainloop
diff --git a/ext/tk/sample/tkextlib/tktable/buttons.rb b/ext/tk/sample/tkextlib/tktable/buttons.rb
new file mode 100644
index 0000000000..b6995bb54b
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/buttons.rb
@@ -0,0 +1,76 @@
+#!/usr/bin/env ruby
+##
+## buttons.rb
+##
+## demonstrates the simulation of a button array
+##
+## ( based on 'buttons.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+# create the table
+tab = TkVariable.new_hash
+rows = 20
+cols = 20
+
+table = Tk::TkTable.new(:rows=>rows + 1, :cols=>cols + 1,
+ :variable=>tab, :titlerows=>1, :titlecols=>1,
+ :roworigin=>-1, :colorigin=>-1,
+ :colwidth=>4, :width=>8, :height=>8,
+ :cursor=>'top_left_arrow', :borderwidth=>2,
+ :flashmode=>false, :state=>:disabled)
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+Tk.grid(table, sy, :sticky=>:news)
+Tk.grid(sx, :sticky=>:ew)
+
+Tk.root.grid_columnconfig(0, :weight=>1)
+Tk.root.grid_rowconfig(0, :weight=>1)
+
+# set up tags for the various states of the buttons
+table.tag_configure('OFF', :bg=>'red', :relief=>:raised)
+table.tag_configure('ON', :bg=>'green', :relief=>:sunken)
+table.tag_configure('sel', :bg=>'gray75', :relief=>:flat)
+
+# clean up if mouse leaves the widget
+table.bind('Leave', proc{|w| w.selection_clear_all}, '%W')
+
+# highlight the cell under the mouse
+table.bind('Motion', proc{|w, x, y|
+ Tk.callback_break if w.selection_include?(TkComm._at(x,y))
+ w.selection_clear_all
+ w.selection_set(TkComm._at(x,y))
+ Tk.callback_break
+ ## "break" prevents the call to tkTableCheckBorder
+ }, '%W %x %y')
+
+# mousebutton 1 toggles the value of the cell
+# use of "selection includes" would work here
+table.bind('1', proc{|w, x, y|
+ #rc = w.curselection[0]
+ rc = w.index(TkComm._at(x,y))
+ if tab[rc] == 'ON'
+ tab[rc] = 'OFF'
+ w.tag_cell('OFF', rc)
+ else
+ tab[rc] = 'ON'
+ w.tag_cell('ON', rc)
+ end}, '%W %x %y')
+
+
+# inititialize the array, titles, and celltags
+0.step(rows){|i|
+ tab[i,-1] = i
+ 0.step(cols){|j|
+ if i == 0
+ tab[-1,j] = j
+ end
+ tab[i,j] = "OFF"
+ table.tag_cell('OFF', "#{i},#{j}")
+ }
+}
+
+Tk.mainloop
diff --git a/ext/tk/sample/tkextlib/tktable/command.rb b/ext/tk/sample/tkextlib/tktable/command.rb
new file mode 100644
index 0000000000..950bc0ccb1
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/command.rb
@@ -0,0 +1,89 @@
+#!/usr/bin/env ruby
+##
+## command.rb
+##
+## This demo shows the use of the table widget's -command options
+##
+## ( based on 'command.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+# create the table
+data = TkVariable.new_hash
+rows = 10
+cols = 10
+
+# fill table variable
+((-(rows))..rows).each{|x|
+ ((-(cols))..cols).each{|y|
+ data[x,y] = "#{x} x #{y}"
+ }
+}
+
+lbl = TkLabel.new(:text=>"TkTable :command Example")
+cur_var = TkVariable.new
+current = TkLabel.new(:textvariable=>cur_var, :width=>5)
+ent_var = TkVariable.new
+entry = TkEntry.new(:textvariable=>ent_var)
+
+table = Tk::TkTable.new(:rows=>rows, :cols=>cols,
+ :command=>[proc{|mode, cell, val|
+ if (mode == :w)
+ data[cell] = val
+ else
+ begin
+ data[cell] # exist
+ rescue
+ '' # not exist
+ end
+ end
+ }, '%i %C %s'],
+ :width=>6, :height=>6,
+ :titlerows=>1, :titlecols=>1,
+ :roworigin=>-1, :colorigin=>-1,
+ :rowstretchmode=>:last, :colstretchmode=>:last,
+ :rowtagcommand=>proc{|row|
+ row = Integer(row)
+ return 'OddRow' if row>0 && row%2 == 1
+ },
+ :coltagcommand=>proc{|col|
+ col = Integer(col)
+ return 'OddCol' if col>0 && col%2 == 1
+ },
+ :selectmode=>:extended, :flashmode=>true,
+ :rowstretch=>:unset, :colstretch=>:unset,
+ :browsecommand=>[proc{|w, s|
+ cur_var.value = s
+ ent_var.value = w.get(s)
+ }, '%W %S'],
+ :validate=>true,
+ :validatecommand=>proc{|e|
+ ent_var.value = e.new_value; true
+ })
+=begin
+ :validatecommand=>[
+ proc{|s|
+ ent_var.value = s; true
+ }, '%S'])
+=end
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+entry.bind('Return', proc{|w| table.curvalue = w.value}, '%W')
+
+Tk.grid(lbl, '-', '-', :sticky=>:ew)
+Tk.grid(current, entry, '-', :sticky=>:ew)
+Tk.grid(table, '-', sy, :sticky=>:news)
+Tk.grid(sx, '-', :sticky=>:ew)
+
+Tk.root.grid_columnconfig(1, :weight=>1)
+Tk.root.grid_rowconfig(2, :weight=>1)
+
+table.tag_configure('OddRow', :bg=>'orange', :fg=>'purple')
+table.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')
+
+puts "Table is #{table.path}"
+
+Tk.mainloop
diff --git a/ext/tk/sample/tkextlib/tktable/debug.rb b/ext/tk/sample/tkextlib/tktable/debug.rb
new file mode 100644
index 0000000000..30508acea6
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/debug.rb
@@ -0,0 +1,101 @@
+#!/usr/bin/env ruby
+##
+## debug.rb
+##
+## This demo uses most features of the table widget
+##
+## ( based on 'debug.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+# create the table
+ary = TkVariable.new_hash
+rows = 25
+cols = 20
+
+# fill table variable
+((-(rows))..rows).each{|x|
+ ((-(cols))..cols).each{|y|
+ ary[x,y] = "r#{x},c#{y}"
+ }
+}
+
+lbl = TkLabel.new(:text=>"TkTable v2 Example")
+
+table = Tk::TkTable.new(:rows=>rows, :cols=>cols, :variable=>ary,
+ :width=>6, :height=>6,
+ :titlerows=>1, :titlecols=>2,
+ :roworigin=>-5, :colorigin=>-2,
+ :coltagcommand=>proc{|col|
+ col = Integer(col)
+ return 'OddCol' if col>0 && col%2 == 1
+ },
+ :selectmode=>:extended, :flashmode=>true,
+ :rowstretch=>:unset, :colstretch=>:unset,
+ :selecttitles=>false, :drawmode=>:single)
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+btn = TkButton.new(:text=>'Exit', :command=>proc{exit})
+
+Tk.grid(lbl, '-', :sticky=>:ew)
+Tk.grid(table, sy, :sticky=>:news)
+Tk.grid(sx, :sticky=>:ew)
+Tk.grid(btn, :sticky=>:ew, :columnspan=>2)
+
+Tk.root.grid_columnconfig(0, :weight=>1)
+Tk.root.grid_rowconfig(1, :weight=>1)
+
+table.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')
+table.tag_configure('title', :bg=>'red', :fg=>'green', :relief=>:sunken)
+table.tag_configure('dis', :state=>:disabled)
+
+first = table[:colorigin]
+%w(n s e w nw ne sw se c).each_with_index{|anchor, idx|
+ table.tag_configure(anchor, :anchor=>anchor)
+ table.tag_row(anchor, idx)
+ table.set([idx,first], anchor)
+}
+courier = TkFont.new(:family=>'Courier', :size=>10)
+table.tag_configure('s', :font=>courier, :justify=>:center)
+
+logo = TkPhotoImage.new(:file=>File.join(File.dirname(File.expand_path(__FILE__)), 'tcllogo.gif'))
+table.tag_configure('logo', :image=>logo, :showtext=>true)
+table.tag_cell('logo', [1,2], [2,3], [4,1])
+table.tag_cell('dis', [2,1], [1,-1], [3,0])
+table.set_width([-2,8], [-1,9], [0, 12], [4, 14])
+
+table.set([1,1], "multi-line\ntext\nmight be\ninteresting",
+ [3,2], "more\nmulti-line\nplaying\n",
+ [2,2], "null\0byte")
+
+# This is in the row span
+l = TkLabel.new(table, :text=>'Window s', :bg=>'yellow')
+table.window_configure([6,0], :sticky=>:s, :window=>l)
+
+# This is in the row titles
+l = TkLabel.new(table, :text=>'Window ne', :bg=>'yellow')
+table.window_configure([4,-1], :sticky=>:ne, :window=>l)
+
+# This will get swallowed by a span
+l = TkLabel.new(table, :text=>'Window ew', :bg=>'yellow')
+table.window_configure([5,3], :sticky=>:ew, :window=>l)
+
+# This is in the col titles
+l = TkLabel.new(table, :text=>'Window news', :bg=>'yellow')
+table.window_configure([-5,1], :sticky=>:news, :window=>l)
+
+l = TkLabel.new(table.winfo_parent, :text=>'Sibling l', :bg=>'orange')
+table.window_configure([5,1], :sticky=>:news, :window=>l)
+
+if table.span_list.empty?
+ table.set_spans([-1,-2], [0,3], [1,2], [0,5], [3,2], [2,2], [6,0], [4,0])
+end
+
+puts "Table is #{table.path} with array #{(table['variable'])}"
+
+# table.postscript(:file=>'out.ps', :first=>:origin, :last=>[2,2])
+
+Tk.mainloop
diff --git a/ext/tk/sample/tkextlib/tktable/dynarows.rb b/ext/tk/sample/tkextlib/tktable/dynarows.rb
new file mode 100644
index 0000000000..35359046f7
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/dynarows.rb
@@ -0,0 +1,99 @@
+#!/usr/bin/env ruby
+##
+## dynarows.rb
+##
+## This demos shows the use of the validation mechanism of the table
+## and uses the table's cache (no -command or -variable) with a cute
+## dynamic row routine.
+##
+## ( based on 'dynarows.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+def table_validate(w, idx)
+ return unless idx =~ /^(\d+),(\d+)$/
+ row = Integer($1)
+ col = Integer($2)
+ val = w.get(idx)
+
+ [w, idx]
+ nrows = w[:rows]
+ return if row == nrows - 1 && val == ''
+
+ begin
+ time = Tk.tk_call('clock', 'scan', val)
+ date = []
+ Tk.tk_call('clock', 'format', time,
+ :format=>'%m %d %Y').split(' ').each{|item|
+ date << item.sub(/^\s*0*/,'')
+ }
+ w.set(idx, date.join('/'))
+ if row == nrows - 1
+ if w.get([row,1]) != '' && w.get([row,2]) != ''
+ w.tag_row_reset(row)
+ w.set([row,0], row)
+ nrows += 1
+ row += 1
+ w.configure(:rows=>nrows)
+ w.tag_row('unset', row)
+ w.set([row,0], '*')
+ w.see([row,1])
+ w.activate([row,1])
+ end
+ end
+ rescue
+ Tk.bell
+ w.activate(idx)
+ w.selection_clear_all
+ w.selection_set(:active)
+ w.see(:active)
+ end
+end
+
+
+lbl = TkLabel.new(:text=>"Dynamic Date Validated Rows")
+
+table = Tk::TkTable.new(:rows=>2, :cols=>3, :cache=>1, :selecttype=>:row,
+ :titlerows=>1, :titlecols=>1, :height=>5,
+ :colstretch=>:unset, :rowstretch=>:unset,
+ :autoclear=>true,
+ :browsecommand=>[
+ proc{|w,s| table_validate(w, s)},
+ '%W %s'
+ ])
+table.set([0,1], 'Begin', [0,2], 'End', [1,0], '*')
+table.tag_configure('unset', :fg=>'#008811')
+table.tag_configure('title', :fg=>'red')
+table.tag_row('unset', 1)
+table.set_width(0,3)
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+Tk.grid(lbl, '-', :sticky=>:ew)
+Tk.grid(table, sy, :sticky=>:news)
+Tk.grid(sx, :sticky=>:ew)
+
+Tk.root.grid_columnconfig(0, :weight=>1)
+Tk.root.grid_rowconfig(1, :weight=>1)
+
+rtn_proc = proc{|w|
+ r = w.row_index(:active)
+ c = w.col_index(:active)
+
+ if c == 2
+ r += 1
+ w.activate([r,1])
+ else
+ c += 1
+ w.activate([r,c])
+ end
+ w.see(:active)
+ Tk.callback_break
+}
+
+table.bind('Return', rtn_proc, '%W')
+table.bind('KP_Enter', rtn_proc, '%W')
+
+Tk.mainloop
diff --git a/ext/tk/sample/tkextlib/tktable/maxsize.rb b/ext/tk/sample/tkextlib/tktable/maxsize.rb
new file mode 100644
index 0000000000..a2c5f606a8
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/maxsize.rb
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+##
+## maxsize.rb
+##
+## This demo uses a really big table. The big startup time is in
+## filling the table's Tcl array var.
+##
+## ( based on 'maxsize.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+ary = TkVariable.new_hash
+rows = 40000
+cols = 10
+
+# fill table variable
+((-(rows))..rows).each{|x|
+ ((-(cols))..cols).each{|y|
+ ary[x,y] = "#{x},#{y}"
+ }
+}
+
+lbl = TkLabel.new(:text=>"TkTable v2 Example")
+
+table = Tk::TkTable.new(:rows=>rows, :cols=>cols, :variable=>ary,
+ :width=>6, :height=>8,
+ :titlerows=>1, :titlecols=>1,
+ :coltagcommand=>proc{|col|
+ col = Integer(col)
+ return 'OddCol' if col>0 && col%2 == 1
+ },
+ :selectmode=>:extended,
+ :colstretch=>:unset, :rowstretch=>:unset,
+ :selecttitles=>false, :drawmode=>:slow)
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+btn = TkButton.new(:text=>'Exit', :command=>proc{exit})
+
+Tk.grid(lbl, '-', :sticky=>:ew)
+Tk.grid(table, sy, :sticky=>:news)
+Tk.grid(sx, :sticky=>:ew)
+Tk.grid(btn, :sticky=>:ew, :columnspan=>2)
+
+Tk.root.grid_columnconfig(0, :weight=>1)
+Tk.root.grid_rowconfig(1, :weight=>1)
+
+table.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')
+table.tag_configure('title', :bg=>'red', :fg=>'blue', :relief=>:sunken)
+table.tag_configure('dis', :state=>:disabled)
+
+first = table[:colorigin]
+%w(n s e w nw ne sw se c).each_with_index{|anchor, idx|
+ table.tag_configure(anchor, :anchor=>anchor)
+ table.tag_row(anchor, idx)
+ table.set([idx,first], anchor)
+}
+courier = TkFont.new(:family=>'Courier', :size=>10)
+table.tag_configure('s', :font=>courier, :justify=>:center)
+
+table.set_width([-2, 8], [-1, 9], [0, 12], [4, 14])
+
+puts "Table is #{table.path} with array #{(table['variable'])}"
+
+Tk.mainloop
diff --git a/ext/tk/sample/tkextlib/tktable/tcllogo.gif b/ext/tk/sample/tkextlib/tktable/tcllogo.gif
new file mode 100755
index 0000000000..4603d4ff41
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/tcllogo.gif
Binary files differ
diff --git a/ext/tk/sample/tkextlib/tktable/valid.rb b/ext/tk/sample/tkextlib/tktable/valid.rb
new file mode 100644
index 0000000000..4570441667
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tktable/valid.rb
@@ -0,0 +1,88 @@
+#!/usr/bin/env ruby
+##
+## valid.rb
+##
+## This demos shows the use of the validation mechanism of the table
+## and uses the table's cache (no -command or -variable)
+##
+## ( based on 'valid.tcl' included source archive of tktable extension )
+##
+require 'tk'
+require 'tkextlib/tktable'
+
+rows = 10
+cols = 10
+
+def colorize(num)
+ num = Integer(num)
+ return 'colored' if (num > 0 && num % 2 == 1)
+end
+
+def fill_headers(w, r=10, c=10)
+ (1..(r-1)).each{|i| w.set([i,0], i.to_s)}
+
+ (1..(c-1)).each{|j|
+ if j % 3 == 1
+ w.set([0,j], 'AlphaNum')
+ elsif j % 2 == 1
+ w.set([0,j], 'Alpha')
+ elsif j != 0
+ w.set([0,j], 'Real')
+ end
+ }
+end
+
+def validate_proc(c, val)
+ if c % 3 == 1
+ # AlphaNum
+ regexp = /^[A-Za-z0-9 ]*$/
+ elsif c % 2 == 1
+ # Alpha
+ regexp = /^[A-Za-z ]*$/
+ elsif c != 0
+ # 'Real'
+ regexp = /^[-+]?[0-9]*\.?[0-9]*([0-9]\.?e[-+]?[0-9]*)?$/
+ end
+ if val =~ regexp
+ return true
+ else
+ Tk.bell
+ return false
+ end
+end
+
+lbl = TkLabel.new(:text=>"TkTable v1 Validated Table Example")
+
+table = Tk::TkTable.new(:rows=>rows, :cols=>cols, :cache=>1,
+ :width=>5, :height=>5, :titlerows=>1, :titlecols=>1,
+ :coltagcommand=>proc{|n| colorize(n)},
+ :flashmode=>true, :selectmode=>:extended,
+ :colstretch=>:unset, :rowstretch=>:unset,
+ :validate=>true,
+ :validatecommand=>proc{|e|
+ unless e.widget.tag_include?('title', e.index)
+ validate_proc(e.column, e.new_value)
+ end } )
+
+fill_headers(table)
+
+table.tag_configure('colored', :bg=>'lightblue')
+table.tag_configure('title', :fg=>'red')
+table.set_width(0,3)
+
+sx = table.xscrollbar(TkScrollbar.new)
+sy = table.yscrollbar(TkScrollbar.new)
+
+btn = TkButton.new(:text=>'Exit', :command=>proc{exit})
+
+Tk.grid(lbl, '-', :sticky=>:ew)
+Tk.grid(table, sy, :sticky=>:news)
+Tk.grid(sx, :sticky=>:ew)
+Tk.grid(btn, '-', :sticky=>:ew)
+
+Tk.root.grid_columnconfig(0, :weight=>1)
+Tk.root.grid_rowconfig(1, :weight=>1)
+
+puts "Table is #{table.path}"
+
+Tk.mainloop