Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
This is the first application that uses the AAC::Pvoice modules after creating those modules for pVoice originally. It's an MP3 player, which was a present for my daughter's birthday last Friday.
It was a rather quick hack, so if you find strange constructs or things that don't work the way it should, please forgive me :)

It also needs the Audio::BASSXS module, which should arrive on a CPAN near you real soon :)

Update: a screenshot
#!/usr/bin/perl #--------------------------------------------------------------------- +-------- # # pMusic 0.1 # # pMusic is an MP3 player for people with disabilities, who are not ab +le to # use a mouse or a keyboard the way healthy people can. It was origina +lly # written for my daughter Krista, who can control a computer by moving + her head # to the left and right, which causes a special headsupport to generat +e events. # # This application makes extensive use of the AAC::Pvoice modules, whi +ch can # be found on CPAN. It also needs the Audio::BASSXS module for playing + the MP3s. # # More of these kinds of applications can be found on http://www.pvoic +e.org # # This application needs a set of icons, which can be downloaded from # http://jouke.pvoice.org/files/pMusic-icons.zip. They are created by # ngMedia (http://www.ngmedia.com). # # Finally, you'll need to have the INPOUT32.DLL, which can be download +ed from # http://jouke.pvoice.org/files/INPOUT32.DLL # # Author: Jouke Visser # Version: 0.1 # Last modification: April 26, 2004 # #--------------------------------------------------------------------- +--------
use strict; use warnings; use Wx; our $VERSION = sprintf("%d.%02d", q$Revision: 0.01 $=~/(\d+)\.(\d+ +)/); # display the splashscreen use Wx::Perl::SplashFast ('img/splash.png', 3000); our $leftpanecolour = Wx::Colour->new(145,211,143); our $rightpanecolour = Wx::Colour->new(215,239,214); our $basepath = $ARGV[0] || 'C:\\mp3\\'; #--------------------------------------------------------------------- +-------- # This is the pMusic package where the frame is called package pMusic; use Wx; use base qw(Wx::App); use Wx::Perl::Carp; #--------------------------------------------------------------------- +-------- sub OnInit { my $self = shift; Wx::InitAllImageHandlers; my $Appname = "pMusic"; my $Appvendor = "pVoice Applications - Jouke Visser"; $self->SetAppName('pMusic'); $self->SetVendorName($Appvendor); my $config = Wx::ConfigBase::Get; my $Device = $config->Read('Device', 'icon' ); $config->Write('Device', $Device ); my $frame = pMusicFrame->new( undef, -1, $self->GetAppName ); $frame->Show(1); return 1; } #--------------------------------------------------------------------- +-------- # This is the pMusicFrame package where the frame created and everythi +ng is # being set up. package pMusicFrame; use strict; use warnings; use Wx qw(:everything); use Wx::Event qw(EVT_TIMER); use Audio::BASSXS; use MP3::M3U::Parser; use MP3::Info; use URI::Escape; use AAC::Pvoice::Panel; use AAC::Pvoice::Input; use AAC::Pvoice::Row; use Wx::Perl::Carp; use base qw(Wx::Frame); #--------------------------------------------------------------------- +-------- sub new { my $class = shift; # Call the Superclass' constructor my $self = $class->SUPER::new(@_); # Set the frame's icon my $icon=Wx::Icon->new( 'pMusic.ico', # name wxBITMAP_TYPE_ICO); # type $self->SetIcon($icon ); my $rv = BASS_Init(1,44100,0,0,0); $self->{backgroundcolour}=$rightpanecolour; $self->SetBackgroundColour($self->{backgroundcolour}); $self->{MAX_X} = 50; $self->{MAX_Y} = 50; $self->{ITEMSPACING} = 3; $self->{itemsperrow} = 4; $self->{maxrows} = 3; $self->{idstart} = 10_000; $self->{splitwindow} = Wx::SplitterWindow->new( $self, -1, wxDefaultPosition, + wxDefaultSize, wxSP_NOBORDER|wxSP +_LIVE_UPDATE ); $self->{splitwindow}->Show(1); $self->Show(1); $self->Maximize(1); $self->{cdinfo} = CDInfoPanel->new( $self->{splitwindow}, -1, wxDefaultPosition, [int((1*$self->GetSize->GetWid +th)/4), ($self->GetSize->GetHeight-20 +)]); $self->{panel} = AAC::Pvoice::Panel->new( $self->{splitwindow}, + # parent -1, # id wxDefaultPosition,# po +sition [int((3*$self->GetSize +->GetWidth)/4), $self->GetSize->GetHe +ight-20], # size wxNO_3D, 1); # style $self->{splitwindow}->SplitVertically( $self->{cdinfo}, $self->{panel}, int((1*$self->GetSize->GetW +idth)/4)); $self->{panel}->Show(1); $self->{cdinfo}->Show(1); $self->{panel}->BackgroundColour($self->{backgroundcolour}); $self->{cdinfo}->SetBackgroundColour($leftpanecolour); $self->{splitwindow}->SetBackgroundColour($self->{backgroundcolour +}); $self->{selectedcd} = 'idx'; $self->{CATIDXBMP} = AAC::Pvoice::Bitmap->new('img/up.png' , $ +self->{MAX_X}, $self->{MAX_Y}); $self->{PREVPAGBMP} = AAC::Pvoice::Bitmap->new('img/prev.png' , $ +self->{MAX_X}, $self->{MAX_Y}); $self->{NEXTPAGBMP} = AAC::Pvoice::Bitmap->new('img/next.png' , $ +self->{MAX_X}, $self->{MAX_Y}); $self->{ROWSELBMP} = AAC::Pvoice::Bitmap->new('img/rowsel.png', $ +self->{MAX_X}, $self->{MAX_Y}); $self->{PLAYBMP} = AAC::Pvoice::Bitmap->new('img/play.png' , $ +self->{MAX_X}, $ +self->{MAX_Y},'',$rightpanecolour); $self->{PAUSEBMP} = AAC::Pvoice::Bitmap->new('img/pause.png' , $ +self->{MAX_X}, $ +self->{MAX_Y},'',$rightpanecolour); $self->{STOPBMP} = AAC::Pvoice::Bitmap->new('img/stop.png' , $ +self->{MAX_X}, $ +self->{MAX_Y},'',$rightpanecolour); $self->{PLAYALLBMP} = AAC::Pvoice::Bitmap->new('img/playall.png',$ +self->{MAX_X}, $ +self->{MAX_Y},'',$rightpanecolour); $self->{PLAYTRACKBMP} = AAC::Pvoice::Bitmap->new('img/playtrack.pn +g',$self->{MAX_X}, $ +self->{MAX_Y},'',$rightpanecolour); # Get information on all playlists in $basedir $self->GetPlayLists; $self->{playall} = 1; # Draw the screen... $self->DrawScreen(); # We're invoking PlayStatus() every second to update the info on t +he CDInfoPanel $self->{timer} = Wx::Timer->new($self,my $tid = Wx::NewId()); $self->{timer}->Start(1000, 0); # 0 is continuous EVT_TIMER($self, $tid, \&PlayStatus); return $self; } #--------------------------------------------------------------------- +-------- sub PlayStatus { my $self = shift; return if not defined $self->{playingcd}; return if not defined $self->{playingindex}; return if $self->{stop} or $self->{pause}; return if not $self->{stream}; $self->UpdateStatus; my $pos = BASS_StreamGetFilePosition($self->{stream},BASS_FILEPOS_ +DECODE); my $len = BASS_StreamGetFilePosition($self->{stream},BASS_FILEPOS_ +END); my $progress=$pos*100.0/$len; # percentage of buffer used if ($progress>100) {$progress=100;} # restrict to 100 (can be high +er) $self->{cdinfo}->UpdateGauge($progress); if ($pos >= $len) { if ($self->{playingindex} < $#{$self->{playlists}->{$self->{pl +ayingcd}}}) { if ($self->{newselection}) { $self->{newselection}=0; $self->{playingindex} = $self->{selectedindex}; $self->{playingcd} = $self->{selectedcd}; } else { $self->{playingindex}++; } $self->{playingfile} = $basepath.$self->{playlists} ->{$self->{playingcd +}} ->[$self->{playingin +dex}]->[2]; $self->{cdinfo}->SetCover(AAC::Pvoice::Bitmap->new( $basep +ath.$self->{playingcd}.'.jpg', $self- +>{cdinfo}->GetSize->GetWidth-50, $self- +>{cdinfo}->GetSize->GetWidth-50, '', $leftp +anecolour)); $self->UpdateSelection; $self->{stream} = BASS_StreamCreateFile(0,$self->{playingf +ile},0,0,0); warn "BASS error: ".BASS_ErrorString(BASS_ErrorGetCode) un +less $self->{stream}; my $rv = BASS_StreamPlay($self->{stream},0,0); warn "BASS error: ".BASS_ErrorString(BASS_ErrorGetCode) un +less $rv == 1; } else { undef $self->{stream}; undef $self->{playingcd}; $self->{playingindex} = 0; $self->{cdinfo}->UpdateStatus("Playing has stopped"); } } } #--------------------------------------------------------------------- +-------- sub DrawScreen { my $self = shift; my $id = $self->{idstart}; #----------------------------------------------------------------- +-------- # This is the closure to select a specific cd my $selectcd = sub{ my $cd = shift; return sub { $self->{selectedcd} = $cd; $self->{selectedindex} = 0; $self->{panel}->{currentpage} += 0; $self->DrawScreen() } }; #----------------------------------------------------------------- +-------- # This is the closure to select a specific item my $selectitem = sub{ my $index = shift; return sub { $self->{stop} = 0; $self->{selectedindex} = $ +index; $self->{newselection}=1; $self->UpdateSelection; } }; #----------------------------------------------------------------- +-------- # This is the closure to go to the previous page my $prevpage = sub{ # not implemented yet }; #----------------------------------------------------------------- +-------- # And the closure to go to the next page my $nextpage = sub{ # not implemented yet }; #----------------------------------------------------------------- +-------- # And the closure to go to play an mp3 file my $play = sub { return sub{ if ($self->{pause}) { BASS_Start; $self->{pause} = 0; $self->UpdateStatus; } else { unless ($self->{stop}) { $self->{playingcd} = $self- +>{selectedcd}; $self->{playingindex} = $self- +>{selectedindex}; } $self->{stop}=0; my $newfile = $basepath.$self->{pl +aylists} ->{$s +elf->{playingcd}} ->[$s +elf->{playingindex}]->[2]; BASS_Stop; $self->{playingfile} = $newfile; $self->{cdinfo}->SetCover(AAC::Pvo +ice::Bitmap->new($basepath.$self->{playingcd}.'.jpg', + $self->{cdinfo}->GetSize->GetWidth-50, + $self->{cdinfo}->GetSize->GetWidth-50, + '', + $leftpanecolour)); $self->UpdateStatus; $self->UpdateSelection; $self->{stream} = BASS_StreamCreat +eFile(0,$self->{playingfile},0,0,0); warn "BASS error: ".BASS_ErrorStri +ng(BASS_ErrorGetCode) unless $self->{stream}; BASS_Start; my $rv = BASS_StreamPlay($self->{s +tream},0,0); warn "BASS error: ".BASS_ErrorStri +ng(BASS_ErrorGetCode) unless $rv == 1; } } }; #----------------------------------------------------------------- +-------- # First we clear the panel $self->{panel}->Clear(); my $title = "pMusic"; $title .= " ( $self->{playlists}->{$self->{selectedcd}}->[0]->[5] +)" if $self->{selectedcd} ne 'idx'; $self->{panel}->AddTitle( $title); #----------------------------------------------------------------- +-------- # create the navigation-row my $items = []; push @$items, [$id++, $self->{ROWSELBMP}, sub{$self->{panel}->ToR +owSelection}]; push @$items, [$id++, $self->{CATIDXBMP}, $selectcd->('idx')] if $self->{selectedcd} ne 'idx'; push @$items, [$id++, $self->{PREVPAGBMP}, $prevpage] if $self->{selectedcd} eq 'idx'; push @$items, [$id++, $self->{NEXTPAGBMP}, $nextpage] if $self->{selectedcd} eq 'idx'; push @$items, [$id++, $self->{PLAYALLBMP}, sub{$self->{playall} = + 1; $self->DrawScreen} + ] if $self->{selectedcd} ne 'idx'; push @$items, [$id++, $self->{PLAYTRACKBMP},sub{$self->{playall} = + 0; $self->DrawScreen} + ] if $self->{selectedcd} ne 'idx'; $self->{panel}->Append(AAC::Pvoice::Row->new($self->{panel}, # p +arent scalar(@$items), # m +ax $items, # i +tems wxDefaultPosition,# p +os wxDefaultSize, $self->{MAX_X}, $self->{MAX_Y}, $self->{ITEMSPACING}, $self->{backgroundcol +our})); if ($self->{selectedcd} eq 'idx') { #------------------------------------------------------------- +------------ # create the rows with selectable cds my $maxY = int( ($self->{panel}->ysize-(3*$self->{MAX_Y})) /($self->{maxrows}) )-$self->{ITEMSPACING}; my $maxX = int($self->{panel}->xsize/($self->{itemsperrow}+1)) +-10; $self->{cdrowsel} = AAC::Pvoice::Bitmap->new( 'img/rowsel.png +', $maxX, $maxY, '', $rightpanecolou +r); $items=[]; my @allitems; @allitems = map { my $pl=$_; [ $id++, AAC::Pvoice::Bitmap->new($base +path.$pl.'.jpg', $maxX +, $maxY +, '', $righ +tpanecolour), $selectcd->($pl) ] } sort keys %{$self->{playlists}}; for (my $ii = 0; $ii < @allitems; $ii+=($self->{itemsperrow}-1 +)) { @$items=@allitems[$ii..($ii+$self->{itemsperrow}-2)]; # add the rowselect button unshift @$items, [$id++, # +id $self->{cdrowsel}, # +bitmap sub{$self->{panel}->ToRowSelection}]; # +action # add the items to the row and the row to the panel $self->{panel}->Append(AAC::Pvoice::Row->new($self->{panel +}, # parent $self->{items +perrow}, # max $items, + # items wxDefaultPosi +tion, # pos wxDefaultSize +, $maxX, $maxY, $self->{ITEMS +PACING}, $self->{backg +roundcolour})); } #------------------------------------------------------------- +------------ # fill up empty rows $self->{panel}->Append(AAC::Pvoice::Row->new($self->{panel}, + # parent $self->{itemsperr +ow}, # max [], + # items wxDefaultPosition +, # pos wxDefaultSize, $maxX, $maxY, $self->{ITEMSPACI +NG}, $self->{backgroun +dcolour}),1) for $self->{panel}->{totalrows}..$self->{maxrows} +; } else { #------------------------------------------------------------- +------------ # create the rows with songs within this cd my $maxY = int( ($self->{panel}->ysize-(3*$self->{MAX_Y})) /(scalar(@{$self->{playlists}->{$self->{select +edcd}}})) )-$self->{ITEMSPACING}; my $maxX = int($self->{panel}->xsize/(2))-10; my $fontsize = 20; $self->UpdateSelection(); for (my $i=0; $i < @{$self->{playlists}->{$self->{selectedcd}} +}; $i++) { my $caption = $self->{playlists}->{ $self->{selectedcd}}-> +[$i]->[4] ." - " .$self->{playlists} ->{$self->{select +edcd}} ->[$i]->[3]; my $newbmp = Wx::Bitmap->new($maxX, $maxY); my $tmpdc = Wx::MemoryDC->new(); $tmpdc->SelectObject($newbmp); $tmpdc->Clear(); my ($cfont, $cpt) = (wxNullFont, 18); my ($cw, $ch); do { $cpt--; $cfont = Wx::Font->new( $cpt, # font siz +e wxSWISS, # font fam +ily wxNORMAL, # style wxNORMAL, # weight 0, 'Comic Sans MS', # face nam +e wxFONTENCODING_SYSTEM); ($cw, $ch, undef, undef) = $tmpdc->GetTextExtent($capt +ion, $cfont); } until ($cw<=$maxX) && ($ch <= $maxY); $fontsize = $cpt if $fontsize > $cpt; } my $cfont = Wx::Font->new( $fontsize, # font size wxSWISS, # font family wxNORMAL, # style wxNORMAL, # weight 0, 'Comic Sans MS', # face name wxFONTENCODING_SYSTEM); for (my $i=0; $i < @{$self->{playlists}->{$self->{selectedcd}} +}; $i++) { my $caption = $self->{playlists} ->{$self->{selectedcd}} ->[$i]->[4] ." - " .$self->{playlists} ->{$self->{selectedcd}} ->[$i]->[3]; my $newbmp = Wx::Bitmap->new($maxX, $maxY); my $tmpdc = Wx::MemoryDC->new(); $tmpdc->SelectObject($newbmp); if ($self->{playall}) { my $br = Wx::Brush->new($leftpanecolour, wxSOLID); $tmpdc->SetBrush($br); $tmpdc->SetBackground($br); $tmpdc->SetTextBackground($leftpanecolour); $tmpdc->SetTextForeground(wxBLACK); } else { $tmpdc->SetTextBackground($leftpanecolour); $tmpdc->SetTextForeground(wxBLACK); } $tmpdc->Clear(); $tmpdc->SetFont($cfont); $tmpdc->DrawText($caption, 0,0); # add the items to the row and the row to the panel $self->{panel}->Append(AAC::Pvoice::Row->new($self->{panel +}, 1, [[$id++, $newbmp, $selectitem +->($i)]], wxDefaultPosi +tion, wxDefaultSize +, $maxX, $maxY, $self->{ITEMS +PACING}, $self->{backg +roundcolour}), $self->{playa +ll}); } } #----------------------------------------------------------------- +-------- # create the control-row $items = []; push @$items, [$id++, $self->{PLAYBMP} , $play->()]; push @$items, [$id++, $self->{PAUSEBMP}, sub{ BASS_Pause(); $self->{pause}=1; $self->UpdateStatus; }]; push @$items, [$id++, $self->{STOPBMP} , sub{ BASS_Stop(); $self->{pause}=0; $self->{stop}=1; $self->{playingindex}=0; $self->{playingcd}=$self->{selectedcd} +; $self->UpdateStatus; $self->UpdateSelection; $self->{cdinfo}->UpdateGauge(0); }]; $self->{panel}->Append(AAC::Pvoice::Row->new($self->{panel}, # p +arent scalar(@$items), # m +ax $items, # i +tems wxDefaultPosition,# p +os wxDefaultSize, $self->{MAX_X}, $self->{MAX_Y}, $self->{ITEMSPACING}, $self->{backgroundcol +our})); #----------------------------------------------------------------- +-------- # finalize the panel $self->{panel}->Finalize(); } #--------------------------------------------------------------------- +-------- sub UpdateStatus { my $self = shift; $self->{cdinfo}->UpdateStatus($self->{playlists} ->{$self->{playingcd}} ->[$self->{playingindex}]->[5], $self->{playlists} ->{$self->{playingcd}} ->[$self->{playingindex}]->[4], $self->{playlists} ->{$self->{playingcd}} ->[$self->{playingindex}]->[3], $self->{playlists} ->{$self->{playingcd}} ->[$self->{playingindex}]->[1], $self->{stop} ? 'stopped' : $self->{pause} ? 'pa +use' : 'pl +aying'); } #--------------------------------------------------------------------- +-------- sub UpdateSelection { my $self = shift; if ($self->{newselection}) { $self->{cdinfo}->UpdateSelection($self->{playlists} ->{$self->{selectedcd}} ->[$self->{selectedindex +}] ->[0]); } elsif (defined $self->{playingcd} && defined $self->{playingindex} +) { $self->{cdinfo}->UpdateSelection($self->{playlists} ->{$self->{playingcd}} ->[$self->{playingindex} ++1] ->[0]); } elsif (not $self->{selectedcd}) { $self->{cdinfo}->UpdateSelection("Geen"); } elsif (not $self->{selectedindex}) { $self->{cdinfo}->UpdateSelection($self->{playlists} ->{$self->{selectedcd}} ->[0]->[0]); } else { $self->{cdinfo}->UpdateSelection($self->{playlists} ->{$self->{selectedcd}} ->[$self->{selectedindex +}] ->[0]); } } #--------------------------------------------------------------------- +-------- sub GetPlayLists { my $self = shift; my $m3u = MP3::M3U::Parser->new( -type => 'dir', -path => $basepath, -seconds => 'format'); $self->{playlists} = $m3u->parse(); foreach my $playlist (keys %{$self->{playlists}}) { foreach my $i (@{$self->{playlists}->{$playlist}}) { $i->[0] =~ s/[\r\n]//g; $i->[2] = uri_unescape($i->[2]); $i->[2] =~ s/[\r\n]//g; my $mp3 = MP3::Info->new($basepath.$i->[2]); $i->[3] = $mp3->artist; $i->[4] = $mp3->title; $i->[5] = $mp3->album; } } } #--------------------------------------------------------------------- +-------- # This is the CDInfoPanel package where we define the left pane of the + frame # which displays status information on what is being played package CDInfoPanel; use strict; use warnings; use Wx qw(:everything); use Wx::Perl::Carp; use base qw (Wx::Panel); #--------------------------------------------------------------------- +-------- sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->Show(1); my $width = $self->GetSize->GetWidth; $self->Show(0); $self->{tls} = Wx::FlexGridSizer->new(0,1); $self->{coversizer} = Wx::GridSizer->new(0,1); $self->{cover} = Wx::BitmapButton->new( $self, -1, AAC::Pvoice::Bitmap->new( 'img/log +o.png', $width-5 +0, $width-5 +0, '', undef, 1), wxDefaultPosition, [$width-20,$width-20], wxSUNKEN_BORDER); $self->{cover}->SetBackgroundColour($leftpanecolour); $self->{coversizer}->Add($self->{cover},0,wxALL|wxALIGN_CENTRE|wxG +ROW, 0); $self->{coversizer}->SetMinSize($width,$width); $self->{tls}->Add($self->{coversizer},0, wxALL|wxALIGN_CENTRE|wxGR +OW, 0); $self->{gauge} = Wx::Gauge->new( $self, #parent -1, #id 100, #max value wxDefaultPosition, #position [200,30], # size wxGA_PROGRESSBAR|wxGA_SMOOTH); #s +tyle $self->{gauge}->SetBackgroundColour(wxWHITE); $self->{tls}->Add($self->{gauge},0, wxALIGN_CENTRE, 0); $self->{statussizer} = Wx::FlexGridSizer->new(0,1); $self->{font} = Wx::Font->new( 9, # font size wxDECORATIVE, # font family wxNORMAL, # style wxNORMAL, # weight 0, 'Comic Sans MS'); $self->{status1} = Wx::StaticText->new($self, -1, 'Album: ', wxDefaultPositio +n, [$width - 20,50] +, wxALIGN_LEFT); $self->{status1}->SetFont($self->{font}); $self->{status1}->SetBackgroundColour($leftpanecolour); $self->{status2} = Wx::StaticText->new($self, -1, 'Title: ', wxDefaultPositio +n, [$width - 20,50] +, wxALIGN_LEFT); $self->{status2}->SetFont($self->{font}); $self->{status2}->SetBackgroundColour($leftpanecolour); $self->{status3} = Wx::StaticText->new($self, -1, 'Artist: ', wxDefaultPositio +n, [$width - 20,50] +, wxALIGN_LEFT); $self->{status3}->SetFont($self->{font}); $self->{status3}->SetBackgroundColour($leftpanecolour); $self->{status4} = Wx::StaticText->new($self, -1, 'Duration: ', wxDefaultPositio +n, [$width - 20,50] +, wxALIGN_LEFT); $self->{status4}->SetFont($self->{font}); $self->{status4}->SetBackgroundColour($leftpanecolour); $self->{status5} = Wx::StaticText->new($self, -1, 'Action: ', wxDefaultPositio +n, [$width - 20,50] +, wxALIGN_LEFT); $self->{status5}->SetFont($self->{font}); $self->{status5}->SetBackgroundColour($leftpanecolour); $self->{selectionfont} = Wx::Font->new( 11, # font size wxDECORATIVE, # font family wxITALIC, # style wxNORMAL, # weight 0, 'Comic Sans MS'); $self->{selection0} = Wx::StaticText->new($self, -1, 'Next: ', wxDefaultPosi +tion, [$width - 20, +50], wxALIGN_LEFT) +; $self->{selection0}->SetFont($self->{selectionfont}); $self->{selection0}->SetBackgroundColour($leftpanecolour); $self->{statussizer}->Add($self->{status4}, 0, wxGROW|wxALL, 0); $self->{statussizer}->Add($self->{status5}, 0, wxGROW|wxALL, 0); $self->{statussizer}->Add($self->{status1}, 0, wxGROW|wxALL, 0); $self->{statussizer}->Add($self->{status2}, 0, wxGROW|wxALL, 0); $self->{statussizer}->Add($self->{status3}, 0, wxGROW|wxALL, 0); $self->{statussizer}->Add($self->{selection0},0, wxGROW|wxALL, 0); $self->{statussizer}->AddGrowableCol(0); $self->{tls}->Add($self->{statussizer},0, wxGROW|wxALL, 0); $self->{tls}->AddGrowableCol(0); $self->{tls}->AddGrowableRow($_) for (0..3); $self->SetSizer($self->{tls}); $self->{tls}->Fit($self); $self->{tls}->Layout; $self->SetBackgroundColour($leftpanecolour); $self->Refresh; $self->Show(1); $self->UpdateStatus("(None)","(None)","(None)","0:00","(None)"); $self->UpdateSelection("(None)"); return $self; } #--------------------------------------------------------------------- +-------- sub UpdateStatus { my $self = shift; $self->{status1}->SetLabel("Album: ".shift); $self->{status2}->SetLabel("Title: ".shift); $self->{status3}->SetLabel("Artist: ".shift); $self->{status4}->SetLabel("Duration: ".shift); $self->{status5}->SetLabel("Action: ".shift); $self->{tls}->Layout(); } #--------------------------------------------------------------------- +-------- sub UpdateSelection { my $self = shift; my $value = shift; $self->{selection0}->SetLabel("Next: ".$value); $self->{tls}->Layout(); } #--------------------------------------------------------------------- +-------- sub UpdateGauge { my $self = shift; $self->{gauge}->SetValue(shift); } #--------------------------------------------------------------------- +-------- sub SetCover { my $self = shift; $self->{cover}->SetBitmapLabel(shift); $self->Refresh; } #--------------------------------------------------------------------- +-------- # This is the main package where the application itself is started package main; my $obj = pMusic->new(); $obj->MainLoop;


Jouke Visser
Speaking at the 2004 O'Reilly Open Source Convention about pVoice

In reply to pMusic - an MP3 player for disabled people by Jouke

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (6)
    As of 2015-07-04 07:24 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (58 votes), past polls