[% pageicon = 'help' %] [% pagetitle = 'Display API' %] [% techinfo = '1' %] [% PROCESS helpheader.html %]

Display Hash

As of 6.2, the preferred method to define the display for a player's screen is via a display hash. All display functions have been updated to support the hash based api.

The standard 2 line display with 2 overlays is described as:

my $hash = {
   'line1'    => 'Text to appear on top line',
   'line2'    => 'Text to appear on bottom line and possibly scroll',
   'overlay1' => 'Overlay to appear at right of top line',
   'overlay2' => 'Overlay to appear at right of bottom line',
}

Centered text is described as:

my $hash = {
   'center1' => 'Text to be centered on top line',
   'center2' => 'Text to be centered on bottom line',
}

Symbols are typically displayed in one of the overlays but can exist in any component. Individual symbols can be added to the hash using $client->symbols():

my $hash = {
   'line1'    => 'Text to appear on top line',
   'line2'    => 'Text to appear on bottom line and possibly scroll',
   'overlay1' => $client->symbols('notesymbol'),
}

See $client->symbols() below for valid symbol names.

Player Specifics

All player types (Slimp3/Squeezebox/Squeezebox-Graphics/Squeezebox2) are intended to display in as similar way as possible. However there are some specifics due to the limited screen resolution of some hardware:

Text Displays (Slimp3/Squeezebox):

In two line mode overlays are displayed. If center1/2 exists for a line then this takes precedence over line1/2 such that only the centered text and overlay are displayed.

Overlays truncate line1/2 so that the overlay is always displayed. In the case of line1, text is simply truncated so the overlay fits. In the case of line2, text will potentially scroll within the region of the screen to the left of overlay2. Centered text will also be truncated by overlays if they appear in the same position.

In single line mode overlays are not displayed by default. Again centered text takes precedence such that if center2 exists then line2 will not be displayed.

Graphic Displays (Squeezebox-Graphics, Squeezebox2):

Graphics players attempt to display all components at the same time, so that both center1/2 and line1/2 are displayed. Overlay1/2 truncate line1/2 in the same way as for text players. However centered text is not truncated by the overlays. As the resulting bitmaps for each text component are displayed on top of each other, it is the calling function's responsibility to avoid overlapping text - e.g. by centered text overlapping overlays.

Bitmaps

Graphics players may also display a bitmap:

my $hash = {
   'bits' => $bitmap,
}

Where $bitmap is a byte string which defines a bitmap of appropriate size for the display. The bitmap will be displayed on top of any other text defined in the same display hash.

Squeezebox 1 G takes a 280 x 2 byte bitmap, with the first byte defining the top 8 bits of the left most display column the second byte defining the lower 8 bits. The 3rd & 4th byte describe the second column etc.

Squeezebox 2 takes a 320 x 4 byte bitmap, with the first byte defining the top 8 bits of the first column, the next 3 defining the rest of the first column etc.

Fonts

The display hash can define a font element to define the font to be used for a display. If it exists it takes precedence over the current font for the player.

A simple font element is used to define a single font to use for all components of the display:

my $hash = {
   'line1' => 'Text to appear on top line',
   'line2' => 'Text to appear on bottom line and possibly scroll',
   'fonts' => {
       'graphic-320x32' => 'standard',
       'graphic-280x16' => 'small',
       'text'           => 2,
       }
}

As different player use different fonts, it is normal to define the font for each type of player:

The font element may also take a more detailed definition to allow more complex displays to be defined.

For graphics players, the specific font for each of line1/line2/overlay1/overlay2/center1/center2 can defined. If the font for only some components are defined, other components take the current active font for the player.

The following fixes the font for overlay1, but leaves all other fonts as the currently active player font:

my $hash = {
   'fonts' => { 
       'graphic-280x16'  => { 'overlay1' => \ 'small.1' },
       'graphic-320x32'  => { 'overlay1' => \ 'standard.1' },
       }
}

