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
    • No tags
    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.
    Powered by MindTouch Core
    Real Time Web Analytics