SqueezePlay And SqueezeCenter Plugins
From SqueezeboxWiki
Contents |
Adding Menus on SqueezeboxController and SqueezePlay from SqueezeCenter Plugins
The main menu hierarchy in SqueezePlay and Squeezebox Controller is now handled differently than deeper browse menus served by SqueezeCenter to SqueezePlay. This is to allow for an easier set of methods to manage what goes into these top level menus and where. Further discussion of the difference of these two types of SqueezeCenter->SqueezePlay "deliverables" can be FOUND HERE
Currently, the main menu hierarchy nodes look roughly like this (subject to change)
- Node: Home (id = 'home')
- Node: Music Library (id = 'myMusic')
- Node: Search (id = 'myMusicSearch')
- Node: Random Mix (id = 'randomplay'; added via Plugin)
- Node: Settings (id = 'settings')
- Node: Screen (id = 'screenSettings')
- Node: Advanced (id = 'advancedSettings')
- Node: Extras (id = 'extras')
- Node: Games (id = 'games')
- Node: Music Library (id = 'myMusic')
These are "nodes", i.e., menu items that serve as "directories" of other items also managed out of these methods. Non-nodes managed by these methods are called "items", and can take the form of either action items, choice items, text input items, or text area items.
Further ramblings on where things should go can be found on the user interface hierarchy and ControllerSettings wiki pages.
Adding a node from an SC Plugin
If your plugin needs to create a node, this is done through the Slim::Control::Jive::registerPluginNode() method.
Any item in the main menu structure needs to have a unique 'id', which allows it to be identified and managed as needed by the Controller itself. Further, any node needs to attach itself to a node as well. For example, if you wanted to add a node for your Foobar plugin, you would do this to register this item to SqueezePlay:
my $node = { text => 'Foobar', weight => 100, id => 'pluginFoobarMenu', node => 'settings', homeMenuText => 'Foobar Settings', window => { titleStyle => 'settings' }, }; Slim::Control::Jive::registerPluginNode($node, $client);
this will add a node with the text 'Foobar', and this node is added to the Settings node (which is in itself attached to the 'home' node). homeMenuText is an optional key-val pair that can set a different text string when this item is added to the top level menu via the SBC's Settings->Home Menu applet.
$client is an optional argument which can be sent if the node to be sent is specific to a certain player. In most cases, this argument is not necessary.
- the weight key is for ordering within the menu. You will need to look at what the weights are set to for other members of the node (default is 5) to understand where yours will be placed. Items with the same weight are sub-sorted alphabetically
- window: parameters for the window that is opened when descending into this node can be set in a hashref to the window key. In the example above, the "titleStyle" is set to 'settings'– this displays a mini-icon on the right side of the title bar that is demonstrative of a settings window.
- an optional item noCustom can be sent, which disallows SqueezePlay from allowing the user to add the item to the top level menu (through Settings->Home Menu)
The SqueezePlay main menu items from SC plugins are sent via Slim::Control::Jive::registerPluginMenu(). Arguments to registerPluginMenu are an array of menu items, (optionally) the node that you want to add them to, and (optionally) a $client object if the menu you are sending needs to be specific to a player (in most cases you do not need to do this). If you don't send a node as a second argument, you will need to add a node key to each item in the array. Node keys in items take precedence over the function argument.
my @menu = ( { # localize text where possible text => Slim::Utils::Strings::string('SOME_STRING'), id => 'pluginFoobarTweakSomething', weight => 10, actions => { do => { player => 0, cmd => [ 'someCustomPluginCommand', 'someArgument' ], params => { state => 'tweaked', }, } }, }, { # localize text where possible text => Slim::Utils::Strings::string('SOME_OTHER_STRING'), id => 'pluginFoobarActivateSomething', weight => 20, actions => { do => { player => 0, cmd => [ 'someOtherCustomPluginCommand', 'someOtherArgument' ], params => { activate => '1', }, } }, },); Slim::Control::Jive::registerPluginMenu(\@menu, 'settings', $client);
See SqueezeCenterSqueezePlayInterface for more information on the API for actions, menu items, etc.
It is possible that your plugin might have a dynamic nature to it, and after executing some code you need to tell SqueezePlay to update its main menu structure, or at least part of it.
With the new architecture, this is possible. Examples:
# refreshes any menu items driven by SC plugins Slim::Control::Jive::refreshPluginMenus($client); # $client is optional here-- if it's not used menu notification will update SqueezePlay no matter what player is selected # refreshes entire main menu item list from SC, all nodes all items # this part was added in svn r15471 Slim::Control::Jive::mainMenu($client); # refreshes just SC items in settings node (and sub nodes of settings) Slim::Control::Jive::playerSettingsMenu($client); # refreshes *only* the player power menu item Slim::Control::Jive::playerPower($client); # refreshes the "Music Library" node (and sub nodes of this one, including the search node) Slim::Control::Jive::myMusicMenu($client); # refreshes just the search node Slim::Control::Jive::searchMenu($client);
Sending the $client object is required for all methods except refreshPluginMenus().
Documentation to be added
- how to add choice items
- do vs. go actions
- text input windows
- textarea windows
- Slim::Control::Jive::deleteMenuItem