Archive for August, 2006

Mozilla Platform – UI Basics [Part 2]

Last time I covered some simple XUL for creating windows, menus and toolbars. This time I’ll look at dialogs, your own and common OS dialogs too. Dialogs are pretty fundamental to a desktop application. Certain types of dialogs are used over and over. So much so that the OS can provide a default implementation. File open and save are good examples. Whenever possible, it is a good idea to reuse these ‘native’ dialogs so users get a consistent experience across applications.

Custom Dialogs

Building dialogs in XUL is very similar to creating windows. Each dialog seems to be in it’s own XUL file. Also like windows, XUL provides a <dialog/> element to act as the container for the dialog. As their window counterparts, dialog XUL files can have DTD, CSS, JS links too. Here is an example XUL dialog:


<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<dialog id="myDialog" title="My Dialog"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        onload="window.sizeToContent();"
        buttons="accept,cancel"
        buttonlabelaccept="Set Favorite"
        buttonaccesskeyaccept="S"
        ondialogaccept="return doSave();"
        buttonlabelcancel="Cancel"
        buttonaccesskeycancel="n"
        ondialogcancel="return doCancel();">

  <script>
    function doSave(){
     //doSomething()
     return true;
    }

    function doCancel(){
      return true;
    }
  </script>

  <dialogheader title="My dialog" description="Example dialog"/>
  <groupbox flex="1">
    <caption label="Select favorite fruit"/>
    <radiogroup>
      <radio id="1" label="Oranges because they are fruity"/>
      <radio id="2" selected="true" label="Strawberries because of color"/>
      <radio id="3" label="Bananna because it pre packaged"/>
    </radiogroup>
  </groupbox>

</dialog>

XUL window elements have a special method to openDialogs. Here is the code needed to open a dialog:


function openDialog() {
  window.openDialog("chrome://basicapp/content/dialog.xul", "newdlg", "modal");
}

mydialog.png
(on Win2K)

The first thing that caught my eye about <dialog/> is the button and related attributes. In an effort to make things easier for developers and more consistent for users, XUL has a mechanism to auto create and position the core dialog buttons (‘ok’, ‘cancel’ and help’ for example). The developer just declares the need for the button, the caption and access key for the button and the JS function to call if the button is pressed. XUL handles placing and styling the buttons on the dialog. This is also nice for cross-platform applications too. Each OS seems to have its own convention for where buttons should be placed on a dialog. Here is a short list of the button attributes (see the above link for a complete reference):

  • buttons – comma separated list of buttons to show on dialog (‘accept’, ‘cancel’, ‘help’, ‘extra1′ and ‘extra2′)
  • buttonlabelaccept – label for accept button (same for other buttons)
  • buttonaccesskeyaccept – access key for accept button (same for other buttons)
  • ondialogaccept – Javascript to execute if accept is pressed (same for other buttons)

XUL has a wide range of input controls you can use on a dialog. In the future, I will try to go into more detail on some of the existing and planned XUL input controls. Not too sure if I’ll use the <dialogheader/>, but if I did, the single element would be a big time saver over building the header from scratch.

Common Dialogs

Some of the most frequently used common dialogs are for opening and saving files. For instance, Windows has supported builtin file open and file save dialogs for many years. It makes creating an application easier for developers. The consisent UI also makes using an application easier too. XUL supports native implementations of filepickers (Mozilla for File Open and Save dialogs). Newer releases will allow using preferences to switch to a XUL emulation filepicker, if you want to. The XUL filepickers are XPCOM components and must be instantiated before using, like this:


function doFileOpen() {
  /* See: http://developer.mozilla.org/en/docs/XUL_Tutorial:Open_and_Save_Dialogs */
  
  var nsIFilePicker = Components.interfaces.nsIFilePicker;
  var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);

  fp.init(window, "Open File", nsIFilePicker.modeOpen);
  fp.appendFilters(nsIFilePicker.filterText | nsIFilePicker.filterAll);
  
  var res = fp.show();
  if (res == nsIFilePicker.returnOK) {
    var thefile = fp.file;
    alert(thefile.leafName);
    // --- do something with the file here ---
  }  
}

XUL does not appear to currently support any other common dialogs. That could change with Firefox 2 and 3 releases coming up. Firefox and Thunderbird both support nearly native Page Setup and Print dialogs. However, XUL does support elements to make creating Wizards a simple task as well.

I still want to look at Input Controls, Printing, Clipboard and XPCOM.

Comments (2)