#!/usr/local/bin/perl -w use Tk; use Tk::TableMatrix; require Tk::JBrowseEntry; require Tk::DragDrop; require Tk::DropSite; use strict; my $tm_array = {}; my $t; my @drag = (); my @drop = (); my @pos = (0, 0); my @old_pos = (0, 0); sub switch_cells {  if ($drag[0] == $drop[0]) # Selbe Zeile   {    if ($drag[1] >= 0) # Kein Titel     {      my $drag_coords = $drag[0].','.$drag[1];      my $drop_coords = $drop[0].','.$drop[1];      my $drag_val = $tm_array->{$drag_coords};      my $drop_val = $tm_array->{$drop_coords};      $t->set($drop_coords, $drag_val);      $tm_array->{$drop_coords} = $drag_val;      $t->set($drag_coords, $drop_val);      $tm_array->{$drag_coords} = $drop_val;     }   } } my $start_row = -3; my $end_row = 50; my $start_col = -1; my $end_col = 50; my $display_cols = 10; my $display_rows = 10; my $nr_rows = $end_row - $start_row + 1; my $nr_cols = $end_col - $start_col + 1; my $title_rows = ($start_row < 0) ? (abs($start_row)) : (0); my $title_cols = ($start_col < 0) ? (abs($start_col)) : (0); foreach my $row  (($start_row - $title_rows)..4) {  foreach my $col (($start_col - $title_cols)..$end_col)   {    $tm_array->{"$row,$col"} = "$row:$col";   } } my $top = MainWindow->new; $top->geometry('870x300'); $top->bind( '', [ sub { $_[0]->yviewScroll(-($_[1]/120)*3, 'units'); }, Tk::Ev('D') ] ); $t = $top->Scrolled( 'TableMatrix',                     -titlerows => $title_rows,   -titlecols => $title_cols,                     -rows =>      $nr_rows,      -cols =>      $nr_cols,                     -height =>    $display_rows, -width =>     $display_cols,                     -variable => $tm_array,                     -roworigin => $start_row,                     -colorigin => $start_col,                     -colstretchmode => 'none',                     -rowstretchmode => 'none',                     -selectmode => 'single',                     -drawmode => 'fast',                     -maxwidth => 800,                     -maxheight => 600,                     -rowheight => -20,                     -colwidth => -200,                     -resizeborders => 'none',                     -sparsearray => 0,                     -selecttitle => 0,                                         -state => 'disabled',                     -font => ['Tahoma', 10, 'bold'],                     -bg => '#D4D0C8',                     -fg => '#000000' ); $t->tagConfigure('Normal',       -bg => '#D4D0C8', -fg => 'black'); $t->tagConfigure('DragSelected', -bg => '#EEEE11', -fg => 'black'); #$t->tagConfigure('DarkRed',      -bg => '#881111', -fg => 'black'); #$t->tagConfigure('LightRed',     -bg => '#EE9999', -fg => 'black'); #$t->tagConfigure('DarkGreen',    -bg => '#118888', -fg => 'black'); #$t->tagConfigure('LightGreen',   -bg => '#99EEEE', -fg => 'black'); my $cb_use = $t->Checkbutton( -text => 'nutzen' ); my @test_arr = ( 'TEXT', 'ZAHL', '#.## ¤', '#.## ¤ / # ¤', 'PLZ', 'TT.MM.JJJJ', 'TT.MM.JJ' ); my $test_var = $test_arr[0]; my $be_format = $t->JBrowseEntry( -label => '', -variable => \$test_var, -choices => \@test_arr,                                  -state => 'normal', -font => ['Tahoma', 8], -width => 10 ); my $lbl_hl = $top->Label(-text => "Headline"); $t->windowConfigure("-3,0", -window=>$cb_use); $t->windowConfigure("-2,0", -window=>$be_format); $t->windowConfigure("-1,0", -window=>$lbl_hl); my $dragging = 0; my $dragscroll_handler; my $dragscroll_delay = 150; my $dragspeed_delay = 50; my $nr_repeated = 0; my $speed_repeat = 10; sub handle_dragscroll {  if ($dragging == 0)   {    $dragscroll_handler->cancel;   }  my ($x_scrollbar_width, $y_scrollbar_height) = (21, 21);  my ($mouse_x, $mouse_y) = $t->pointerxy;  my ($x_left, $x_right) = ($t->rootx, $t->rootx + $t->width);  my ($y_top, $y_bottom) = ($t->rooty, $t->rooty + $t->height);  my $x_scroll = ($mouse_x < ($x_left + $x_scrollbar_width)) ? (-1) : (($mouse_x < $x_right) ? (0) : (1));  my $y_scroll = ($mouse_y < $y_top) ? (-1) : (($mouse_y < ($y_bottom - $y_scrollbar_height)) ? (0) : (1));  if (($x_scroll) == 0 and ($y_scroll == 0))   {    $dragscroll_handler->time($dragscroll_delay) unless ($nr_repeated == 0);    $nr_repeated = 0;   }  else   {    $nr_repeated++;    $dragscroll_handler->time($dragspeed_delay) if ($nr_repeated >= $speed_repeat);   }  $t->xviewScroll($x_scroll, 'units');  $t->yviewScroll($y_scroll, 'units'); } my ($dnd_t, $ds_t); $dnd_t = $t->DragDrop( -event => '',                       -sitetypes => [qw(Local)],                       -startcommand =>  sub {                                              my @coords = split(",", $t->index('@'.($t->pointerx - $t->rootx).','.($t->pointery - $t->rooty)));                                              if (($coords[0] >= 0) and ($coords[1] >= 0))                                               {                                                $dragging = 1;                                                $dragscroll_handler = $top->repeat($dragscroll_delay, \&handle_dragscroll);                                                $t->tagCell('Normal', $drop[0].','.$drop[1]) if (@drop);                                                $t->tagCell('Normal', $drag[0].','.$drag[1]) if (@drag);                                                @drag = @coords;                                                @old_pos = @pos;                                                  @pos = @drag;                                                $dnd_t->configure( -text => $tm_array->{$drag[0].','.$drag[1]} );                                                $t->tagCell('DragSelected', $drag[0].','.$drag[1]);                                                return 0;                                               }                                              else                                               { return(1); }                                             } ); $dnd_t->bind('', sub { $dragging = 0; } ); $ds_t = $t->DropSite ( -droptypes     => ['Local'],                       -dropcommand   => sub {                                              $dragging = 0;                                              $dragscroll_handler->cancel;                                              @drop = split(",", $t->index('@'.($t->pointerx - $t->rootx).','.($t->pointery - $t->rooty)));                                              @old_pos = @pos;                                                @pos = @drop;                                              $t->tagCell('Normal', $drag[0].','.$drag[1]);                                              $t->tagCell('DragSelected', $drop[0].','.$drop[1]);                                                              &switch_cells;                                             } ); my $button = $top->Button( -text => 'Exit', -width => 135, -command => sub{ $top->destroy } ); $t->place( -x =>  20, -y => 20 ); $button->place( -x => 20, -y => 260 ); $t->tagCell('DragSelected', $pos[0].','.$pos[1]);   sub change_position {    my ($y, $x) = @_;  my @new_pos = ($pos[0] + $y, $pos[1] + $x);  return if (($new_pos[0] < 0) or ($new_pos[0] > $end_row) or ($new_pos[1] < 0) or ($new_pos[1] > $end_col));  $t->tagCell('Normal', $pos[0].','.$pos[1]);  $t->tagCell('DragSelected', $new_pos[0].','.$new_pos[1]);      @old_pos = @pos;    @pos = @new_pos;  $t->see(join(",", @pos)); } $top->bind( '',  sub { &change_position(  0, -1 ); } ); $top->bind( '', sub { &change_position(  0,  1 ); } ); $top->bind( '',    sub { &change_position( -1,  0 ); } ); $top->bind( '',  sub { &change_position(  1,  0 ); } ); Tk::MainLoop;