# 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
$DEBUG = (defined($ENV{USER
}) and $ENV{USER
} eq 'ach') ?
1 : 0;
print STDERR
"tixGrid: debug = $DEBUG\n" if $DEBUG;
$VERSION = '3.023'; # $Id: //depot/Tk8/TixGrid/TixGrid.pm#23 $
use Tk qw(Ev $XS_VERSION);
carp "\n".__PACKAGE__.' is deprecated' unless defined($Test::ntest);
Construct Tk::Widget '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
to_list_commands dragsite dropsite geometryinfo info
nearest selection sort );
# 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?
die "wrong args. Should be \$w->editSet(x,y)\n" unless @_ == 3;
die "wrong args. Should be \$w->editApply()\n" unless @_ == 1;
'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) ],
####################################################
## For button 2 scrolling. So TixGrid has 'standard'
## standard scrolling interface
# die "wrong # args: \$w->scanMark(x,y)\n" unless @_ == 3;
# $w->{__scanMarkXY__} = [ @_[1,2] ];
# die "wrong # args: \$w->scanDragto(x,y)\n" unless @_ == 3;
# my ($ox, $oy) = @{ $w->{__scanMarkXY__} };
### end button 2 scrolling stuff ####################
# 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>
$class->SUPER::ClassInit
($mw);
$mw->XYscrollBind($class);
$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')]);
$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 if $w->cget('-state') eq 'disabled';
return if $w->cget('-state') eq 'disabled';
return if $w->cget('-state') eq 'disabled';
#----------------------------------------------------------------------
#----------------------------------------------------------------------
return if $w->cget('-state') eq 'disabled';
print STDERR
"$w->DirKey($key)\n" if $DEBUG;
return if $w->cget('-state') eq 'disabled';
return if $w->cget('-state') eq 'disabled';
#----------------------------------------------------------------------
#----------------------------------------------------------------------
my $data = $w->privateData();
$data->{state} = 0 unless exists $data->{state};
$w->B1_Motion($Tk::x
, $Tk::y
);
sub Control_Button_Motion
$w->Control_B1_Motion($Tk::x
, $Tk::y
);
$w->privateData()->{state} = $state;
my ($w, $state) = (shift, shift);
print STDERR
'Gostate: ', $w->GetState, " --> $state, " if $DEBUG;
my $method = "GoState_$state";
print STDERR
'args=(', join(',',@_), ')'.
"\t(",$w->cget('-selectmode').
',',$w->cget('-selectunit').")\n" if $DEBUG;
%@
= (); # Workaround to prevent spurious loss of $@
eval { $w->$method(@_) };
print STDERR
"Error Gostate: '$state': ", $@
if $@
;
## ChgState is a fancy case statement
print STDERR
'ChgState(', join(',',@_,'['), join(',',@
$map,),']) ' if $DEBUG;
my $state = $w->GetState;
print STDERR
"$state --> $to \n" if $DEBUG;
print STDERR
"*no* chg for $state\n" if $DEBUG;
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#proc tixGrid:SelectSingle {w ent} {
# $w selection set [lindex $ent 0] [lindex $ent 1]
# tixGrid:CallBrowseCmd $w $ent
$w->selection('set', $n1, $n2);
#FIX: -options -browsecmd not implemented jet
#$w->Callback('-browsecmd' => $n1, $n2);
#----------------------------------------------------------------------
#----------------------------------------------------------------------
my $list = $w->privateData()->{list
};
return unless defined $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
#proc tixGrid:GoState-0 {w} {
# if [info exists $list] {
# foreach cmd [set $list] {
# if [info exists $list] {
my @ent = $w->mynearest($x,$y);
$w->selection('clear', 0, 0, 'max', 'max');
if ($w->cget('-selectmode') ne 'single')
my @ent = $w->mynearest($x,$y);
my (@ent) = $w->mynearest($x,$y);
my $mode = $w->cget('-selectmode');
elsif ($mode eq 'browse')
$w->selection('clear', 0, 0, 'max', 'max');
elsif ($mode eq 'multiple' ||
my (@anchor) = $w->anchor('get');
$w->selection('adjust', @anchor[0,1], @ent[0,1]);
my @ent = $w->mynearest($x,$y);
##############################################
# return scalar instead of errors
sub mynearest
{ shift->split_s2a('nearest', @_); }
sub myanchorGet
{ shift->split_s2a('anchor', 'get', @_); }
my @ent = $w->$method(@_);
@ent = split(/ /, $ent[0]) if @ent == 1;
print STDERR
join('|',"$method splitted '$tmp' =>",@ent,"\n") if $DEBUG;
#print STDERR join("|","$method splitted is okay :",@ent,"\n") if $DEBUG;
##############################################
my @ent = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-command' => @ent);
## - 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');
@anchor = $w->info($key, @anchor);
$w->anchor('set', @anchor);
#proc tixGrid:GoState-s8 {w key} {
# set anchor [$w info anchor]
# set anchor [$w info $key $anchor]
#print STDERR "GoState_s9 is not implemented\n";
my (@anchor) = $w->info('anchor');
$w->anchor('set', @anchor);
unless ($w->info('anchor'))
# ! may not have any elements
$w->Callback('-command' => $w->info('anchor'));
$w->selection('set', @anchor);
my (@anchor) = $w->info('anchor');
$w->anchor('set', @anchor);
unless ($w->info('anchor'))
# ! may not have any elements
$w->Callback('-browsecmd' => $w->info('anchor'));
$w->selection('set', @anchor);
#----------------------------------------------------------------------
#----------------------------------------------------------------------
my (@ent) = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
my (@ent) = $w->info('anchor');
$w->selection('set', @ent);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
my (@ent) = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
sub GoState_b5
{ shift->StartScan(); }
sub GoState_b6
{ shift->DoScan(); }
my (@ent) = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-command' => @ent);
my (@anchor) = $w->info('anchor');
@anchor = $w->info('key', @anchor);
$w->anchor('set', @anchor);
$w->selection('set', @anchor);
$w->Callback('-browsecmd' => @anchor);
my (@anchor) = $w->info('anchor');
$w->anchor('set', @anchor);
# ! may not have any elements
$w->Callback('-command' => $w->info('anchor'));
$w->selection('set', @anchor);
my (@anchor) = $w->info('anchor');
$w->anchor('set', @anchor);
# ! may not have any elements
$w->Callback('-browsecmd' => $w->info('anchor'));
$w->selection('set', @anchor);
#----------------------------------------------------------------------
#----------------------------------------------------------------------
my (@ent) = $w->mynearest($x,$y);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
my (@ent) = $w->info('anchor');
$w->Callback('-browsecmd' => @ent);
my (@from) = $w->info('anchor');
my (@to) = $w->mynearest($x, $y);
$w->selection('set', @from, @to);
$w->Callback('-browsecmd' => @to);
my (@ent) = $w->mynearest($x, $y);
$w->Callback('-browsecmd' => @ent);
my (@from) = $w->info('anchor');
my (@to) = $w->mynearest($x, $y);
$w->anchor('set', @from);
$w->selection('set', @from, @to);
$w->Callback('-browsecmd' => @to);
sub GoState_m8
{ shift->StartScan() }
sub GoState_m9
{ shift->DoScan() }
my (@ent) = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
#----------------------------------------------------------------------
#----------------------------------------------------------------------
my (@ent) = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
my (@ent) = $w->info('anchor');
$w->Callback('-browsecmd' => @ent);
my (@from) = $w->info('anchor');
my (@to) = $w->mynearest($x, $y);
$w->selection('set', @from, @to);
$w->Callback('-browsecmd' => @to);
my (@ent) = $w->mynearest($x, $y);
$w->Callback('-browsecmd' => @ent);
my (@from) = $w->info('anchor');
my (@to) = $w->mynearest($x, $y);
$w->anchor('set', @from);
$w->selection('set', @from, @to);
$w->Callback('-browsecmd' => @to);
sub GoState_e8
{ shift->StartScan(); }
sub GoState_e9
{ shift->DoScan(); }
my (@ent) = $w->mynearest($x, $y);
if ($w->selection('includes', @ent))
$w->selection('clear', @ent);
$w->selection('set', @ent);
$w->Callback('-browsecmd' => @ent);
my (@ent) = $w->mynearest($x, $y);
$w->selection('set', @ent);
$w->Callback('-command' => @ent);
#----------------------------------------------------------------------
#----------------------------------------------------------------------
$w->CancelRepeat; # xxx will not work
#proc tixGrid:GoState-12 {w x y} {
# tixGrid:GoState 5 $w $x $y
# 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
my $data = $w->MainWindow->privateData('Tix');
if ($w->InsideArmedIndicator($x, $y))
$w->anchor('set', @
{ $data->{indicator
} });
$w->selection('set', @
{ $data->{indicator
} });
$w->IndicatorCmd('<Activate>', @
{ $data->{indicator
} });
$w->IndicatorCmd('<Disarm>', @
{ $data->{indicator
} });
delete($data->{indicator
});
if ($w->cget('-selectmode') ne 'single')
$w->GoState(6, $Tk::x
, $Tk::y
);
my $data = $w->MainWindow->privateData('Tix');
if ($w->InsideArmedIndicator($x, $y))
$w->IndicatorCmd('<Arm>', $data->{'indicator'});
my $data = $w->MainWindow->privateData('Tix');
unless ($w->InsideArmedIndicator($x, $y))
$w->IndicatorCmd('<Disarm>', $data->{'indicator'});
my $data = $w->MainWindow->privateData('Tix');
if (@
{ $data->{oldEntry
} })
$w->anchor('set', @
{ $data->{oldEntry
} });
#----------------------------------------------------------------------
#----------------------------------------------------------------------
# xxx check @ent of @$ent
$w->selection('set', @ent)
# xxx check new After handling
$Tk::afterId
= $w->after(50, [AutoScan
, $w]);
$w->yview('scroll', 1, 'units');
$w->yview('scroll', -1, 'units');
$w->xview('scroll', 2, 'units');
$w->xview('scroll', -2, 'units');
$Tk::afterId
= $w->after(50, ['AutoScan', $w]);
#proc tixGrid:CallBrowseCmd {w ent} {
# set browsecmd [$w cget -browsecmd]
# if {$browsecmd != ""} {
# tixEvalCmdBinding $w $browsecmd bind $ent
#proc tixGrid:CallCommand {w ent} {
# set command [$w cget -command]
# tixEvalCmdBinding $w $command bind $ent
# This command is called when "$w edit set $x $y" is called. It causes
# an SetEdit call when the grid's state is 0.
my $list = $w->privateData()->{'list'};
$w->SetEdit($x, $y); # xxx really correct ? once 2, once 4 args?
push(@
$list, [ $w, 'SetEdit', $x, $y]);
#proc tixGrid:EditCell {w x y} {
# case [tixGrid:GetState $w] {
# tixGrid:SetEdit $w [list $x $y]
# lappend $list [list tixGrid:SetEdit $w [list $x $y]]
# This command is called when "$w edit apply $x $y" is called. It causes
# an CheckEdit call when the grid's state is 0.
my $list = $w->privateData()->{'list'};
$w->CheckEdit; # xxx really correct ? once 2, once 4 args?
push(@
$list, $w->CheckEdit);
#proc tixGrid:EditApply {w} {
# case [tixGrid:GetState $w] {
# lappend $list [list tixGrid:CheckEdit $w]
# 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.
my $edit = $w->privateData->{editentry
};
# 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??
if ($w->cget('-takefocus'))
# # 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.*/)
# Puts a floatentry on top of an editable entry.
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";
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'); };
my @bbox = $w->info('bbox', $px, $py);
my $edit = $w->privateData()->{__EDIT__
};
unless (Tk
::Exists
($edit))
$edit = $w->FloatEntry();
$w->privateData()->{__EDIT__
} = $edit;
$edit->configure(-command
=>[\
&DoneEdit
, $w, $px, $py]);
$edit->configure(-value
=>$oldvalue);
my ($w, $x, $y, @args) = @_;
my $edit = $w->privateData()->{__EDIT__
};
$edit->configure(-command
=>undef);
# set value [tixEvent value]
if ($w->info('exists', $x, $y))
Tk
::catch
{ $w->entryconfigure($x, $y, -text
=>$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); };
$w->Callback('-editdonecmd' => $x, $y);