package ZincText; sub new { my $proto = shift; my $type = ref($proto) || $proto; my ($zinc) = @_; my $self = {}; $zinc->bind('text', '<1>' => sub {startSel($zinc)}); $zinc->bind('text', '<2>' => sub {pasteSel($zinc)}); $zinc->bind('text', '' => sub {extendSel($zinc)}); $zinc->bind('text', '' => sub {extendSel($zinc)}); $zinc->bind('text', '' => sub { my $e = $zinc->XEvent(); my($x, $y) = ($e->x, $e->y); $zinc->select('adjust', 'current', "\@$x,$y"); }); $zinc->bind('text', '' => sub {moveCur($zinc, -1);}); $zinc->bind('text', '' => sub {moveCur($zinc, 1);}); $zinc->bind('text', '' => sub {setCur($zinc, 'up');}); $zinc->bind('text', '' => sub {setCur($zinc, 'down');}); $zinc->bind('text', '' => sub {setCur($zinc, 'bol');}); $zinc->bind('text', '' => sub {setCur($zinc, 'bol');}); $zinc->bind('text', '' => sub {setCur($zinc, 'eol');}); $zinc->bind('text', '' => sub {setCur($zinc, 'eol');}); $zinc->bind('text', '' => sub {setCur($zinc, 0);}); $zinc->bind('text', '' => sub {setCur($zinc, 'end');}); $zinc->bind('text', '' => sub {insertKey($zinc);}); $zinc->bind('text', '' => sub {insertKey($zinc);}); $zinc->bind('text', '' => sub { insertChar($zinc, chr(10)); }); $zinc->bind('text', '' => sub {textDel($zinc, -1)}); $zinc->bind('text', '' => sub {textDel($zinc, -1)}); $zinc->bind('text', '' => sub {textDel($zinc, 0)}); bless ($self, $type); return $self; } sub pasteSel { my ($w) = @_; my $e = $w->XEvent; my($x, $y) = ($e->x(), $e->y()); my @it = $w->focus(); if (@it != 0) { eval { $w->insert(@it, "\@$x,$y", $w->SelectionGet()); }; } } sub insertChar { my ($w, $c) = @_; my @it = $w->focus(); my @selit = $w->select('item'); if (@it == 0) { return; } if ((scalar(@selit) == scalar(@it)) && ($selit[0] == $it[0]) && ($selit[1] == $it[1])) { $w->dchars(@it, 'sel.first', 'sel.last'); } $w->insert(@it, 'insert', $c); } sub insertKey { my ($w) = @_; my $c = $w->XEvent->A(); if ((ord($c) < 32) || (ord($c) == 128)) { return; } insertChar($w, $c); } sub setCur { my ($w, $where) = @_; my @it = $w->focus(); if (@it != 0) { $w->cursor(@it, $where); } } sub moveCur { my ($w, $dir) = @_; my @it = $w->focus(); my $index; if (@it != 0) { $index = $w->index(@it, 'insert'); $w->cursor(@it, $index + $dir); } } sub startSel { my($w) = @_; my $e = $w->XEvent; my($x, $y) = ($e->x(), $e->y()); my $part = $w->currentpart(1); $w->cursor('current', $part, "\@$x,$y"); $w->focus('current', $part); $w->Tk::focus(); $w->select('from', 'current', $part, "\@$x,$y"); } sub extendSel { my($w) = @_; my $e = $w->XEvent; my($x, $y) = ($e->x, $e->y); my $part = $w->currentpart(1); $w->select('to', 'current', $part, "\@$x,$y"); } sub textDel { my($w, $dir) = @_; my @it = $w->focus(); my @selit = $w->select('item'); my $ind; if (@it == 0) { return; } if ((scalar(@selit) == scalar(@it)) && ($selit[0] == $it[0]) && ($selit[1] == $it[1])) { $w->dchars(@it, 'sel.first', 'sel.last'); } else { $ind = $w->index(@it, 'insert') + $dir; $w->dchars(@it, $ind, $ind) if ($ind >= 0); } } 1;