Updating Extensions for Songbird 1.4.1

Introduction

Songbird 1.4.1 rolled out a new Feather, "Purple Rain" to address many of the usability issues and feedback we'd gotten from users.  While most of the changes won't affect extension developers, there is one fairly significant change for any extensions that utilise display panes -- specifically, ones that utilise the display pane header navigation elements (the label title, button, and tab elements).

Picture 1.png
Album Art is an exception in
the use of display pane titles

Previously, in Gonzo, we had allowed display panes to set titles, overload the display pane titlebar to be a button (ala what Album Art did for toggling between "Now Playing"/"Now Selected", and what LyricMaster did for enabling/disabling notifications), or overload the display pane titlebar to be a tab navigation element (e.g. mashTape).  This was found to be confusing for users, as there weren't strong visual indications that the header was a button, or due to the tab bar being so condensed.

In Purple Rain, we've gotten rid of the button and tab bar elements.  While extensions can continue to set titles, we strongly encourage extension developers to move away from this unless absolutely necessary (of the bundled Songbird extensions in the first-run/recommended bundle, we only use this for Album Art as a special case).  Additionally, the right sidebar display pane's splitter (where the titles are overlaid) runs vertically, so labels/titles won't be possible for this space.

New Display Pane Sub-menu Customisation

For extensions that wish to provide navigation elements, we have a new alternative.. extensible (and virtually unlimited) sub-menus available via callback hooks that plug into the add-on picker (i.e. the drop-down menu available in the display pane splitter).  We utilise this in Album Art to allow the user to conveniently switch between "Now Playing" and "Now Selected" states.  We also helped update LyricMaster to do this to toggle notifications.

Album Art submenu
Album Art submenu
LyricMaster submenu
LyricMaster submenu

In order to utilise this, your display pane JS should define a top-level method named onDisplayPaneMenuPopup() which will take three parameters:

function onDisplayPaneMenuPopup(commandString, menupopupElement, documentElement)

where the parameters are:

  • commandString - a string denoting the action occuring.  Currently only two commands are supported:
    • create - called when the menupopup is being created.
    • destroy - called when the menupopup is being destroyed.
  • menupopupElement - the XUL element representing the menupopup DOM element.  Any menuitems or submenus you create should be appended to this element.
  • documentElement - the XUL element corresponding to the document managing the menupopup.  You'll need this to createElement from.

 

When the menupopup is created (i.e. when the user has clicked on the drop down menu button in the display pane splitter), your onDisplayPaneMenuPopup() routine will be called with the first parameter being set to "create".  It is your routine's responsibility to then create any menuitem or menupopup elements (for submenus) using the passed in documentElement, and then append them to the menupopupElement created by Songbird.

Similarly, when the menupopup is destroyed, your onDisplayPaneMenuPopup() will be called with the first parameter being set to "destroy".  It is your add-ons responsibility to keep track of any elements you may have connected to the display pane menupopup during the "create" phase, and subsequently destroy them during the "destroy" phase.  In practice, for simple cases, this can usually be limited to simply keeping track of the menupopup element, and destroying all attached children.

Here is full code for a sample implementation derived from the Album Art & LyricMaster usages of this callback:

/* Function invoked by the display pane manager to populate the display pane menu. */
function onDisplayPaneMenuPopup(commandString, menupopupElement, documentElement) {
  switch (commandString) {
    case "create":
      var menuitem1 = documentElement.createElement("menuitem");
      menuitem1.setAttribute("label", "Switch to Test Mode 1);
      menuitem1.setAttribute("type", "radio");
      menuitem1.addEventListener("command", myExtension.setTestMode1, false);
      menupopup.appendChild(menuitem1);
      
      var menuitem2 = documentElement.createElement("menuitem");
      menuitem2.setAttribute("label", "Switch to Test Mode 2");
      menuitem2.setAttribute("type", "radio");
      menuitem2.addEventListener("command", myExtension.setTestMode2, false);
      menupopup.appendChild(notifDisabledMenu);

      // Initialise our checked state based on the extension's saved pref
      if (myExtension.mode == 1)
        menuitem1.setAttribute("checked", "true");
      else
        menuitem2.setAttribute("checked", "true");

      // Save reference to the menupopup for cleanup
      myExtension._menupopup = menupopup;
      break;
    case "destroy":
      while (myExtension._menupopup.firstChild)
        myExtension._menupopup.removeChild(myExtension._menupopup.firstChild);
      break;
    default:
      break;
  }
}

var myExtension = {
  _mode : 1,
  _menupopup: null,

  setTestMode1 : function() {
    myExtension._mode = 1;
  }
  
  setTestMode2 : function() {
    myExtension._mode = 2;
  }
}
Picture 5.png
Using the same navigation
choices in your context menu
simplifies user experience

If your add-on utilises a context menu for the display pane, then we also recommend providing the same navigation choices in that context menu, as we do in Album Art & LyricMaster.

Removal of Display Pane Titlebar Navigation Tabs

For add-ons that utilised display pane header tabs like mashTape previously did, we recommend moving towards using the display pane content browser space for your navigation elements as we've done in our revised mashTape design.  Users complained that the display pane header tabs were too small to easily navigate and were unintuitively overloaded too close to the splitter for resizing display panes.

Picture 7.png

Use in-browser tabs for more intuitive navigation

Toolbar Buttons

Due to some CSS constraints, we moved away from the generic bg-button background images that were given to all toolbar buttons.  Previously you could use standard 16x16 images for toolbarbuttons your extension may be adding, and get a background image from the Feather for "free".  In Purple Rain, we moved towards 23x20 images with background images "built-in" to the graphic. 

Ultimately, when we upgrade to XULRunner 1.9.2 in a couple of releases, we should be able to revert to something that will let Extension authors again use Feather-agnostic toolbarbutton images, but in the interm, you'll have to provide something here that Featherers can then override using chrome override URLs.

Alternatively, you might want to move away from toolbarbuttons altogether.  They aren't shown by default if the user doesn't have a tabbrowser open (since the nav-bar is hidden), so aren't the best for an "always-on" UI presence.

Tag page
FileSizeDateAttached by 
 Picture 1.png
No description
15.25 kB12:46, 12 Dec 2009stevelActions
 Picture 2.png
No description
27.15 kB12:46, 12 Dec 2009stevelActions
 Picture 4.png
No description
24.51 kB12:46, 12 Dec 2009stevelActions
 Picture 5.png
No description
24.58 kB12:46, 12 Dec 2009stevelActions
 Picture 7.png
No description
79.82 kB12:46, 12 Dec 2009stevelActions
You must login to post a comment.