home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Tk / DragDrop.pm < prev    next >
Encoding:
Perl POD Document  |  1997-08-10  |  5.9 KB  |  279 lines

  1. package Tk::DragDrop;
  2. require Tk::DragDrop::Common;
  3. require Tk::Toplevel;
  4. require Tk::Label;
  5. @ISA = qw(Tk::DragDrop::Common Tk::Toplevel);
  6.  
  7. # This is a little tricky, ISA says 'Toplevel' but we 
  8. # define a Tk_cmd to actually build a 'Label', then 
  9. # use Tix's wmRelease in Populate to make it a toplevel. 
  10. sub Tk_cmd { \&Tk::label }
  11.  
  12. Construct Tk::Widget 'DragDrop';
  13.  
  14. use strict;
  15. use vars qw(%type @types);
  16. use Carp;
  17.  
  18.  
  19. sub ClassInit
  20. {
  21.  my ($class,$mw) = @_;
  22.  $mw->bind($class,'<Map>','Mapped');
  23.  $mw->bind($class,'<Any-KeyPress>','Done');
  24.  $mw->bind($class,'<Any-ButtonRelease>','Drop');
  25.  $mw->bind($class,'<Any-Motion>','Drag');
  26.  return $class;
  27. }
  28.  
  29.  
  30. sub Populate
  31. {
  32.  my ($token,$args) = @_;
  33.  my $parent = $token->parent;
  34.  $token->wmRelease;
  35.  $token->withdraw;
  36.  $token->overrideredirect(1);
  37.  $token->saveunder(1);     
  38.  $token->ConfigSpecs(-sitetypes       => ['METHOD','siteTypes','SiteTypes',undef],
  39.                      -startcommand    => ['CALLBACK',undef,undef,undef],
  40.                      -predropcommand  => ['CALLBACK',undef,undef,undef],
  41.                      -postdropcommand => ['CALLBACK',undef,undef,undef],
  42.                      -cursor          => ['SELF','cursor','Cursor','hand2'],
  43.                      -text            => ['SELF','text','Text',$parent->class],
  44.                      -handlers        => ['SETMETHOD','handlers','Handlers',[[[$token,'SendText']]]],  
  45.                      -selection       => ['SETMETHOD','selection','Selection',"dnd_" . $parent->toplevel->name],  
  46.                      -event           => ['SETMETHOD','event','Event','<B1-Motion>']
  47.                     );
  48.  $token->{InstallHandlers} = 0;
  49.  $args->{-borderwidth} = 3;
  50.  $args->{-relief} = 'flat';
  51.  $args->{-takefocus} = 1;
  52. }
  53.  
  54. sub sitetypes
  55. {
  56.  my ($w,$val) = @_;
  57.  confess "Not a widget $w" unless (ref $w);
  58.  my $var = \$w->{Configure}{'-sitetypes'};
  59.  if (@_ > 1)
  60.   {
  61.    if (defined $val)
  62.     {
  63.      $val = [$val] unless (ref $val);
  64.      my $type;
  65.      foreach $type (@$val)
  66.       {
  67.        Tk::DragDrop->import($type);
  68.       }
  69.     }
  70.    $$var = $val;
  71.   }
  72.  return (defined $$var) ? $$var : \@types;
  73. }
  74.  
  75. sub SendText
  76. {
  77.  my ($w,$offset,$max) = @_;
  78.  my $s = substr($w->cget('-text'),$offset);
  79.  $s = substr($s,0,$max) if (length($s) > $max);
  80.  return $s;
  81. }
  82.  
  83. sub handlers
  84. {
  85.  my ($token,$opt,$value) = @_;
  86.  $token->{InstallHandlers} = (defined($value) && @$value);
  87.  $token->{'handlers'}  = $value;
  88. }
  89.  
  90. sub selection
  91. {
  92.  my ($token,$opt,$value) = @_;
  93.  my $handlers = $token->{'handlers'};
  94.  $token->{InstallHandlers} = (defined($handlers) && @$handlers);
  95. }
  96.  
  97. sub event
  98. {
  99.  my ($w,$opt,$value) = @_;
  100.  # delete old bindings
  101.  $w->parent->Tk::bind($value,[$w,'StartDrag']);
  102. }
  103.  
  104. sub Mapped
  105. {
  106.  my ($token) = @_;
  107.  my $e = $token->parent->XEvent;
  108.  $token->grabGlobal;
  109.  $token->focus;
  110.  if (defined $e)
  111.   {
  112.    my $X = $e->X;
  113.    my $Y = $e->Y;
  114.    $token->MoveWindow($X,$Y); 
  115.    $token->NewDrag;
  116.    $token->FindSite($X,$Y);
  117.   }
  118. }
  119.  
  120. sub FindSite
  121. {
  122.  my ($token,$X,$Y) = @_;
  123.  my $types = $token->sitetypes;
  124.  if (defined $types && @$types)
  125.   {
  126.    my $type;
  127.    foreach $type (@$types)
  128.     {
  129.      my $site;
  130.      my $class = $type{$type};
  131.      if (defined $class)
  132.       {
  133.        foreach $site ($class->SiteList($token))
  134.         {
  135.          return $site if ($site->Over($X,$Y));
  136.         }
  137.       }
  138.     }
  139.   }
  140.  else
  141.   {
  142.    warn "No sitetypes";
  143.   }
  144.  return undef;
  145. }
  146.  
  147. sub NewDrag
  148. {
  149.  my ($token) = @_;
  150.  my $types = $token->sitetypes;
  151.  if (defined $types && @$types)
  152.   {
  153.    my $type;
  154.    foreach $type (@$types)
  155.     {
  156.      my $class = $type{$type};
  157.      if (defined $class)
  158.       {
  159.        $class->CheckSites($token);
  160.       }
  161.     }
  162.   }
  163. }
  164.  
  165. sub Drag
  166. {
  167.  my $token = shift;
  168.  my $e = $token->XEvent;
  169.  $token = $token->toplevel;
  170.  my $X  = $e->X;
  171.  my $Y  = $e->Y;
  172.  my $site = $token->FindSite($X,$Y);
  173.  my $over = $token->{'Over'};
  174.  if ($over)
  175.   {
  176.    if (!defined($site) || !$over->Match($site))
  177.     {
  178.      $over->Leave($token,$e);
  179.      $site->Enter($token,$e) if (defined $site);
  180.     }
  181.    else
  182.     {
  183.      $over->Motion($token,$e);
  184.     }
  185.   }
  186.  elsif (defined $site)
  187.   {
  188.    $site->Enter($token,$e);
  189.   }
  190.  $token->MoveWindow($X,$Y);
  191. }
  192.  
  193. sub Done
  194. {
  195.  my $token = shift;
  196.  my $e     = $token->XEvent;
  197.  $token    = $token->toplevel;
  198.  my $over  = $token->{'Over'};
  199.  $over->Leave($token,$e) if (defined $over);
  200.  my $w     = $token->parent;
  201.  eval {local $SIG{__DIE__}; $token->grabRelease };
  202.  $token->withdraw;
  203.  delete $w->{'Dragging'};
  204.  $w->update;
  205. }
  206.  
  207. sub HandleLoose
  208. {
  209.  my ($w,$seln) = @_;
  210.  return "";
  211. }
  212.  
  213. sub Drop
  214. {
  215.  my $ewin  = shift;
  216.  my $e     = $ewin->XEvent;
  217.  my $token = $ewin->toplevel;
  218.  Done($ewin);
  219.  my $site  = $token->FindSite($e->X,$e->Y);
  220.  if (defined $site)
  221.   {
  222.    my $seln = $token->cget('-selection'); 
  223.    unless ($token->Callback(-predropcommand => $seln, $site))
  224.     {
  225.      my $w = $token->parent;  
  226.      if ($token->{InstallHandlers})
  227.       {                       
  228.        my $h;                 
  229.        foreach $h (@{$token->cget('-handlers')})
  230.         {                     
  231.          $w->SelectionHandle('-selection' => $seln,@$h);
  232.         }                     
  233.        $token->{InstallHandlers} = 0;
  234.       }                       
  235.      if (!$w->IS($w->SelectionOwner('-selection'=>$seln)))              
  236.       {                                                                 
  237.        $w->SelectionOwn('-selection' => $seln, -command => [\&HandleLoose,$w,$seln]);
  238.       }                                                                 
  239.      $site->Drop($w,$seln,$e); 
  240.      $token->Callback(-postdropcommand => $seln);
  241.     }
  242.   }
  243. }
  244.  
  245. sub StartDrag
  246. {
  247.  my $token = shift;
  248.  my $w     = $token->parent;
  249.  unless ($w->{'Dragging'})
  250.   {
  251.    my $e = $w->XEvent;
  252.    my $X = $e->X;
  253.    my $Y = $e->Y;
  254.    my $was = $token->{'XY'};
  255.    if ($was)
  256.     {
  257.      if ($was->[0] != $X || $was->[1] != $Y)
  258.       {
  259.        unless ($token->Callback('-startcommand'))
  260.         {
  261.          delete $token->{'XY'};  
  262.          $w->{'Dragging'} = $token;
  263.          $token->MoveWindow($X,$Y);
  264.          $token->raise;          
  265.          $token->deiconify;      
  266.          $token->FindSite($X,$Y);
  267.         }
  268.       }
  269.     }
  270.    else
  271.     {
  272.      $token->{'XY'} = [$X,$Y];
  273.     }
  274.   }
  275. }
  276.  
  277.  
  278. 1;
  279.