Mozilla Platform – UI Basics [Part 1]

My quest to build a basic desktop application using XUL continues. Last time I installed XULRunner and built a very simple, bare-bones test application. This time I want to add some of the things common to a desktop application UI:

  • Windows and Dialogs
  • Menus and Toolbars
  • OS Common Dialogs
  • Controls or Widgets

Windows
Each window or dialog should be created in it’s own XUL file. The XUL file may also contain other top-level declarations for CSS and DTD, which I will discuss in a moment. <window/> is the basic windowing element in XUL. It has attributes to set the title/caption as well as control width and height. Although I have not seen it mentioned yet, I am assuming that you can only have one <window/> element per XUL file. Here is an example:


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

<!DOCTYPE window SYSTEM "chrome://basicapp/locale/main.dtd">

<window id="main"
    title="&title;"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="main.js"/>
...
</window>

Notice the references to CSS and DTD files. The CSS is used to apply formatting to elements, just as it would in HTML. The DTD is used to create entity references so strings for titles and labels are not stored directly in the XUL file. The window title is done this way in the above example. Also notice the <script/> element which is used to include the window’s Javascript into the XUL file. Keeping CSS, DTD and Javascript out of the XUL file is considered a best practice. These references have more information on windows.

When you launch your XUL application, you’ll notice that XULRunner gives your windows a default icon (top left corner on Windows). You’ll most likely want to specify your own icons. Here is how to do it.

Menus and Toolbars
Most desktop applications are complex enough to require some sort of menu and/or toolbar to structure the application’s available commands. XUL provides elements to support both menus and toolbars. Building on the simple window code, here is what XUL menus and toolbars look like:


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

<!DOCTYPE window SYSTEM "chrome://basicapp/locale/main.dtd">

<window id="main"
    title="&title;"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script src="main.js"/>
  <toolbox>
    <menubar id="menubar">
      <menu id="file-menu" label="&file;">
        <menupopup id="file-popup">
          <menuitem label="&file.new'" oncommand="doFileNew();"/>
          <menuitem label="&file.open;" oncommand="doFileOpen();"/>
          <menuitem label="&file.save;" oncommand="doFileSave();"/>
          <menuseparator/>
          <menuitem label="&file.exit;" oncommand="doFileExit();"/>
        </menupopup>
      </menu>
      <menu id="edit-menu" label="&edit;">
        <menupopup id="edit-popup">
          <menuitem label="&edit.undo;" oncommand="doEditUndo();"/>
          <menuitem label="&edit.redo;" oncommand="doEditRedo();"/>
        </menupopup>
      </menu>
    </menubar>
    <toolbar id="main-toolbar">
      <toolbarbutton id="open" label="&file.open;" oncommand="doFileOpen();"/>
      <toolbarbutton id="save" label="&file.save;" oncommand="doFileSave();"/>
    </toolbar>
  </toolbox>
...
</window>

Notice that I used entity-references for the menu and toolbar labels. The oncommand event is hooked up to Javascript, just like an onclick in HTML. The Javascript is contained in the main.js file. XUL has a way to centralize commands and event handlers for menus and toolbars that do the same thing, like open and save in the above example. You can add a <commandset/> and <command/> elements like this:


<commandset>
  <command id="cmd_open" label="&file.open;" oncommand="doFileOpen();"/>
  <command id="cmd_save" label="&file.save;" oncommand="doFileSave();"/>
</commandset>
...
<menuitem  command="cmd_open"/>
<menuitem command="cmd_save"/>
...
<toolbarbutton id="open" command="cmd_open"/>
<toolbarbutton id="save" command="cmd_save"/>
...

We can add images to the toolbar buttons through the CSS file. We could hard-code the images in the XUL file itself, but CSS is a better practice. Here’s the CSS file:


/* global skin --------------------------------------------------- */
@import url(chrome://global/skin/);

/* toolbar ------------------------------------------------------- */
#open {
  list-style-image: url(chrome://basicapp/skin/open.png);
  -moz-box-orient: vertical;
}

#save {
  list-style-image: url(chrome://basicapp/skin/save.png);
  -moz-box-orient: vertical;
}

Of course, you need to make sure the PNG files are included in the application.

There is quite a bit of things XUL offers for application UI. More than I can fit into a single post, so I will wrap this post up and will continue looking at UI basics in the next one.

2 Comments

  1. Mark Finkle’s Weblog » Blog Archive » Mozilla Platform - Basic Desktop Application said,

    July 30, 2006 @ 7:28 pm

    [...] UI Basics [Part 1] [...]

  2. Mark Finkle’s Weblog » Blog Archive » Mozilla Platform - UI Basics [Part 2] said,

    August 28, 2006 @ 6:17 am

    [...] Mark Finkle’s Weblog « Mozilla Platform – UI Basics [Part 1] [...]

RSS feed for comments on this post