diff options
Diffstat (limited to 'Master/tlpkg/tlperl/lib/Tk/TixGrid.pm')
-rw-r--r-- | Master/tlpkg/tlperl/lib/Tk/TixGrid.pm | 1597 |
1 files changed, 1597 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl/lib/Tk/TixGrid.pm b/Master/tlpkg/tlperl/lib/Tk/TixGrid.pm new file mode 100644 index 00000000000..2dd238095f3 --- /dev/null +++ b/Master/tlpkg/tlperl/lib/Tk/TixGrid.pm @@ -0,0 +1,1597 @@ + +# TODO: +# +# o How to get into state 's0' 'b0' so cursor keys start +# working (compare with Tk/Widget XYscrollBind +# o the options -browsecmd and -command callback are not +# not implemented (as in Tix) +# o privateData 'state' used only once (check again Grid.tcl) +# o FloatEntry 'sometimes not activeted immediately on selection +# o check also Leave Binding. Looks like entry does get unpost'ed + +package Tk::TixGrid; + +BEGIN + { + use vars '$DEBUG'; + $DEBUG = (defined($ENV{USER}) and $ENV{USER} eq 'ach') ? 1 : 0; + print STDERR "tixGrid: debug = $DEBUG\n" if $DEBUG; + } + +use strict; +use vars qw($VERSION); +$VERSION = sprintf '4.%03d', q$Revision: #9 $ =~ /\D(\d+)\s*$/; + +use Tk qw(Ev $XS_VERSION); +use Tk::Widget; +use Carp; + +# carp "\n".__PACKAGE__.' is deprecated' unless defined($Test::ntest); + +use base 'Tk::Widget'; + +Construct Tk::Widget 'TixGrid'; + +bootstrap Tk::TixGrid; + +sub Tk_cmd { \&Tk::tixGrid } + +sub Tk::Widget::SrclTixGrid { shift->Scrolled('TixGrid' => @_) } + +Tk::Methods qw(anchor bdtype delete entrycget entryconfigure format index + move set size unset xview yview + dragsite dropsite geometryinfo info + nearest see selection sort ); + +use Tk::Submethods + ( + 'anchor' => [ qw(get set) ], + 'delete' => [ qw(column row) ], + 'info' => [ qw(bbox exists anchor) ], + 'move' => [ qw(column row) ], + 'selection' => [ qw(adjust clear includes set) ], + 'size' => [ qw(column row) ], + 'format' => [ qw(grid border) ], + ); + +# edit subcommand is special. It justs invokes tcl code: +# +# edit set x y -> tixGrid:EditCell $w, x, y +# edit apply -> tixGrid:EditApply + +# xxx Create an edit sub? +# sub edit { .... } + +sub editSet + { + die "wrong args. Should be \$w->editSet(x,y)\n" unless @_ == 3; + my ($w, $x, $y) = @_; + $w->EditCell($x, $y); + } + +sub editApply + { + die "wrong args. Should be \$w->editApply()\n" unless @_ == 1; + my ($w) = @_; + $w->EditApply() + } + + +#################################################### +## +## For button 2 scrolling. So TixGrid has 'standard' +## standard scrolling interface +## + +#sub scanMark +# { +# die "wrong # args: \$w->scanMark(x,y)\n" unless @_ == 3; +# my ($w) = @_; +# $w->{__scanMarkXY__} = [ @_[1,2] ]; +# return ""; +# } +# +#sub scanDragto +# { +# die "wrong # args: \$w->scanDragto(x,y)\n" unless @_ == 3; +# my ($w, $x, $y) = @_; +# my ($ox, $oy) = @{ $w->{__scanMarkXY__} }; +# +# #... +# +# return ""; +# } + +### end button 2 scrolling stuff #################### + + +# Grid.tcl -- +# +# This file defines the default bindings for Tix Grid widgets. +# +# Copyright (c) 1996, Expert Interface Technologies +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# Bindings translated to perl/Tk by Achim Bohnet <ach@mpe.mpg.de> + +sub ClassInit + { + my ($class, $mw) = @_; + $class->SUPER::ClassInit($mw); + + $mw->XYscrollBind($class); + + ## + ## Button bindings + ## + + $mw->bind($class, '<ButtonPress-1>', ['Button_1', Ev('x'), Ev('y')]); + $mw->bind($class, '<Shift-ButtonPress-1>', ['Shift_Button_1', Ev('x'), Ev('y')]); + $mw->bind($class, '<Control-ButtonPress-1>',['Control_Button_1', Ev('x'), Ev('y')]); + $mw->bind($class, '<ButtonRelease-1>', ['ButtonRelease_1', Ev('x'), Ev('y')]); + $mw->bind($class, '<Double-ButtonPress-1>', ['Double_1', Ev('x'), Ev('y')]); + $mw->bind($class, '<B1-Motion>','Button_Motion'); + $mw->bind($class, '<Control-B1-Motion>','Control_Button_Motion'); + $mw->bind($class, '<B1-Leave>','Button_Leave'); + $mw->bind($class, '<Double-ButtonPress-1>', ['Double_1', Ev('x'), Ev('y')]); + $mw->bind($class, '<B1-Enter>', ['B1_Enter', Ev('x'), Ev('y')]); + $mw->bind($class, '<Control-B1-Leave>','Control_Button_Leave'); + $mw->bind($class, '<Control-B1-Enter>', ['Control_B1_Enter', Ev('x'), Ev('y')]); + + ## + ## Keyboard bindings + ## + + $mw->bind($class, '<Up>', ['DirKey', 'up' ]); + $mw->bind($class, '<Down>', ['DirKey', 'down' ]); + $mw->bind($class, '<Left>', ['DirKey', 'left' ]); + $mw->bind($class, '<Right>', ['DirKey', 'right' ]); + + $mw->PriorNextBind($class); + + $mw->bind($class, '<Return>', 'Return'); + $mw->bind($class, '<space>', 'Space' ); + + return $class; + } + +#---------------------------------------------------------------------- +# +# +# Mouse bindings +# +# +#---------------------------------------------------------------------- + +sub Button_1 + { + my $w = shift; + + return if $w->cget('-state') eq 'disabled'; + $w->SetFocus; + $w->ChgState(@_, + [ + '0'=>'1', + ] + ); + } + +sub Shift_Button_1 + { + my $w = shift; + + return if $w->cget('-state') eq 'disabled'; + $w->SetFocus; + +# $w->ChgState(@_, +# [ +# ] +# ); + } + +sub Control_Button_1 + { + my $w = shift; + + return if $w->cget('-state') eq 'disabled'; + $w->SetFocus; + + $w->ChgState(@_, + [ + 's0' => 's1', + 'b0' => 'b1', + 'm0' => 'm1', + 'e0' => 'e10', + ] + ); + } + +sub ButtonRelease_1 + { + shift->ChgState(@_, + [ + '2' => '5', + '4' => '3', + ] + ); + } + +sub B1_Motion + { + shift->ChgState(@_, + [ + '2' => '4', + '4' => '4', + ] + ); + } + + +sub Control_B1_Motion + { + shift->ChgState(@_, + [ + 's2' => 's4', + 's4' => 's4', + 'b2' => 'b4', + 'b4' => 'b4', + 'm2' => 'm4', + 'm5' => 'm4', + ] + ); + } + + +sub Double_1 + { + shift->ChgState(@_, + [ + 's0' => 's7', + 'b0' => 'b7', + ] + ); + } + + +sub B1_Leave + { + shift->ChgState(@_, + [ + 's2' => 's5', + 's4' => 's5', + 'b2' => 'b5', + 'b4' => 'b5', + 'm2' => 'm8', + 'm5' => 'm8', + 'e2' => 'e8', + 'e5' => 'e8', + ] + ); + } + + +sub B1_Enter + { + shift->ChgState(@_, + [ + 's5' => 's4', + 's6' => 's4', + 'b5' => 'b4', + 'b6' => 'b4', + 'm8' => 'm4', + 'm9' => 'm4', + 'e8' => 'e4', + 'e9' => 'e4', + ] + ); + } + + +sub Control_B1_Leave + { + shift->ChgState(@_, + [ + 's2' => 's5', + 's4' => 's5', + 'b2' => 'b5', + 'b4' => 'b5', + 'm2' => 'm8', + 'm5' => 'm8', + ] + ); + } + + +sub Control_B1_Enter + { + shift->ChgState(@_, + [ + 's5' => 's4', + 's6' => 's4', + 'b5' => 'b4', + 'b6' => 'b4', + 'm8' => 'm4', + 'm9' => 'm4', + ] + ); + } + + +sub AutoScan + { + shift->ChgState(@_, + [ + 's5' => 's9', + 's6' => 's9', + 'b5' => 'b9', + 'b6' => 'b9', + 'm8' => 'm9', + 'm9' => 'm9', + 'e8' => 'm9', + 'e9' => 'm9', + ] + ); + } + +#---------------------------------------------------------------------- +# +# +# Key bindings +# +# +#---------------------------------------------------------------------- + +sub DirKey + { + my ($w, $key) = @_; + + return if $w->cget('-state') eq 'disabled'; + +print STDERR "$w->DirKey($key)\n" if $DEBUG; + $w->ChgState($key, + [ + 's0' => 's8', + 'b0' => 'b8', + ] + ); + } + + +sub Return + { + my ($w) = @_; + + return if $w->cget('-state') eq 'disabled'; + + $w->ChgState( + [ + 's0' => 's9', + 'b0' => 'b9', + ] + ); + } + + +sub Space + { + my ($w) = @_; + + return if $w->cget('-state') eq 'disabled'; + + $w->ChgState( + [ + 's0' => 's10', + 'b0' => 'b10', + ] + ); + } + + +#---------------------------------------------------------------------- +# +# STATE MANIPULATION +# +# +#---------------------------------------------------------------------- + +sub GetState + { + my ($w) = @_; + my $data = $w->privateData(); + $data->{state} = 0 unless exists $data->{state}; + return $data->{state}; +} + +sub Button_Motion +{ + my $w = shift; + my $Ev = $w->XEvent; + $Tk::x = $Ev->x; + $Tk::y = $Ev->y; + $Tk::X = $Ev->X; + $Tk::Y = $Ev->Y; + $w->B1_Motion($Tk::x, $Tk::y); +} + + +sub Control_Button_Motion +{ + my $w = shift; + my $Ev = $w->XEvent; + $Tk::x = $Ev->x; + $Tk::y = $Ev->y; + $Tk::X = $Ev->X; + $Tk::Y = $Ev->Y; + $w->Control_B1_Motion($Tk::x, $Tk::y); +} + + +sub Button_Leave +{ + my $w = shift; + my $Ev = $w->XEvent; + $Tk::x = $Ev->x; + $Tk::y = $Ev->y; + $Tk::X = $Ev->X; + $Tk::Y = $Ev->Y; + $w->B1_Leave(); +} + + +sub Control_Button_Leave +{ + my $w = shift; + my $Ev = $w->XEvent; + $Tk::x = $Ev->x; + $Tk::y = $Ev->y; + $Tk::X = $Ev->X; + $Tk::Y = $Ev->Y; + $w->Control_B1_Leave(); +} + + +sub SetState + { + my ($w, $state) = @_; + $w->privateData()->{state} = $state; + } + +sub GoState + { + my ($w, $state) = (shift, shift); + print STDERR 'Gostate: ', $w->GetState, " --> $state, " if $DEBUG; + $w->SetState($state); + my $method = "GoState_$state"; + + print STDERR 'args=(', join(',',@_), ')'. + "\t(",$w->cget('-selectmode'). + ',',$w->cget('-selectunit').")\n" if $DEBUG; + + if (0) + { + $@ = ''; + %@ = (); # Workaround to prevent spurious loss of $@ + eval { $w->$method(@_) }; + print STDERR "Error Gostate: '$state': ", $@ if $@; + return undef; + } + + $w->$method(@_); + return undef + } + +## +## ChgState is a fancy case statement +## + +sub ChgState + { + my $w = shift; + my $map = pop; + print STDERR 'ChgState(', join(',',@_,'['), join(',',@$map,),']) ' if $DEBUG; + my $state = $w->GetState; + + my ($match, $to); + while (@$map) + { + $match = shift @$map; + $to = shift @$map; + if ($match eq $state) + { + print STDERR "$state --> $to \n" if $DEBUG; + $w->GoState($to, @_); + return; + } + } + print STDERR "*no* chg for $state\n" if $DEBUG; + } + + +#---------------------------------------------------------------------- +# SELECTION ROUTINES +#---------------------------------------------------------------------- + +#proc tixGrid:SelectSingle {w ent} { +# $w selection set [lindex $ent 0] [lindex $ent 1] +# tixGrid:CallBrowseCmd $w $ent +#} + +sub SelectSingle + { + my ($w, $n1, $n2) = @_; + $w->selection('set', $n1, $n2); + $w->Callback('-browsecmd' => $n1, $n2); + } + +#---------------------------------------------------------------------- +# SINGLE SELECTION +#---------------------------------------------------------------------- + +sub GoState_0 + { + my ($w) = @_; + my $list = $w->privateData()->{list}; + return unless defined $list; + + foreach my $cmd (@$list) + { + # XXX should do more something like $w->Callback'('__pending_cmds__'); + eval $cmd; # XXX why in tcl in global context (binding?) + } + undef(@$list); # XXX should really delete? Maybe on needed in TCL + } + +# XXXX how to translate global context +# what does unset +#proc tixGrid:GoState-0 {w} { +# set list $w:_list +# global $list +# +# if [info exists $list] { +# foreach cmd [set $list] { +# uplevel #0 $cmd +# } +# if [info exists $list] { +# unset $list +# } +# } +#} + +sub GoState_1 + { + my ($w, $x, $y) = @_; + + my @ent = $w->mynearest($x,$y); + if (@ent) + { + $w->SetAnchor(@ent); + } + $w->CheckEdit; + $w->selection('clear', 0, 0, 'max', 'max'); + + if ($w->cget('-selectmode') ne 'single') + { + $w->SelectSingle(@ent); + } + $w->GoState(2); + } + +sub GoState_2 + { + my ($w) = @_; + } + +sub GoState_3 + { + my ($w, $x, $y) = @_; + + my @ent = $w->mynearest($x,$y); + if (@ent) + { + $w->SelectSingle(@ent); + } + $w->GoState(0); + + } + +sub GoState_4 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x,$y); + my $mode = $w->cget('-selectmode'); + + if ($mode eq 'single') + { + $w->SetAnchor(@ent); + } + elsif ($mode eq 'browse') + { + $w->SetAnchor(@ent); + $w->selection('clear', 0, 0, 'max', 'max'); + $w->SelectSingle(@ent); + } + elsif ($mode eq 'multiple' || + $mode eq 'extended') + { + my (@anchor) = $w->anchor('get'); + $w->selection('adjust', @anchor[0,1], @ent[0,1]); + } + } + +sub GoState_5 + { + my ($w, $x, $y) = @_; + + my @ent = $w->mynearest($x,$y); + if (@ent) + { + $w->SelectSingle(@ent); + $w->SetEdit(@ent); + } + $w->GoState(0); + + } + +############################################## +# BUG xxx +# return scalar instead of errors + +sub mynearest { shift->split_s2a('nearest', @_); } +sub myanchorGet { shift->split_s2a('anchor', 'get', @_); } + +sub split_s2a + { + my $w = shift; + my $method = shift; + my @ent = $w->$method(@_); + if (@ent == 1) + { +my $tmp = $ent[0]; + @ent = split(/ /, $ent[0]) if @ent == 1; +print STDERR join('|',"$method splitted '$tmp' =>",@ent,"\n") if $DEBUG; + } + else + { +#print STDERR join("|","$method splitted is okay :",@ent,"\n") if $DEBUG; + } + return @ent; + } + +############################################## + + +sub GoState_s5 + { + shift->StartScan(); + } + + +sub GoState_s6 + { + shift->DoScan(); + } + + +sub GoState_s7 + { + my ($w, $x, $y) = @_; + + my @ent = $w->mynearest($x, $y); + if (@ent) + { + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-command' => @ent); + } + $w->GoState('s0'); + } + + +sub GoState_s8 + { + my ($w, $key) = @_; + + ## BUGS .... + ## - anchor is bad, only bbox, exists8 + ## - looks like anchor is 1-dim: set anchor 0 + ## - method see unknown (even when defined with Tk::Method) + + my (@anchor) = $w->info('anchor'); + if (@anchor) + { + @anchor = (); + } + else + { + @anchor = $w->info($key, @anchor); + } + + $w->anchor('set', @anchor); + $w->see(@anchor); + + $w->GoState('s0'); + } + +#proc tixGrid:GoState-s8 {w key} { +# set anchor [$w info anchor] +# +# if {$anchor == ""} { +# set anchor 0 +# } else { +# set anchor [$w info $key $anchor] +# } +# +# $w anchor set $anchor +# $w see $anchor +# tixGrid:GoState s0 $w +#} + + +sub GoState_s9 + { + my ($w, $key) = @_; + +#print STDERR "GoState_s9 is not implemented\n"; + + my (@anchor) = $w->info('anchor'); + unless (@anchor) + { + @anchor = (); + $w->anchor('set', @anchor); + $w->see(@anchor); + } + + unless ($w->info('anchor')) + { + # ! may not have any elements + # + $w->Callback('-command' => $w->info('anchor')); + $w->selection('clear'); + $w->selection('set', @anchor); + } + + $w->GoState('s0'); + } + + +sub GoState_s10 + { + my ($w, $key) = @_; + + my (@anchor) = $w->info('anchor'); + if (@anchor) + { + @anchor = (); + $w->anchor('set', @anchor); + $w->see(@anchor); + } + + unless ($w->info('anchor')) + { + # ! may not have any elements + # + $w->Callback('-browsecmd' => $w->info('anchor')); + $w->selection('clear'); + $w->selection('set', @anchor); + } + + $w->GoState('s0'); + } + + +#---------------------------------------------------------------------- +# BROWSE SELECTION +#---------------------------------------------------------------------- + +sub GoState_b0 + { + my ($w) = @_; + } + +sub GoState_b1 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->anchor('set', @ent); + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-browsecmd' => @ent); + } + + $w->GoState('b2'); + } + +sub GoState_b2 + { + my ($w) = @_; + } + +sub GoState_b3 + { + my ($w) = @_; + + my (@ent) = $w->info('anchor'); + if (@ent) + { + $w->selection('clear'); + $w->selection('set', @ent); + $w->selection('set', @ent); + $w->Callback('-browsecmd' => @ent); + } + + $w->GoState('b0'); + } + + +sub GoState_b4 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->anchor('set', @ent); + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-browsecmd' => @ent); + } + } + + +sub GoState_b5 { shift->StartScan(); } + + +sub GoState_b6 { shift->DoScan(); } + + +sub GoState_b7 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-command' => @ent); + } + $w->GoState('b0'); + } + + +sub GoState_b8 + { + my ($w, $key) = @_; + + my (@anchor) = $w->info('anchor'); + if (@anchor) + { + @anchor = $w->info('key', @anchor); + } + else + { + @anchor = (0,0); # ????? + } + + $w->anchor('set', @anchor); + $w->selection('clear'); + $w->selection('set', @anchor); + $w->see(@anchor); + + $w->Callback('-browsecmd' => @anchor); + $w->GoState('b0'); + } + + +sub GoState_b9 + { + my ($w) = @_; + + my (@anchor) = $w->info('anchor'); + unless (@anchor) + { + @anchor = (0,0); + $w->anchor('set', @anchor); + $w->see(@anchor); + } + + if ($w->info('anchor')) + { + # ! may not have any elements + # + $w->Callback('-command' => $w->info('anchor')); + $w->selection('clear'); + $w->selection('set', @anchor); + } + + $w->GoState('b0'); + } + + +sub GoState_b10 + { + my ($w) = @_; + + my (@anchor) = $w->info('anchor'); + unless (@anchor) + { + @anchor = (0,0); + $w->anchor('set', @anchor); + $w->see(@anchor); + } + + if ($w->info('anchor')) + { + # ! may not have any elements + # + $w->Callback('-browsecmd' => $w->info('anchor')); + $w->selection('clear'); + $w->selection('set', @anchor); + } + + $w->GoState('b0'); + } + +#---------------------------------------------------------------------- +# MULTIPLE SELECTION +#---------------------------------------------------------------------- + + +sub GoState_m0 + { + my ($w) = @_; + } + +sub GoState_m1 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x,$y); + if (@ent) + { + $w->anchor('set', @ent); + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-browsecmd' => @ent); + } + + $w->GoState('m2'); + } + +sub GoState_m2 + { + my ($w) = @_; + } + +sub GoState_m3 + { + my ($w) = @_; + + my (@ent) = $w->info('anchor'); + if (@ent) + { + $w->Callback('-browsecmd' => @ent); + } + + $w->GoState('m0'); + } + + +sub GoState_m4 + { + my ($w, $x, $y) = @_; + + my (@from) = $w->info('anchor'); + my (@to) = $w->mynearest($x, $y); + if (@to) + { + $w->selection('clear'); + $w->selection('set', @from, @to); + $w->Callback('-browsecmd' => @to); + } + $w->GoState('m5'); + } + +sub GoState_m5 + { + my ($w) = @_; + } + +sub GoState_m6 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->Callback('-browsecmd' => @ent); + } + $w->GoState('m0'); + } + +sub GoState_m7 + { + my ($w, $x, $y) = @_; + + my (@from) = $w->info('anchor'); + my (@to) = $w->mynearest($x, $y); + unless (@from) + { + @from = @to; + $w->anchor('set', @from); + } + if (@to) + { + $w->selection('clear'); + $w->selection('set', @from, @to); + $w->Callback('-browsecmd' => @to); + } + $w->GoState('m5'); + } + + +sub GoState_m8 { shift->StartScan() } + + +sub GoState_m9 { shift->DoScan() } + + +sub GoState_xm7 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-browsecmd' => @ent); + } + $w->GoState('m0'); + } + +#---------------------------------------------------------------------- +# EXTENDED SELECTION +#---------------------------------------------------------------------- + +sub GoState_e0 + { + my ($w) = @_; + } + +sub GoState_e1 + { + my ($w, $x, $y) = @_; + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->anchor('set', @ent); + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-browsecmd' => @ent); + } + $w->GoState('e2'); + } + + +sub GoState_e2 + { + my ($w) = @_; + } + +sub GoState_e3 + { + my ($w) = @_; + + my (@ent) = $w->info('anchor'); + if (@ent) + { + $w->Callback('-browsecmd' => @ent); + } + $w->GoState('e0'); + } + +sub GoState_e4 + { + my ($w, $x, $y) = @_; + + my (@from) = $w->info('anchor'); + my (@to) = $w->mynearest($x, $y); + if (@to) + { + $w->selection('clear'); + $w->selection('set', @from, @to); + $w->Callback('-browsecmd' => @to); + } + $w->GoState('e5'); + } + +sub GoState_e5 + { + my ($w) = @_; + } + +sub GoState_e6 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->Callback('-browsecmd' => @ent); + } + $w->GoState('e0'); + } + +sub GoState_e7 + { + my ($w, $x, $y) = @_; + + my (@from) = $w->info('anchor'); + my (@to) = $w->mynearest($x, $y); + unless (@from) + { + @from = @to; + $w->anchor('set', @from); + } + if (@to) + { + $w->selection('clear'); + $w->selection('set', @from, @to); + $w->Callback('-browsecmd' => @to); + } + $w->GoState('e5'); + } + +sub GoState_e8 { shift->StartScan(); } + +sub GoState_e9 { shift->DoScan(); } + +sub GoState_e10 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + if ($w->info('anchor')) + { + $w->anchor('set', @ent); + } + if ($w->selection('includes', @ent)) + { + $w->selection('clear', @ent); + } + else + { + $w->selection('set', @ent); + } + $w->Callback('-browsecmd' => @ent); + } + $w->GoState('e2'); + } + +sub GoState_xe7 + { + my ($w, $x, $y) = @_; + + my (@ent) = $w->mynearest($x, $y); + if (@ent) + { + $w->selection('clear'); + $w->selection('set', @ent); + $w->Callback('-command' => @ent); + } + $w->GoState('e0'); + } + + +#---------------------------------------------------------------------- +# HODGE PODGE +#---------------------------------------------------------------------- + +sub GoState_12 + { + my ($w, $x, $y) = @_; + + $w->CancelRepeat; # xxx will not work + $w->GoState(5, $x, $y); + } +#proc tixGrid:GoState-12 {w x y} { +# tkCancelRepeat +# tixGrid:GoState 5 $w $x $y +#} + +sub GoState_13 + { + # FIX: a) $ent or @ent, b) 13 is never called!!? same in Grid.tcl + my ($w, @ent, @oldEnt) = @_; + + my $data = $w->MainWindow->privateData('Tix'); + $data->{indicator} = \@ent; + $data->{oldEntry} = \@oldEnt; + $w->IndicatorCmd('<Arm>', @ent); + } +# set tkPriv(tix,oldEnt) $oldEnt +# tixGrid:IndicatorCmd $w <Arm> $ent +#} + +sub GoState_14 + { + my ($w, $x, $y) = @_; + + my $data = $w->MainWindow->privateData('Tix'); + if ($w->InsideArmedIndicator($x, $y)) + { + $w->anchor('set', @{ $data->{indicator} }); + $w->selection('clear'); + $w->selection('set', @{ $data->{indicator} }); + $w->IndicatorCmd('<Activate>', @{ $data->{indicator} }); + } + else + { + $w->IndicatorCmd('<Disarm>', @{ $data->{indicator} }); + } + delete($data->{indicator}); + $w->GoState(0); + } + +sub GoState_16 + { + my ($w, @ent) = @_; + + return unless (@ent); + if ($w->cget('-selectmode') ne 'single') + { + $w->Select(@ent); + $w->Browse(@ent); + } + } + +sub GoState_18 + { + my ($w) = @_; + + $w->CancelRepeat; ## xxx + $w->GoState(6, $Tk::x, $Tk::y); + } + +sub GoState_20 + { + my ($w, $x, $y) = @_; + + my $data = $w->MainWindow->privateData('Tix'); + if ($w->InsideArmedIndicator($x, $y)) + { + $w->IndicatorCmd('<Arm>', $data->{'indicator'}); + } + else + { + $w->GoState(21, $x, $y); + } + } + +sub GoState_21 + { + my ($w, $x, $y) = @_; + + my $data = $w->MainWindow->privateData('Tix'); + unless ($w->InsideArmedIndicator($x, $y)) + { + $w->IndicatorCmd('<Disarm>', $data->{'indicator'}); + } + else + { + $w->GoState(20, $x, $y); + } + } + +sub GoState_22 + { + my ($w) = @_; + my $data = $w->MainWindow->privateData('Tix'); + if (@{ $data->{oldEntry} }) + { + $w->anchor('set', @{ $data->{oldEntry} }); + } + else + { + $w->anchor('clear'); + } + $w->GoState(0); + } + + +#---------------------------------------------------------------------- +# callback actions +#---------------------------------------------------------------------- + +sub SetAnchor + { + my ($w, @ent) = @_; + + if (@ent) + { + $w->anchor('set', @ent); +# $w->see(@ent); + } + } + +# xxx check @ent of @$ent +sub Select + { + my ($w, @ent) = @_; + $w->selection('clear'); + $w->selection('set', @ent) + } + +# xxx check new After handling +sub StartScan + { + my ($w) = @_; + $Tk::afterId = $w->after(50, [AutoScan, $w]); + } + +sub DoScan + { + my ($w) = @_; + my $x = $Tk::x; + my $y = $Tk::y; + my $X = $Tk::X; + my $Y = $Tk::Y; + + my $out = 0; + if ($y >= $w->height) + { + $w->yview('scroll', 1, 'units'); + $out = 1; + } + if ($y < 0) + { + $w->yview('scroll', -1, 'units'); + $out = 1; + } + if ($x >= $w->width) + { + $w->xview('scroll', 2, 'units'); + $out = 1; + } + if ($x < 0) + { + $w->xview('scroll', -2, 'units'); + $out = 1; + } + if ($out) + { + $Tk::afterId = $w->after(50, ['AutoScan', $w]); + } + } + + +#proc tixGrid:CallBrowseCmd {w ent} { +# return +# +# set browsecmd [$w cget -browsecmd] +# if {$browsecmd != ""} { +# set bind(specs) {%V} +# set bind(%V) $ent +# +# tixEvalCmdBinding $w $browsecmd bind $ent +# } +#} + +#proc tixGrid:CallCommand {w ent} { +# set command [$w cget -command] +# if {$command != ""} { +# set bind(specs) {%V} +# set bind(%V) $ent +# +# tixEvalCmdBinding $w $command bind $ent +# } +#} + +# tixGrid:EditCell -- +# +# This command is called when "$w edit set $x $y" is called. It causes +# an SetEdit call when the grid's state is 0. +# + +sub EditCell + { + my ($w, $x, $y) = @_; + my $list = $w->privateData()->{'list'}; + if ($w->GetState == 0) + { + $w->SetEdit($x, $y); # xxx really correct ? once 2, once 4 args? + } + else + { + push(@$list, [ $w, 'SetEdit', $x, $y]); + } + } +#proc tixGrid:EditCell {w x y} { +# set list $w:_list +# global $list +# +# case [tixGrid:GetState $w] { +# {0} { +# tixGrid:SetEdit $w [list $x $y] +# } +# default { +# lappend $list [list tixGrid:SetEdit $w [list $x $y]] +# } +# } +#} + + +# tixGrid:EditApply -- +# +# This command is called when "$w edit apply $x $y" is called. It causes +# an CheckEdit call when the grid's state is 0. +# + +sub EditApply + { + my ($w) = @_; + my $list = $w->privateData()->{'list'}; + if ($w->GetState eq 0) + { + $w->CheckEdit; # xxx really correct ? once 2, once 4 args? + } + else + { + push(@$list, $w->CheckEdit); + } + } +#proc tixGrid:EditApply {w} { +# set list $w:_list +# global $list +# +# case [tixGrid:GetState $w] { +# {0} { +# tixGrid:CheckEdit $w +# } +# default { +# lappend $list [list tixGrid:CheckEdit $w] +# } +# } +#} + +# tixGrid:CheckEdit -- +# +# This procedure is called when the user sets the focus on a cell. +# If another cell is being edited, apply the changes of that cell. +# + +sub CheckEdit + { + my ($w) = @_; + my $edit = $w->privateData->{editentry}; + if (Tk::Exists($edit)) + { + # If it -command is not empty, it is being used for another cell. + # Invoke it so that the other cell can be updated. + # + if (defined $edit->cget('-command')) + { + $edit->invoke; # xxx no args?? + } + } + } + +sub SetFocus + { + my ($w) = @_; + if ($w->cget('-takefocus')) + { +$w->focus; +# # xxx translation of if ![string match $w.* [focus -displayof $w]] { +# my $hasfocus = $w->focus(-displayof => $w)->pathname; +# my $pathname = $w->pathname; +# if ($hasfocus =~ /\Q$pathname\E.*/) +# { +# $w->focus +# } + } + } + + +# tixGrid:SetEdit -- +# +# Puts a floatentry on top of an editable entry. +# + +sub SetEdit + { + my ($w, $px, $py) = @_; + + $w->CheckEdit; + + my $efc = $w->cget('-editnotifycmd'); + return unless ( defined($efc) && length($efc) ); + + unless ($w->Callback('-editnotifycmd' => $px, $py)) + { + print STDERR "editnotifycmd not defined or returned false\n"; + return; + } + + my $oldvalue; + if ($w->info('exists', $px, $py)) + { + # if entry doesn't support -text option. Can't edit it. + # + # If the application wants to force editing of an entry, it could + # delete or replace the entry in the editnotifyCmd procedure. + # + Tk::catch { $oldvalue = $w->entrycget($px, $py, '-text'); }; + if ($@) + { + return; + } + } + else + { + $oldvalue = ''; + } + + my @bbox = $w->info('bbox', $px, $py); + + my $edit = $w->privateData()->{__EDIT__}; + unless (Tk::Exists($edit)) + { + require Tk::FloatEntry; + $edit = $w->FloatEntry(); + $w->privateData()->{__EDIT__} = $edit; + } + $edit->configure(-command=>[\&DoneEdit, $w, $px, $py]); + $edit->post(@bbox); + $edit->configure(-value=>$oldvalue); +} + + +sub DoneEdit + { + my ($w, $x, $y, @args) = @_; + + my $edit = $w->privateData()->{__EDIT__}; + $edit->configure(-command=>undef); + $edit->unpost; + + # FIX xxx + # set value [tixEvent value] + my $value = $edit->get; + if ($w->info('exists', $x, $y)) + { + Tk::catch { $w->entryconfigure($x, $y, -text=>$value) }; + if ($@) + { + return + } + } + elsif ( length($value) ) + { + # This needs to be catch'ed because the default itemtype may + # not support the -text option + # + Tk::catch { $w->set($x,$y,-text $value); }; + if ($@) + { + return; + } + } + else + { + return; + } + $w->Callback('-editdonecmd' => $x, $y); + } + +1; +__END__ |