Here is a little example that ought to get you going. The trick is to bind to mouse button 3, or whatever else you can. The original is from an advanced perl programming book, but it didn't use strict. :-)You will need to provide a couple of bitmap files for open-folder and close-folder, to run the example. Here they are, save them to files.
open_folder.xbm
#define openfolder_width 16
#define openfolder_height 10
static unsigned char openfolder_bits[] = {
0xfc, 0x00, 0x02, 0x07, 0x01, 0x08, 0xc1, 0xff, 0x21, 0x80, 0x11, 0
+x40,
0x09, 0x20, 0x05, 0x10, 0x03, 0x08, 0xff, 0x07};
folder.xbm
#define folder_width 16
#define folder_height 10
static unsigned char folder_bits[] = {
0xfc, 0x00, 0x02, 0x07, 0x01, 0x08, 0x01, 0x08, 0x01, 0x08, 0x01, 0
+x08,
0x01, 0x08, 0x01, 0x08, 0x01, 0x08, 0xff, 0x07};
#!/usr/bin/perl
#Advanced Perl Programming Chapter 14 -updated
use warnings;
#use diagnostics;
use Tk;
require Tk::HList;
my $top = MainWindow->new();
my $hlist = $top->Scrolled(
'HList',
drawbranch => 1, # yes, draw branches
separator => '/', # filename separator
indent => 15, # pixels
command => \&show_or_hide_dir
);
$hlist->pack( -fill => 'both', -expand => 'y' );
$hlist->bind("<Button-3>" => [\&menu_popup, Ev('x'), Ev('y')]);
# Read bitmap files and create "image" objects.
$open_folder_bitmap = $top->Bitmap( -file => './open_folder.xbm' );
$closed_folder_bitmap = $top->Bitmap( -file => './folder.xbm' );
# Start with the current directory
show_or_hide_dir(".");
MainLoop();
#---------------------------------------------------------------------
+--
sub menu_popup {
my ($wg,$x1,$y1) = @_;
print "@_\n";
my ($x, $y) = $top->pointerxy;
print "\t$x $y\n";
my $s = $hlist->nearest($y - $hlist->rooty);
print "$s\n";
$hlist->selectionClear();
$hlist->selectionSet($s);
#pop a dialogbox here and get new text
#you can probably popup a editable label to
#get the new value
my $newtext = 'foobar';
$hlist->itemConfigure($s,0,-text=> $newtext );
# here is some other unsuccesful hacks I tried to make a popup
# $wg->eventGenerate('<Button-1>', -x => $x , -y => $y );
# if (my $sel=$wg->info("selection")) {
# $top->Popup(-popover => "cursor",
# -popanchor => 'nw')
# }
}
sub show_or_hide_dir { # Called when an entry is double-clicked
my $path = $_[0];
return if ( !-d $path ); # Not a directory.
if ( $hlist->info( 'exists', $path ) ) {
# Toggle the directory state.
# We know that a directory is open if the next entry is a
# a substring of the current path
$next_entry = $hlist->info( 'next', $path );
if ( !$next_entry || ( index( $next_entry, "$path/" ) == -1 )
+) {
# Nope. open it
$hlist->entryconfigure( $path, -image => $open_folder_bitm
+ap );
add_dir_contents($path);
}
else {
# Yes. Close it by changing the icon, and deleting its chi
+ldren
$hlist->entryconfigure( $path, -image => $closed_folder_bi
+tmap );
$hlist->delete( 'offsprings', $path );
}
}
else {
die "'$path' is not a directory\n" if ( !-d $path );
$hlist->add(
$path,
-itemtype => 'imagetext',
-image => $open_folder_bitmap,
-text => $path
);
add_dir_contents($path);
}
}
sub add_dir_contents {
my $path = $_[0];
my $oldcursor = $top->cget('cursor'); # Remember current cursor
+, and
$top->configure( -cursor => 'watch' ); # change cursor to watch
$top->update();
my @files = glob "$path/*";
foreach $file (@files) {
$file =~ s|//|/|g;
( $text = $file ) =~ s|^.*/||g;
if ( -d $file ) {
$hlist->add(
$file,
-itemtype => 'imagetext',
-image => $closed_folder_bitmap,
-text => $text
);
}
else {
$hlist->add(
$file,
-itemtype => 'text',
-text => $text
);
}
}
$top->configure( -cursor => $oldcursor );
}
|