Note: the font name should be the font file name including the line number. It is specified as a reference to a string. [This is used to speed up the font rendering code]

By setting non standard fonts for each component it is possible to create new types of display. For example using 'standard.1' for line2 and 'standard.2' for line1 means that the top line of the display can be made to scroll. [Only line2 scrolls, but by changing the font it appears on a different portion of the screen.] Care should be taken in setting the overlay fonts to match as the point at which line1 & line2 are truncated is based on the respective overlays.

For text players, the font element may define the number of lines and also force display of overlays in single line mode:

my $hash = {
   'fonts' => { 
       'text'  => { 'lines' => 1,
                    'displayoverlays' => 1
		  },
       }
}
Scrolling

For all players, text in line2 will scroll if it is too long to fit into the space to the left of overlay2. The default operation of scrolling for a player is set via preference 'scrollMode', but can be overridden by setting 'scrollmode' in the display hash:

my $hash = {
   'scrollmode' => < 'scrollonce' | 'noscroll' | 'ticker' >
}

Where 'scrollonce' means line2 will scroll round once but then stop scrolling until it changes. 'noscroll' indicates that line2 should not scroll. 'ticker' is a special scroll mode which is described below.

Normal scrolling of line2 shows as much of line2 as will fit to the left of overlay2. This is displayed without scrolling for the 'scrollPause' interval. Line2 then rotates to the left to the point when the start of line2 is displayed again. At this point the display pauses again before continuing the rotation.

During scrolling, if update is called with a display hash which changes line1, overlay1 or overlay2 these are updated without interrupting scrolling. This allows scrolling to continue while elapsed times etc are updated, for example in the Now Playing screen.

Ticker Scrolling

Ticker scrolling is designed to be used by screensavers such as the RssNews. It changes the scrolling operation to that of a ticker display - text appears from the right edge, scrolls across the screen and off the left side. It does not rotate in the manner of normal scrolling.

Ticker scrolling is activated by setting the 'scrollmode' to 'ticker' in the display hash and is cleared as soon as a display hash without this is sent to update.

Items are added to the ticker by calling update with a display hash such as:

my $hash = {
   'line1' => 'Non scrolling top line',
   'line2' => 'New item to be added to ticker',
   'scrollmode => 'ticker',
}

If line1/overlay1/overlay2 changes during ticker mode these are displayed immediately. However if anything is defined for line2, this is added to the ticker queue and will appear once items currently in the ticker queue have been displayed.

The function: $client->scrollTickerTimeLeft() is used to find the current length of the ticker queue and is used to optimise when new items are added to the queue:

my ($complete, $queue) = $client->scrollTickerTimeLeft();

Where $complete is the approx number of seconds left before all text disappears off the left hand side of the display. $queue is the approx number of seconds worth of text which is queued up but has not yet appeared on the right edge of the display.

A lines function may use this to decide whether to return undef or text for line2. If undef is returned for line2, nothing is added to the ticker queue allowing it to drain.

For example to maintain a ticker using a lines function which is called once per second:

sub lines {
   my $client = shift;
   my ($complete, $queue) = $client->scrollTickerTimeLeft();
   
   my $text = 'Whatever you want to add to the ticker';

   return( {
      'line1' => 'Fixed top line',
      'line2' => ($queue < 1) ? $text : undef,
      'scrollmode' => 'ticker',
   });
}

Display Functions

Displays are sent to the screen via one of the display functions:

$client->update()

This is the normal way of updating the display. Updated is normally called with no params and in this case the lines function registered for the current mode is called to determine the display hash.

Update can be called with a display hash to display something other than the current lines immediately:

