Since I've mentioned the project so many times in the chatterbox
and many people have shown interest, I thought it would be
fair to let you all see what I have up till now. Updates will
come later.
.
# These variables are global, so they don't have to be passed through
+to every
# subroutine
use vars qw (
$PROGRAM_TITLE
$BGCOLOR
$ACTIVE_BGCOLOR
$SOUNDDIR
$CURRENT_CATEGORY
$CURRENT_PAGE
$INDEXFILE
$CATFILE
$SOUND_EXT
$IMG_EXT
$NEXT_IMG
$PREV_IMG
$UP_IMG
$MAX_HEIGHT
$MAX_WIDTH
$BORDER_WIDTH
$SELECTED_BUTTON
@BUTTONS
);
#---------------------------------------------------------------------
+---------
# Configuration-stuff
$PROGRAM_TITLE = "pVoice";
$BGCOLOR = 'white';
$ACTIVE_BGCOLOR = 'red';
$SOUNDDIR = "./data";
$CURRENT_CATEGORY = "";
$CURRENT_PAGE = 1;
$INDEXFILE = "index.txt";
$CATFILE = "cat.txt";
$SOUND_EXT = "wav";
$IMG_EXT = "jpg";
$NEXT_IMG = "volgende.$IMG_EXT"; # next-image
$PREV_IMG = "vorige.$IMG_EXT"; # previous-image
$UP_IMG = "omhoog.$IMG_EXT"; # up-image
$MAX_HEIGHT = 120;
$MAX_WIDTH = 100;
$BORDER_WIDTH = 10;
$SELECTED_BUTTON = 0;
@BUTTONS = ();
# Create the main window
my $main = MainWindow->new(-background => $BGCOLOR);
# Maximize the window
my ($screenw, $screenh) = ($main->screenwidth, $main->screenheight);
$main->geometry($screenw."x".$screenh);
# Write the title of the window
$main->title($PROGRAM_TITLE);
#create the window for the images
my $mainframe = $main->Frame(-background => $BGCOLOR)->pack();
# -fill=>'both',
# -expand=>1
# );
#configure the grid to constant cellsizes
$mainframe->gridColumnconfigure(0, -minsize => $MAX_WIDTH + 2*$BORDER_
+WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridColumnconfigure(1, -minsize => $MAX_WIDTH + 2*$BORDER_
+WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridColumnconfigure(2, -minsize => $MAX_WIDTH + 2*$BORDER_
+WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridColumnconfigure(3, -minsize => $MAX_WIDTH + 2*$BORDER_
+WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridRowconfigure (0, -weight => 0, -pad => 4);
$mainframe->gridRowconfigure (1, -minsize => $MAX_HEIGHT + 2*$BORDER
+_WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridRowconfigure (2, -minsize => $MAX_HEIGHT + 2*$BORDER
+_WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridRowconfigure (3, -minsize => $MAX_HEIGHT + 2*$BORDER
+_WIDTH,
-weight => 0, -pad => 4);
$mainframe->gridRowconfigure (4, -minsize => $MAX_HEIGHT + 2*$BORDER
+_WIDTH,
-weight => 0, -pad => 4);
# Write the header
my $label=$main->Label(-text => $PROGRAM_TITLE, -background => $BGCOLO
+R);
$label->grid(
-in => $mainframe,
-column => 0,
-row => 0,
-columnspan=> 4
);
# Read the categoryfile and draw the first page with category-buttons
my @categories = readcategoryfile();
drawcatpage($mainframe, \@categories);
# Make the first button active
$BUTTONS[$SELECTED_BUTTON]->configure(-state => 'active');
# At present time only left and right mousebuttons are used...
$main->bind('<Button-3>',
sub {
$BUTTONS[$SELECTED_BUTTON]->configure(
-state => 'normal');
if ($SELECTED_BUTTON < @BUTTONS -1)
{$SELECTED_BUTTON++}
else {$SELECTED_BUTTON=0}
$BUTTONS[$SELECTED_BUTTON]->configure(
-state => 'active');
}
);
$main->bind('<Button-1>', sub {
$BUTTONS[$SELECTED_BUTTON]->invoke;
}
);
MainLoop;
#---------------------------------------------------------------------
+---------
sub play
# Play the sound
{
my ($label) = @_;
my $file = "$SOUNDDIR/$CURRENT_CATEGORY/$label.$SOUND_EXT";
warn "File does not exist ($file)" unless (-f $file);
return sub {system('play', "$file")} if $^O ne 'MSWin32';
return sub {Win32::Sound::Play($file)} if $^O eq 'MSWin32';
}
#---------------------------------------------------------------------
+---------
sub readcurrentcategoryindex
{
my (@categorycontents, $page, $index, $file);
# Parse index.txt in the category directory and open the files
open (INDEX, "$SOUNDDIR/$CURRENT_CATEGORY/$INDEXFILE") || die "Can
+'t open $SOUNDDIR/$CURRENT_CATEGORY/$INDEXFILE: $!\n";
my @indexfile = <INDEX>;
close(INDEX);
foreach(@indexfile)
{
next if !($_);
chop;
($page, $index, $file) = split(/\t/);
$categorycontents[$page]->[$index]=$file;
}
return @categorycontents;
}
#---------------------------------------------------------------------
+---------
sub readcategoryfile
{
my (@categoryfile, $page, $index, $dir);
# Parse cat.txt
open (INDEX, "$SOUNDDIR/$CATFILE") || die "Can't open $SOUNDDIR/$C
+ATFILE: $!\n";
my @catfile = <INDEX>;
close(INDEX);
foreach(@catfile)
{
next if !($_);
chop;
($page, $index, $dir) = split(/\t/);
$categoryfile[$page]->[$index]=$dir;
}
return @categoryfile;
}
#---------------------------------------------------------------------
+---------
sub drawpage
{
my ($mainframe, $categorycontentsref) = @_;
my @categorycontents = @{$categorycontentsref};
my ($j, @images);
@BUTTONS = ();
die "No words found\n" unless @{$categorycontents[$CURRENT_PAGE]};
+
if ($CURRENT_PAGE eq 1)
{
addupbutton($mainframe, \@categorycontents);
}
else {
addprevbutton($mainframe, \@categorycontents);
}
my $y=1;
#Draw the images of the current category (first page)
for ($j=1; $j<15; $j++)
{
next if not defined($categorycontents[$CURRENT_PAGE]->[$j-1]);
my $scaledimage = $mainframe->Photo(
"button$y",
-data => scaleimage("$SOUNDDIR/$CURRENT_
+CATEGORY/$categorycontents[$CURRENT_PAGE]->[$j-1].$IMG_EXT"),
-format => 'jpeg'
);
my $callback = \&play($categorycontents[$CURRENT_PAGE]->[$j-1]
+);
$BUTTONS[$y] = $mainframe->Button(
-activebackground => $ACTIVE_BGCOLOR,
-borderwidth => $BORDER_WIDTH,
-image => "button$y",
-command => $callback,
-relief => 'flat'
);
$BUTTONS[$y]->grid(
-in => $mainframe,
-column => ($j%4),
-row => int($j/4)+1
);
$y++;
}
}
#---------------------------------------------------------------------
+---------
sub scaleimage
{
my ($file) = @_;
open(GDFILE, $file) || die "File could not be opened ($file) : $!\
+n";
my $im = GD::Image->newFromJpeg(\*GDFILE);
close (GDFILE);
my ($width, $height) = $im->getBounds();
# Create an empty image with the desired dimensions
my $resizedim = $width/($height/$MAX_HEIGHT)<$MAX_WIDTH ? new GD::
+Image($width/($height/$MAX_HEIGHT),$MAX_HEIGHT) : new GD::Image($MAX_
+WIDTH, $height/($width/$MAX_WIDTH));
# Copy everything from $im and resize it into $resizedim
$resizedim->copyResized($im,0,0,0,0,$resizedim->getBounds(),$width
+, $height);
# encode the jpeg-output of the $resizedim
return encode_base64($resizedim->jpeg(100));
}
#---------------------------------------------------------------------
+---------
sub drawcatpage
{
my ($mainframe, $categoryref) = @_;
my @categories = @{$categoryref};
my ($j, @images, $x);
@BUTTONS = ();
die "No categories found\n" unless $#{$categories[$CURRENT_PAGE]};
+
$x = 0;
#Put the images of the categories on the screen
for ($j=1; $j<=@{$categories[$CURRENT_PAGE]}; $j++)
{
my $idx = $CURRENT_PAGE eq 1 ? $x : $j;
my $cat = $categories[$CURRENT_PAGE]->[$x];
my $scaledimage = $mainframe->Photo("button$idx",
-data => scaleimage("$SOUNDDIR/$cat.$IMG_E
+XT"),
-format => 'jpeg'
);
my $callback = sub {
#retrieve the categorycontents
$CURRENT_CATEGORY=$cat;
my @categorycontent = readcurrentcategoryindex();
foreach (@BUTTONS)
{
$_->destroy()
}
@BUTTONS = ();
$CURRENT_PAGE=1;
drawpage($mainframe, \@categorycontent);
if ($CURRENT_PAGE < $#categorycontent) {addlastbut
+ton($mainframe, \@categorycontent);}
else {addupbutton($mainframe, \@categorycontent);}
$SELECTED_BUTTON=0;
$BUTTONS[$SELECTED_BUTTON]->configure(-state => 'a
+ctive');
};
$BUTTONS[$idx] = $mainframe->Button(
-activebackground => $ACTIVE_BGCOLOR,
-borderwidth => $BORDER_WIDTH,
-image => "button$idx",
-command => $callback,
-relief => 'flat'
);
$BUTTONS[$idx]->grid(
-in => $mainframe,
-column => ($idx%4),
-row => int($idx/4)+1
);
$x++;
}
}
#---------------------------------------------------------------------
+---------
sub addupbutton
{
my ($mainframe, $categorycontentref) = @_;
my @categorycontent = @$categorycontentref;
my $i = @BUTTONS;
my $y = $CURRENT_PAGE == $#{$categorycontentref} ? 15 : 0;
my $scaledimage = $mainframe->Photo("button$i",
-data => scaleimage("$SOUNDDIR/$UP_IMG"),
-format => 'jpeg'
);
my $callback = sub {
my @categories = readcategoryfile();
foreach (@BUTTONS)
{
$_->destroy()
}
@BUTTONS = ();
$CURRENT_PAGE=1;
drawcatpage($mainframe, \@categories);
$SELECTED_BUTTON=0;
$BUTTONS[$SELECTED_BUTTON]->configure(-state => 'activ
+e');
};
$BUTTONS[$i] = $mainframe->Button(
-activebackground => $ACTIVE_BGCOLOR,
-borderwidth => $BORDER_WIDTH,
-image => "button$i",
-command => $callback,
-relief => 'flat'
);
$BUTTONS[$i]->grid(
-in => $mainframe,
-column => $y%4,
-row => int($y/4)+1
);
}
#---------------------------------------------------------------------
+---------
sub addlastbutton
{
my ($mainframe, $categorycontentref) = @_;
my @categorycontent = @$categorycontentref;
my $y = 15;
my $j = @BUTTONS;
my $scaledimage = $mainframe->Photo("button$j",
-data => scaleimage("$SOUNDDIR/$NEXT_IMG"),
-format => 'jpeg'
);
my $callback = sub {
foreach (@BUTTONS)
{
$_->destroy()
}
@BUTTONS = ();
$CURRENT_PAGE++;
drawpage($mainframe, \@categorycontent);
if ($CURRENT_PAGE < $#categorycontent) {addlastbutton(
+$mainframe, \@categorycontent);}
else {addupbutton($mainframe, \@categorycontent);}
# Make the first button active
$SELECTED_BUTTON=0;
$BUTTONS[$SELECTED_BUTTON]->configure(-state => 'activ
+e');
};
$BUTTONS[$j] = $mainframe->Button(
-activebackground => $ACTIVE_BGCOLOR,
-borderwidth => $BORDER_WIDTH,
-image => "button$j",
-command => $callback,
-relief => 'flat'
);
$BUTTONS[$j]->grid(
-in => $mainframe,
-column => ($y%4),
-row => int($y/4)+1
);
}
#---------------------------------------------------------------------
+---------
sub addprevbutton
{
my ($mainframe, $categorycontentref) = @_;
my @categorycontent = @$categorycontentref;
my $j = @BUTTONS;
my $scaledimage = $mainframe->Photo("button$j",
-data => scaleimage("$SOUNDDIR/$PREV_IMG"),
-format => 'jpeg'
);
my $callback = sub {
foreach (@BUTTONS)
{
$_->destroy()
}
@BUTTONS = ();
$CURRENT_PAGE--;
drawpage($mainframe, \@categorycontent);
if ($CURRENT_PAGE < $#categorycontent) {addlastbutton(
+$mainframe, \@categorycontent);}
else {addupbutton($mainframe, \@categorycontent);}
$SELECTED_BUTTON=0;
$BUTTONS[$SELECTED_BUTTON]->configure(-state => 'activ
+e');
};
$BUTTONS[$j] = $mainframe->Button(
-activebackground => $ACTIVE_BGCOLOR,
-borderwidth => $BORDER_WIDTH,
-image => "button$j",
-command => $callback,
-relief => 'flat'
);
$BUTTONS[$j]->grid(
-in => $mainframe,
-column => ($j%4),
-row => int($j/4) +1
);
}
Jouke Visser, Perl 'Adept'