mozilla
Your Search Results

    Windows and menus in XULRunner

    Our quest to build a basic desktop application using XULRunner 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 user interface:

    • Windows and dialogs
    • Menus and toolbars
    • OS Common dialogs
    • Controls or widgets

    Windows

    Each window or dialog should be created in its 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 to control its 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; this makes updating the text -- and localization of the application -- much easier. 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.

    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. You can learn how to do it in the article Window icons.

    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 are quite a few things XUL offers for application UI. More than I can fit into a single article, so we will continue looking at building UI in XULRunner in the next article.

    See also

    Original Document Information

    • Author: Mark Finkle
    • Last Updated Date: October 2, 2006

    Document Tags and Contributors

    Tags: 
    Last updated by: teoli,