$client->update( {
   'line1' => 'line1 display',
   'line2' => 'line2 display',
}

However as the server may call $client->update() to refresh the display this is not recommended. It is normal to use the lines function to return the display and call $client->update() to use it.

If a plugin wishes to update the display on a regular basis, this is best done by setting the following in the setMode function:

$client->param('modeUpdateInterval', X);

Where X defines the number of seconds between each update. The server will automatically call update every X seconds whilst in this mode.

$client->showBriefly()

This is used to display a message on the screen for a short period of time, before returning to the normal display of the mode.

showBriefly should always be called with a display hash and one or more optional parameters:

$client->showBriefly($hash, $duration, $firstline, $blockupdate)

For example:

$client->showBriefly( {
   'line1' => $line1,
   'line2' => $line2,
   'overlay2' => $client->symbols('notesymbol'),
}, 5, undef, 1);

Displays two lines plus an overlay for 5 seconds and is not cancelled by updates during this time.

[showBriefly also accepts the old $line1, $line2 in place of the display hash for backwards compatibility. Note however that as showBriefly now takes a display hash, there is no need to use $client->renderOverlay() to build a display to send to showBriefly]

$client->block()

This is used to display a message for a period of time with a spinning activity notification in overlay1. The message is displayed using the 'block' mode so that it is not interrupted and is only cleared by a call to $client->upblock().

$client->block($hash)

For example:

$client->block( {
   'line1' => string('PLAYER_NEEDS_UPGRADE_1'), 
   'line2' => string('PLAYER_NEEDS_UPGRADE_2'),
   'fonts' => { 
      'graphic-320x32' => 'standard',
      'graphic-280x16' => 'small',
      'text'           => 2,
      }
});

This forces the font so that two lines are displayed and displays two strings until $client->unblock() is called.

[block also takes $line1, $line2 for backwards compatibility]

Lines

A mode's lines function should return the display hash to display when $client->update() is called.

A simple lines function would be:

sub lines {
    my $client = shift;

    return {
       'line1'    => 'Line1 text',
       'line2'    => 'Line2 text',
       'overlay1' => $client->symbols('notesymbol'),
    };
}

A more complex lines function which specifies the fonts and scrolling mode would be:

sub lines {
    my $client = shift;

    return {
       'line1'      => 'Line1 text',
       'line2'      => 'Line2 text',
       'overlay1'   => $client->symbols('bell'),
       'scrollmode' => 'scrollonce',
       'fonts'      => { 
           'graphic-280x16'  => { 'overlay1' => \ 'small.1' },
           'graphic-320x32'  => { 'overlay1' => \ 'standard.1' },
           'text' =>            { 'lines' => 2,
                                  'displayoverlays' => 1,
                                  },
           },
    };
}

Note: A lines function which returns a display hash is responsible for converting symbol names to symbol characters. The lines function should therefore call $client->symbols() on any text which contains symbols prior to adding to the display hash.

$client->symbols()

$client->symbols() is used to convert the names of symbols to the graphic character representing the symbol itself. As of 6.2 the preferred use of $client->symbols() is as a replacement for Slim::Display::Display:symbol to specify individual symbols. However it can also be used to parse a complete text line and convert symbol tokens (created by Slim::Display::Display::symbol) into the symbol character.

Preferred use:

return {
   'line1'    => 'text '.$client->symbols('bell').' more text',
   'overlay2' => $client->symbols('bell'),
}

Valid symbol names are currently:

$client->curLines()

$client->curLines() returns a display hash using the current lines function. This is equivalent to the display that would result from calling $client->update().

The method returns the same information as Slim::Display::Display::curLines(), but always returns a display hash even if the lines function itself does not return a display hash.

$client->curDisplay()

$client->curDisplay() returns a display hash containing the text components of the current display. [It contains each of line1, line2, overlay1, overlay2, center1, center2 but does not contain font or scrolling elements.]

The difference between $client->curDisplay() and $client->curLines() is that $client->curLines() makes a call to the mode's lines function and hence potentially gets a new display, whereas $client->curDisplay() returns what is currently being displayed.


Menu Transitions

The scrolling menu transitions which make up the slim user interface are controlled by push and bump animation commands. Push animations are used for transition to new menu screens. Bump animations are used to bump the screen against the edge, normally when the end of a menu structure is reached.

$client->pushLeft($start, $end), $client->pushRight($start, $end)

Pushes the old screen off the left/right side of the display and replaces it with a new screen.

SB2 does not use $start as it uses the existing displayed screen for $start. As of 6.2, $start may be set to undef for other players. In this case the server uses the last displayed screen for $start.

As of 6.2 $end may also be set to undef. In this case, the server will call the current lines function to define $end. It is therefore acceptable to use e.g. $client->pushLeft() to carry out a menu transition.

$client->pushUp($end), $client->pushDown($end)

On SB2 this scrolls the bottom line (or all text if in one line mode) to move to the next menu or list item. On all other player it simply calls $client->update() to display a new screen with the new display. As $end can only be set for SB2 it is not normally used. The new screen to display is therefore defined by the current lines function. Normally called as e.g. $client->pushUp().

$client->bumpLeft(), $client->bumpRight()
$client->bumpUp(), $client->bumpDown()

Used to bump the current screen against the edge of the display to indicate that no additional menu items are available.


Custom Characters

Custom characters may be defined for both character and graphic display players. These enable lines functions to display customised symbols as icons and to build up complex displays for e.g. games like SlimTris.
Character Displays
The character display hardware uses a fixed font definition for all normal characters (See here).

It also supports definition of up to 8 custom characters per display. These may be defined by plugins and used anywhere on the display.

Slimserver allows you to define as many custom characters using: Slim::Hardware::VFD::setCustomChar().

Each display screen can then use up to 8 custom characters. If more custom characters exist on a screen they will be replaced with a blank character. [NB slimserver also uses custom characters for the predefined symbols which also count towards this limit.]

Each custom character is 5 pixels wide and 7 pixels high plus an underline which is either on or off [equivalent of a single wide pixel].

For example to define a custom character to be called 'slimtristop':

Slim::Hardware::VFD::setCustomChar( 'slimtristop', ( 
		0b00000000, 
		0b00000000, 
		0b00000000, 
		0b00000000, 
		0b00011110, 
		0b00011111, 
		0b00011111,

		0b00000000
		));
Note: The 3 most signifcant bits of each line are not used.

Custom characters do not work in 1 line mode on character displays.

Graphics Displays
Graphic displays may display custom characters through the use of custom font files.

Custom font files define a bitmap to use for each character in the custom font. The format of font files is described here.

The function Slim::Player::SqueezeboxG::setCustomChar() is used to register a name to associate with specific characters. This may be used to give names for each character in a custom font.

For example:

Slim::Player::SqueezeboxG::setCustomChar( 'slimtristop', "\x02" );
Registers the 'slimtristop' for character "\x02".

Note that name to character mappings are independant of font, but only make sense when used with the appropriate font - see below.

Displaying Custom Characters
Custom characters may be included in a display by using the character name with $client->symbols(). For example:
$parts = {
    'line1' => $client->symbols('slimtristop').$client->symbols('slimtristop'),
    'fonts' => {
    'graphic-320x32' => { 'line1' => \ 'trisSB2.1' },
    'graphic-280x16' => { 'line1' => \ 'trisSBG.1' },
      },
};
Will display 2 'slimtristop' custom characters on line1 of the display.

For character displays it assumes this character has been defined using Slim::Hardware::VFD::setCustomChar().

For graphic displays it assumes the name to character mapping has been defined using Slim::Player::SqueezeboxG::setCustomChar() and that the font file defined in the display hash contains this character. An appropriate font file should be defined for each type of graphic display.

Note at present, Graphic displays can only mix text and custom characters in a display component (e.g. line1) if the font file defines both the custom characters and all text characters. This is because each display component must use a single font.

Character displays may mix standard and custom characters in 2 line mode.

[% PROCESS helpfooter.html %]