Index: HTML/EN/html/docs/input.html =================================================================== RCS file: /home/cvs/cvsroot/slim/server/HTML/EN/html/docs/input.html,v retrieving revision 1.10 diff -u -p -B -r1.10 input.html --- HTML/EN/html/docs/input.html 3 Aug 2004 17:28:55 -0000 1.10 +++ HTML/EN/html/docs/input.html 18 Aug 2004 00:12:39 -0000 @@ -790,5 +790,180 @@ Slim::Buttons::Common::pushMode($client,

Bar

Description
-

Not currently implemented.

+

+ The Bar input mode is used to select a value that is best represented as + on a sliding scale. This may be a single direction or bi-directional slider. +

+

+ On entry into the mode, the initial selection will depend on the supplied + parameters. If valueRef is supplied, then the mode will begin with that value. + If valueRef is not supplied, or if its value does not appear in + fit withing the bounds supplied in the other parameters, the value will be assumed to be zero. +

+ This mode will not maintain state between invocations, so if such state + information needs to be kept, it is the responsibility of the calling + mode to do so. +

+
Parameters
+

+ The following parameters are used by the INPUT.Bar mode. They are + listed in the order of likelyhood to be supplied. Other parameters can be + supplied for use by the callback, external display, or change handler + functions, but will not otherwise have any effect on the INPUT.Bar + behavior. +

+

+ The header parameter can be supplied in a number of different ways. If a scalar, it + will be displayed as is. If a code reference, it will be invoked with the + arguments specified in the corresponding Args parameter + (header would use headerArgs etc.) and the return value + will be displayed. If a hash reference, the value corresponding to the key + indicated by the referenced value of valueRef will be displayed. + If an array ref, the value at listIndex of the array is extracted + and then interpreted as above. If the extracted value is itself an array ref, + the array referenced is returned. +

+

+

+
header
+
Default: "Select item:" (not localized)
+
+ String to display on the top line of the display. This parameter can + be interpreted in a number of ways, see above. After the value to be + displayed is determined, it is then modified according to the + stringHeader and headerAddCount parameters, below. +
+
headerArgs
+
Default: "CV"
+
+ One of "CV", "C", "V", or "". + The C indicates that the client object should be passed to the function + to determine the header value, the V indicates that the internal value + should be passed. +
+
stringHeader
+
Default: undef
+
+ If set to a true value, the display value of header is + passed to the string() function to be localized. If no + localized string is defined for the value of header, it is + displayed as is. +
+
callback
+
Default: none
+
+ A code reference which is called whenever an exit event occurs. If + this parameter is not supplied, INPUT.Bar will + perform a pop mode right on left exit event, bump right on right exit + events, and a simple pop mode on other types of exit event. This + behavior should be sufficient for simple list displays where nothing + needs to happen on a right exit event. The procedure referenced should + take the client object as the first parameter and the exit event type + as the second. +
+
valueRef
+
+ Default: reference to copy of item in listIndex position in list +
+
+ valueRef contains a reference to the currently selected item. + Typically this will be a reference to a variable local to the calling + mode, so that the final value will not need to be explicitly assigned + to some local variable. +
+
min
+
Default: 0
+
+ Sets the minimum value allowed for selection. The slider will stop and hold + at this value unless the user selects a greater value. +
+
max
+
Default: 100
+
+ Sets the maximum value allowed for selection. The slider will stop and hold + at this value unless the user selects a lesser value. +
+
mid
+
Default: 0
+
+ Sets the midpoint reference for bi-directional sliders. Accellerated scrolling + will pause at this point, and the bar will display mirrored output centred on this point. +
+
increment
+
Default: 2.5
+
+ Determines the value increase for each step in the scrolling function. +
+
barOnDouble
+
Default: 0
+
+ Determines the display when large fonts are used. Setting to 1 will show only the Bar on large fonts. + The default of 0 shows the header line provided by the header parameter. +
+
onChange
+
Default: none
+
+ A code reference which is executed each time the currently selected + item changes. It is passed arguments according to the value of + onChangeArgs. Any return value will be ignored. +
+
onChangeArgs
+
Default: "CV"
+
+ One of "CV", "C", "V", or "". + The C indicates that the client object should be passed to the function, + the V indicates that the internal value should be passed. +
+
+

+
Exit Event Types
+

+ The callback function should handle the following event types in some way. + Ignoring them is acceptable, crashing the server is not. +

+

+

+
left
+
+ By default, generated by a left button press. If no callback function + specified, this will result in leaving the mode with the animated + push to the right. +
+
right
+
+ By default, generated by a right button press. If no callback function + specified, this will result in a bump right animation. +
+
Other
+
+ Generated by the exit function where the type is determined by the + argument supplied. Usually will be a button name like play or add, but + be prepared for anything. +
+
+

+
Functions
+

+

+
up
+
Changes the current position in the list. Repeat is allowed and accelerates. + If the bar is bi-directional, there will be a pause at the middle value
+
down
+
Changes the current position in the list. Repeat is allowed and accelerates. + If the bar is bi-directional, there will be a pause at the middle value
+
exit
+
+ Takes an argument. An exit event is generated with the type being the + supplied argument. If no argument is supplied, the exit event type is + exit. +
+
passback
+
+ Executes the last button event (button plus pressing style) in the + context of the parent mode (set by the parentMode parameter). This + allows for parent modes to map button presses to functions without + needing to modify the mapping of the INPUT.List mode. +
+
+

[% PROCESS helpfooter.html %] Index: IR/Default.map =================================================================== RCS file: /home/cvs/cvsroot/slim/server/IR/Default.map,v retrieving revision 1.12 diff -u -p -B -r1.12 Default.map --- IR/Default.map 3 Aug 2004 17:29:05 -0000 1.12 +++ IR/Default.map 18 Aug 2004 00:12:42 -0000 @@ -271,3 +275,11 @@ search.* = passback stop.* = passback pause.* = passback +[INPUT.Bar] +arrow_left = exit_left +arrow_right = exit_right +play.* = passback +add.* = passback +search.* = passback +stop.* = passback +pause.* = passback Index: Slim/Buttons/Common.pm =================================================================== RCS file: /home/cvs/cvsroot/slim/server/Slim/Buttons/Common.pm,v retrieving revision 1.36 diff -u -p -B -r1.36 Common.pm --- Slim/Buttons/Common.pm 3 Aug 2004 17:29:09 -0000 1.36 +++ Slim/Buttons/Common.pm 18 Aug 2004 00:12:43 -0000 @@ -17,6 +17,7 @@ use Slim::Buttons::Plugins; use Slim::Buttons::Input::Text; use Slim::Buttons::Input::Time; use Slim::Buttons::Input::List; +use Slim::Buttons::Input::Bar; use Slim::Display::Display; # hash of references to functions to call when we leave a mode @@ -35,6 +36,7 @@ my %modes = ( 'INPUT.Text' => \&Slim::Buttons::Input::Text::setMode, 'INPUT.List' => \&Slim::Buttons::Input::List::setMode, 'INPUT.Time' => \&Slim::Buttons::Input::Time::setMode, + 'INPUT.Bar' => \&Slim::Buttons::Input::Bar::setMode, ); # Hashed list for registered Screensavers. Register these using addSaver. @@ -50,6 +52,7 @@ sub init { $modeFunctions{'INPUT.Text'} = Slim::Buttons::Input::Text::getFunctions(); $modeFunctions{'INPUT.List'} = Slim::Buttons::Input::List::getFunctions(); $modeFunctions{'INPUT.Time'} = Slim::Buttons::Input::Time::getFunctions(); + $modeFunctions{'INPUT.Bar'} = Slim::Buttons::Input::Bar::getFunctions(); Slim::Buttons::Plugins::getPluginModes(\%modes); Slim::Buttons::Plugins::getPluginFunctions(\%modeFunctions); Slim::Buttons::ScreenSaver::init(); Index: Slim/Buttons/Settings.pm =================================================================== RCS file: /home/cvs/cvsroot/slim/server/Slim/Buttons/Settings.pm,v retrieving revision 1.15 diff -u -p -B -r1.15 Settings.pm --- Slim/Buttons/Settings.pm 6 Aug 2004 04:16:46 -0000 1.15 +++ Slim/Buttons/Settings.pm 18 Aug 2004 00:12:43 -0000 @@ -17,10 +17,6 @@ use Slim::Utils::Prefs; use Slim::Buttons::Information; Slim::Buttons::Common::addMode('settings',Slim::Buttons::Settings::getFunctions(),\&Slim::Buttons::Settings::setMode); -Slim::Buttons::Common::addMode('treble',getTrebleFunctions(),\&setTrebleMode); -Slim::Buttons::Common::addMode('volume',getVolumeFunctions(),\&setVolumeMode); -Slim::Buttons::Common::addMode('bass',getBassFunctions(),\&setBassMode); -Slim::Buttons::Common::addMode('pitch',getPitchFunctions(),\&setPitchMode); # button functions for browse directory my @defaultSettingsChoices = ('ALARM','VOLUME', 'BASS','TREBLE','PITCH','REPEAT','SHUFFLE','TITLEFORMAT','TEXTSIZE','OFFDISPLAYSIZE','INFORMATION','SETUP_SCREENSAVER'); @@ -42,16 +38,40 @@ my %menuParams = ( 'useMode' => 'alarm' } ,catdir('settings','VOLUME') => { - 'useMode' => 'volume' # replace with INPUT.Bar when available + 'useMode' => 'INPUT.Bar' + ,'header' => \&volheader + ,'onChange' => sub { + my ($subref,$subarg) = Slim::Buttons::Common::getFunction($_[0],'volume_'.$_[1],'Common'); + &$subref($_[0],'volume',$subarg);} + ,'onChangeArgs' => 'CV' + ,'initialValue' => sub { return Slim::Utils::Prefs::clientGet($_[0], "volume");} } ,catdir('settings','BASS') => { - 'useMode' => 'bass' # replace with INPUT.Bar when available + 'useMode' => 'INPUT.Bar' + ,'header' => sub {return string('BASS').' ('.(int($_[1]/100*40 + 0.5) - 20).')';} + ,'mid' => 50 + ,'onChange' => sub { Slim::Buttons::Common::mixer($_[0],'bass',$_[1]);} + ,'onChangeArgs' => 'CV' + ,'initialValue' => sub { return Slim::Utils::Prefs::clientGet($_[0], "bass");} } ,catdir('settings','PITCH') => { - 'useMode' => 'pitch' # replace with INPUT.Bar when available + 'useMode' => 'INPUT.Bar' + ,'header' => sub {return string('PITCH').' ('.(int($_[1])).'%)';} + ,'min' => 80 + ,'max' => 120 + ,'mid' => 100 + ,'increment' => 1 + ,'onChange' => sub { Slim::Buttons::Common::mixer($_[0],'pitch',$_[1]);} + ,'onChangeArgs' => 'CV' + ,'initialValue' => sub { return Slim::Utils::Prefs::clientGet($_[0], "pitch");} } ,catdir('settings','TREBLE') => { - 'useMode' => 'treble' # replace with INPUT.Bar when available + 'useMode' => 'INPUT.Bar' + ,'header' => sub {return string('TREBLE').' ('.(int($_[1]/100*40 + 0.5) - 20).')';} + ,'mid' => 50 + ,'onChange' => sub { Slim::Buttons::Common::mixer($_[0],'treble',$_[1]);} + ,'onChangeArgs' => 'CV' + ,'initialValue' => sub { return Slim::Utils::Prefs::clientGet($_[0], "treble");} } ,catdir('settings','REPEAT') => { 'useMode' => 'INPUT.List' @@ -146,7 +166,7 @@ sub settingsExitHandler { my $nextmenu = catdir('settings',$current{$client}); if (exists($menuParams{$nextmenu})) { my %nextParams = %{$menuParams{$nextmenu}}; - if ($nextParams{'useMode'} eq 'INPUT.List' && exists($nextParams{'initialValue'})) { + if (($nextParams{'useMode'} eq 'INPUT.List' || $nextParams{'useMode'} eq 'INPUT.Bar') && exists($nextParams{'initialValue'})) { #set up valueRef for current pref my $value; if (ref($nextParams{'initialValue'}) eq 'CODE') { @@ -224,169 +244,17 @@ sub setMode { $client->update(); } -###################################################################### -# settings submodes for: treble, bass, and volume -################################################################################# -my %trebleSettingsFunctions = ( - 'up' => sub { - my $client = shift; - Slim::Buttons::Common::mixer($client,'treble','up'); - }, - 'down' => sub { - my $client = shift; - Slim::Buttons::Common::mixer($client,'treble','down'); - }, - 'left' => sub { - my $client = shift; - Slim::Buttons::Common::popModeRight($client); - }, - 'right' => sub { shift->bumpRight(); }, - 'add' => sub { shift->bumpRight(); }, - 'play' => sub { shift->bumpRight(); }, -); - -sub getTrebleFunctions { - return \%trebleSettingsFunctions; -} - -sub setTrebleMode { - my $client = shift; - $client->lines(\&trebleSettingsLines); -} - - sub trebleSettingsLines { - my $client = shift; - my ($line1, $line2); - my $level = int(Slim::Utils::Prefs::clientGet($client, "treble")/100*40 + 0.5) - 20; - $line1 = string('TREBLE') . " ($level)"; - - $line2 = Slim::Display::Display::balanceBar($client, $client->displayWidth(), Slim::Utils::Prefs::clientGet($client, "treble")); - if ($client->linesPerScreen() == 1) { $line2 = $line1; } - - return ($line1, $line2); -} - -################################################################################# -my %bassSettingsFunctions = ( - 'up' => sub { - my $client = shift; - Slim::Buttons::Common::mixer($client,'bass','up'); - }, - 'down' => sub { - my $client = shift; - Slim::Buttons::Common::mixer($client,'bass','down'); - }, - 'left' => sub { - my $client = shift; - Slim::Buttons::Common::popModeRight($client); - }, - 'right' => sub { shift->bumpRight(); }, - 'add' => sub { shift->bumpRight(); }, - 'play' => sub { shift->bumpRight(); }, -); - -sub getBassFunctions { - return \%bassSettingsFunctions; -} - -sub setBassMode { - my $client = shift; - $client->lines(\&bassSettingsLines); -} - - sub bassSettingsLines { - my $client = shift; - my ($line1, $line2); - - my $level = int(Slim::Utils::Prefs::clientGet($client, "bass")/100*40 + 0.5) - 20; - $line1 = string('BASS') . " ($level)"; - - $line2 = Slim::Display::Display::balanceBar($client, $client->displayWidth(), Slim::Utils::Prefs::clientGet($client, "bass")); - if ($client->linesPerScreen() == 1) { $line2 = $line1; } - return ($line1, $line2); -} - -################################################################################# -my %pitchSettingsFunctions = ( - 'up' => sub { - my $client = shift; - Slim::Buttons::Common::mixer($client,'pitch','up'); - }, - 'down' => sub { - my $client = shift; - Slim::Buttons::Common::mixer($client,'pitch','down'); - }, - 'left' => sub { - my $client = shift; - Slim::Buttons::Common::popModeRight($client); - }, - 'right' => sub { shift->bumpRight(); }, - 'add' => sub { shift->bumpRight(); }, - 'play' => sub { shift->bumpRight(); }, -); - -sub getPitchFunctions { - return \%pitchSettingsFunctions; -} - -sub setPitchMode { - my $client = shift; - $client->lines(\&pitchSettingsLines); -} - - sub pitchSettingsLines { - my $client = shift; - my ($line1, $line2); - - my $level = int(Slim::Utils::Prefs::clientGet($client, "pitch")); - $line1 = string('PITCH') . " ($level%)"; - - $line2 = Slim::Display::Display::balanceBar($client, $client->displayWidth(), ((Slim::Utils::Prefs::clientGet($client, "pitch") - 80) / 40 * 100)); - - if ($client->linesPerScreen() == 1) { $line2 = $line1; } - return ($line1, $line2); -} - -################################################################################# -my %volumeSettingsFunctions = ( - 'left' => sub { - my $client = shift; - Slim::Buttons::Common::popModeRight($client); - }, - 'right' => sub { shift->bumpRight(); }, - 'add' => sub { shift->bumpRight(); }, - 'play' => sub { shift->bumpRight(); }, -); - -sub getVolumeFunctions { - return \%volumeSettingsFunctions; -} - -sub setVolumeMode { - my $client = shift; - $client->lines(\&volumeLines); +sub volheader { + my ($client,$arg) = @_; + return string('VOLUME').' ('.($arg <= 0 ? string('MUTED') : int($arg/100*40+0.5)).')'; } - sub volumeLines { +sub volumeLines { my $client = shift; - my $level = int(Slim::Utils::Prefs::clientGet($client, "volume") / $Slim::Player::Client::maxVolume * 40); - - my $line1; - my $line2; - - if ($level < 0) { - $line1 = string('VOLUME')." (". string('MUTED') . ")"; - $level = 0; - } else { - $line1 = string('VOLUME')." (".$level.")"; - } - - $line2 = Slim::Display::Display::progressBar($client, $client->displayWidth(), $level / 40); - - if ($client->linesPerScreen() == 1) { $line2 = $line1; } - - return ($line1, $line2); + my $vol = Slim::Utils::Prefs::clientGet($client, "volume"); + my $volstring = volheader($client,$vol); + return Slim::Buttons::Input::Bar::lines($client,$vol,$volstring); } 1; Index: Slim/Player/Player.pm =================================================================== RCS file: /home/cvs/cvsroot/slim/server/Slim/Player/Player.pm,v retrieving revision 1.21 diff -u -p -B -r1.21 Player.pm --- Slim/Player/Player.pm 6 Aug 2004 04:16:49 -0000 1.21 +++ Slim/Player/Player.pm 18 Aug 2004 00:12:44 -0000 @@ -513,24 +513,26 @@ sub renderOverlay { return Slim::Hardware::VFD::renderOverlay($line1, $line2, $overlay1, $overlay2); } -# returns progress bar text AND sets up custom characters if necessary -sub progressBar { - my $client = shift; - my $width = shift; - my $fractioncomplete = shift; - +# Draws a slider bar, bidirectional or single direction is possible. +# $value should be pre-processed to be from 0-100 +# $midpoint specifies the position of the divider from 0-100 (use 0 for progressBar) +# returns a +/- balance/bass/treble bar text AND sets up custom characters if necessary +# range 0 to 100, 50 is middle. +sub sliderBar { + my ($client,$width,$value,$midpoint,$fullstep) = @_; + $midpoint = 0 unless defined $midpoint; if ($width == 0) { return ""; } my $charwidth = 5; - if ($fractioncomplete < 0) { - $fractioncomplete = 0; + if ($value < 0) { + $value = 0; } - if ($fractioncomplete > 1.0) { - $fractioncomplete = 1.0; + if ($value > 100) { + $value = 100; } my $chart = ""; @@ -540,32 +542,61 @@ sub progressBar { # felix mueller discovered some rounding errors that were causing the # calculations to be off. Doing it 1000 times up seems to be better. # go figure. - my $dots = int( ( ( $fractioncomplete * 1000) * $totaldots) / 1000); + my $dots = int( ( ( $value * 10 ) * $totaldots) / 1000); + my $divider = ($midpoint/100) * ($width-2); + + my $val = $value/100 * $width; + $width = $width - 1 if $midpoint; if ($dots < 0) { $dots = 0 }; if ($dots < $charwidth) { - $chart = Slim::Display::Display::symbol('leftprogress'.$dots); + $chart = $midpoint ? Slim::Display::Display::symbol('leftprogress4') : Slim::Display::Display::symbol('leftprogress'.$dots); } else { - $chart = Slim::Display::Display::symbol('leftprogress4'); + $chart = $midpoint ? Slim::Display::Display::symbol('leftprogress0') : Slim::Display::Display::symbol('leftprogress4'); } $dots -= $charwidth; - for (my $i = 1; $i < ($width - 1); $i++) { + if ($midpoint) { + for (my $i = 1; $i < $divider; $i++) { + if ($dots <= 0) { + $chart .= Slim::Display::Display::symbol('solidblock'); + } else { + $chart .= Slim::Display::Display::symbol('middleprogress0'); + } + $dots -= $charwidth; + } + if ($value < $midpoint) { + $chart .= Slim::Display::Display::symbol('solidblock'); + $dots -= $charwidth; + } else { + $chart .= Slim::Display::Display::symbol('leftmark'); + $dots -= $charwidth; + } + } + for (my $i = $divider + 1; $i < ($width - 1); $i++) { + if ($midpoint && $i == $divider + 1) { + if ($value > $midpoint) { + $chart .= Slim::Display::Display::symbol('solidblock'); + } else { + $chart .= Slim::Display::Display::symbol('rightmark'); + } + $dots -= $charwidth; + } if ($dots <= 0) { - $chart .= Slim::Display::Display::symbol('middleprogress0'); - } elsif ($dots < $charwidth) { - $chart .= Slim::Display::Display::symbol('middleprogress'.$dots); + $chart .= Slim::Display::Display::symbol('middleprogress0'); + } elsif ($dots < $charwidth && !$fullstep) { + $chart .= Slim::Display::Display::symbol('middleprogress'.$dots); } else { - $chart .= Slim::Display::Display::symbol('solidblock'); + $chart .= Slim::Display::Display::symbol('solidblock'); } $dots -= $charwidth; } - + if ($dots <= 0) { $chart .= Slim::Display::Display::symbol('rightprogress0'); - } elsif ($dots < $charwidth) { + } elsif ($dots < $charwidth && !$fullstep) { $chart .= Slim::Display::Display::symbol('rightprogress'.$dots); } else { $chart .= Slim::Display::Display::symbol('rightprogress4'); @@ -574,80 +605,17 @@ sub progressBar { return $chart; } -# returns a +/- balance/bass/treble bar text AND sets up custom characters if necessary -# range 0 to 100, 50 is middle. +# returns progress bar text +sub progressBar { + return sliderBar(shift,shift,(shift)*100,0); +} + sub balanceBar { - my $client = shift; - my $width = shift; - my $balance = shift; - - if ($balance < 0) { - $balance = 0; - } - - if ($balance > 100) { - $balance = 100; - } - - if ($width == 0) { - return ""; - } - - my $chart = ""; - - my $edgepos = $balance / 100.0 * $width; - # do the leftmost char - if ($balance <= 0) { - $chart = Slim::Display::Display::symbol('leftprogress4'); - } else { - $chart = Slim::Display::Display::symbol('leftprogress0'); - } - - my $i; - - # left half - for ($i = 1; $i < $width/2; $i++) { - if ($balance >= 50) { - if ($i == $width/2-1) { - $chart .= Slim::Display::Display::symbol('leftmark'); - } else { - $chart .= Slim::Display::Display::symbol('middleprogress0'); - } - } else { - if ($i < $edgepos) { - $chart .= Slim::Display::Display::symbol('middleprogress0'); - } else { - $chart .= Slim::Display::Display::symbol('solidblock'); - } - } - } - - # right half - for ($i = $width/2; $i < $width-1; $i++) { - if ($balance <= 50) { - if ($i == $width/2) { - $chart .= Slim::Display::Display::symbol('rightmark'); - } else { - $chart .= Slim::Display::Display::symbol('middleprogress0'); - } - } else { - if ($i < $edgepos) { - $chart .= Slim::Display::Display::symbol('solidblock'); - } else { - $chart .= Slim::Display::Display::symbol('middleprogress0'); - } - } - } - - # do the rightmost char - if ($balance >= 100) { - $chart .= Slim::Display::Display::symbol('rightprogress4'); - } else { - $chart .= Slim::Display::Display::symbol('rightprogress0'); - } - - return $chart; + return sliderBar(shift,shift,shift,50); } + + + 1; Index: Slim/Player/SqueezeboxG.pm =================================================================== RCS file: /home/cvs/cvsroot/slim/server/Slim/Player/SqueezeboxG.pm,v retrieving revision 1.6 diff -u -p -B -r1.6 SqueezeboxG.pm --- Slim/Player/SqueezeboxG.pm 17 Aug 2004 22:59:59 -0000 1.6 +++ Slim/Player/SqueezeboxG.pm 18 Aug 2004 00:12:44 -0000 @@ -280,7 +280,7 @@ sub sliderBar { my $value = shift; my $midpoint = shift; my $sym; - $midpoint = 50 unless defined $midpoint; + $midpoint = 0 unless defined $midpoint; if ($value < 0) { $value = 0; }