Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
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
  • Outside of code tags, you may need to use entities for some characters:
            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 chilling in the Monastery: (6)
    As of 2014-08-21 11:17 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The best computer themed movie is:











      Results (134 votes), past polls