User Tools

Site Tools


developer_center:recipe_book:extensions_and_core:playlist_buttons_aka_playlist_commands:playlist_command_visibility_callbacks

Playlist Command Visibility Callbacks

setVisibleCallback and setCommandVisibleCallback

Every playlist command can have a visibility callback specified that determines under what conditions that command and it's children will and will not appear. For examples and some of the most common visibility callbacks see Playlist Command Callback Templates.

Visibility callbacks can be specified with either of two methods in sbIPlaylistCommandsBuilder.

  • setVisibleCallback(in sbIPlaylistCommandsBuilderPCCallback aVisibleCallback)
  • setCommandVisibleCallback(in AString aParentSubMenuId, in AString aCommandId, in sbIPlaylistCommandsBuilderPCCallback aVisibleCallback)

These methods differ on what is affected by the provided aVisibleCallback with setVisibleCallback setting aVisibleCallback as the visibility callback for the playlist command on which the method was called, while setCommandVisibleCallback sets aVisibleCallback for a subcommand of the playlist command on which setCommandVisibleCallback is called.

To demonstrate this difference consider:

/* Javascript, difference between setVisibleCallback and setCommandVisibleCallback */

  // setup our command builder
  const PlaylistCommandsBuilder = 
      new Components.Constructor("@songbirdnest.com/Songbird/PlaylistCommandsBuilder;1", 
                                 "sbIPlaylistCommandsBuilder", 
                                 "init");

  // make our root command
  var rootCommand = new PlaylistCommandsBuilder("my-root-command");

  // append the first action
  rootCommand.appendAction(null, // this isn't going into a submenu
                           "first-action", // the action's id
                           "First!", // a user-facing label
                           "unused tooltip", 
                           TriggerCallback1);
                           
  // append a second action
  rootCommand.appendAction(null, // this isn't going into a submenu
                           "second-action", // the action's id
                           "Second", // a user-facing label
                           "unused tooltip", 
                           TriggerCallback2);


  // an sbIPlaylistCommandsBuilderPCCallback that always returns false for setVisibleCallback
  var visCallback = function (aContext, aHost, aData) { 
    return false; 
  }

  /*
   * This will change the visibility of rootCommand, 
   * and thus both actions will not be visible       
   */
  rootCommand.setVisibleCallback(visCallback);
  
  /*
   * This will change the visibility of only "second-action", 
   * so the button labeled "First!" should still be visible     
   */
  rootCommand.setCommandVisibleCallback
             (null, // "second-action" is not in a submenu
              "second-action", // select the subcommand that we want to affect
              visCallback);

A note about setCommandVisibleCallback

It is worth noting that as of June 2011, setCommandVisilbleCallback takes the wrong type of callback. Whereas setVisibleCallback rightfully takes an sbIPlaylistCommandsBuilderPCCallback, setCommandVisibleCallback currently takes a sbIPlaylistCommandsBuilderGetBoolCallback instead. This is incorrect because the method that checks if a command should be visible expects it to be an sbIPlaylistCommandsBuilderPCCallback which means a handleCallback of the form:

handleCallback(in sbIPlaylistCommandsBuilderContext aContext, in AString aHost, in AString aData)

If you would like to use setCommandVisibleCallback but it still expects an sbIPlaylistCommandsBuilderGetBoolCallback, you can get all the same functionality by simply implementing your callback to expect params 2 and 3 to be aHost and aData respectively and not aSubMenuId and aCommandId as sbIPlaylistCommandsBuilderGetBoolCallback would want.

Defining a Visibilty Callback

Visibility callbacks are defined differently in C++ and Javascript with Javascript making things significantly easier. In Javascript a function can be passed directly as the visibility callback to either of the setters. This means that you can do the following:

/* Javascript, defining a visibility callback */

  // the visibility callback function
  var visCallback = function (aContext, aHost, aData) { 
    
    // do stuff to determine if shouldBeVisible
    
    return shouldBeVisible;
  }

  newCommand.setVisibleCallback(visCallback);

In C++, however, you must create a class that implements sbIPlaylistCommandsBuilderPCCallback's handleCallback. This can make things significantly more verbose as the following shows:

/* C++, defining a visibility callback */

class sbPlaylistCommandsVisibility : public sbIPlaylistCommandsBuilderPCCallback
{
  public:
    NS_DECL_ISUPPORTS;
    NS_DECL_SBIPLAYLISTCOMMANDSBUILDERPCCALLBACK;
    sbPlaylistCommandsVisibility();
    virtual ~sbPlaylistCommandsVisibility();
};

sbPlaylistCommandsVisibility::sbPlaylistCommandsVisibility()
{
}

/* virtual */ sbPlaylistCommandsVisibility::~sbPlaylistCommandsVisibility()
{
}

NS_IMETHODIMP
sbPlaylistCommandsVisibility::HandleCallback
                              (sbIPlaylistCommandsBuilderContext *aContext,
                               const nsAString &aHost,
                               const nsAString &aData,
                               PRBool *_retval)
{
  NS_ENSURE_ARG_POINTER(aContext);
  NS_ENSURE_ARG_POINTER(_retval);
  
  // do stuff to determine if shouldBeVisible

  *_retval = shouldBeVisible;
  return NS_OK;
}

NS_IMPL_THREADSAFE_ISUPPORTS1(sbPlaylistCommandsVisibility,
                              sbIPlaylistCommandsBuilderPCCallback);

// ...

  sbPlaylistCommandsVisibility visCallback = new sbPlaylistCommandsVisibility();
  
  rv = newCommand->SetVisibleCallback(visCallback);
  NS_ENSURE_SUCCESS(rv, rv);

All visible callback's receive three parameters

  • aContext, an sbIPlaylistCommandsBuilderContext with the following attributes:
    • commands: a reference to the owning sbiPlaylistCommandsBuilder
    • medialist: the medialist for which the callback was called
    • playlist: the playlist binding for which the callback was called
    • window: a reference to the window
    • implementorContext: an all-purpose, nsISupports receptacle that can be used to save information about a playlist commands action or the state when the callback was called
  • aHost, a string indicating the location the command's visibility is currently being evaluated for. Options are:
    • “toolbar” for the toolbar at the bottom of the medialistview
    • “menu” for the context menu (both mediaitem and servicepane context menus use this hoststring)
    • “shortcuts” for keyboard shortcuts (callbacks must return true when aHost = “shortcuts” for the specified shortcut to be available)
  • aData, a string data payload that should always be “Visible” when passed to your visibility callback

For other callback examples and some commonly used callbacks see Playlist Command Callback Templates.

developer_center/recipe_book/extensions_and_core/playlist_buttons_aka_playlist_commands/playlist_command_visibility_callbacks.txt · Last modified: 2013/12/28 09:57 by geekshadow