Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

pMusic - an MP3 player for disabled people

by Jouke (Curate)
on Apr 26, 2004 at 11:08 UTC ( #348135=CUFP: 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

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://348135]
Approved by Corion
Front-paged by broquaint
help
Chatterbox?
[ambrus]: I'm currently in the process of rewriting my proof of concept programs. They sort of developped organically as I was experimenting, so now I've got an ugly mess of multiple programs and one-liners held together by nothing. I'll have to rewrite them to som
[ambrus]: ething that's both cleanly organized and mostly automated.
LanX in train, bad connection
[Corion]: ambrus: Yeah - we're in that situation too, except that there is no time to do the reorganizing :-/
[LanX]: ... so my boss started a project with the newest sun servers and invited the traders to come on weekend to test it... and they were so pleased, that they forced him to keep it in production...
[ambrus]: Corion: sure, this is the long-term plan. The short term is that I have to run this ungodly mess to get results from the new input data today.
[Corion]: ambrus: Most of our "automation" is tied to process exit codes and a shell pipeline :-\
[LanX]: ... a week later they realized that one of the databases - which recorded how much the other banks due to this bank - was not correctly plugged
[ambrus]: Corion: I have no problem with exit codes and shell pipeline. My problem is that the current process requires a lot of manual intervention from me, including editing the source codes.
[ambrus]: (Also a lot of manual intervention by two or three other co-workers, who do other parts of the process.)

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (16)
As of 2017-03-29 11:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Should Pluto Get Its Planethood Back?



    Results (350 votes). Check out past polls.