Archive for July, 2006

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.

Comments (2)

Mozilla Platform – Getting Started with XULRunner

I want to build a simple XUL-based Windows desktop application. If you’re going to build a XUL-based desktop application, you’ll probably need to install XULRunner. In this post, I try to get XULRunner installed and make sure it runs a bare-bones application.

Step 1 – Download XULRunner: The Mozilla developer page lists 1.8.0.1 as the most recent release, but I see there is also a 1.8.0.4, so that is the one I downloaded. UPDATE: 1.8.0.4 release and SDK are available from Mozilla FTP.

The XULRunner download is a ZIP file, not a true install. As a developer, I like the idea that XULRunner only needs to be unzipped onto my machine. I am assuming that it doesn’t need to hook into my Windows system and that’s a good thing.

Step 2 – Install XULRunner: I unzipped the archive to a new “c:\program files\xulrunner” folder. Pretty simple so far.

Time to start a simple, bare bones application shell. Call it a XUL “Hello World” if you want, but I need to make sure that XULRunner will work at all. Googling turned up a nice tutorial here. It is definately worth reading. Using the tutorial, I created a simple bootstrap application. All of what you see below can be found in Ryan’s tutorial and the Mozilla XULRunner documentation pages.

Step 3 – Create application folder struture: I create the root in a new “c:\program files\xulapp” folder. Here is the subfolder structure:


/xulapp
  /chrome
    /content
      main.xul
    chrome.manifest
  /defaults
    /preferences
      prefs.js
  application.ini

Notice that there are 4 files in the folder structure: application.ini, chrome.manifest, prefs.js & main.xul

Step 4 – Setup application.ini: The application.ini file acts as the XULRunner entry point for your application. It seems to be used to configure how your application intends to use the XULRunner platform as well as configure some information that XULRunner uses to run your application. Here is mine:


[App]
Vendor=Finkle
Name=Test App
Version=1.0
BuildID=20060101
Copyright=Copyright (c) 2006 Mark Finkle
ID=xulapp@starkravingfinkle.org

[Gecko]
MinVersion=1.8
MaxVersion=1.8

Step 5 – Setup Chrome Manifest: The chrome manifest file is used by XULRunner to define specific URI’s which in turn are used to locate application resources. This will become clearer when we see how the “chrome://” URI is used. Applications can be distributed compressed in a JAR file or uncompressed as folders and files. I am using the uncompressed method for now. Here is my manifest:

content myapp file:content/

Step 6 – Setup Preferences: The prefs.js files is used to tell XULRunner the name of the XUL file to use as the main window. Here is mine:

pref("toolkit.defaultChromeURI", "chrome://myapp/content/main.xul");

XULRunner preferences include:

Step 7 – Create some XUL: Finally, we need to create a simple XUL window. Nothing fancy here, just the minimum we need to make a window. No menus or anything:


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

<window id="main" title="My App" width="300" height="300"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <caption label="Hello World"/>
</window>

Step 8 – Run the App: The moment of truth. We need to get XULRunner to launch the bare-bones application. From a command prompt opened to the “c:\program files\myapp” folder, we should be able to execute this:

xulrunner.exe application.ini

Of course, xulrunner.exe must be in the PATH. Because of where I unzipped XULRunner, I could also try this if xulrunner.exe is not in the PATH:

..\xulrunner\xulrunner.exe application.ini

Success! Here is a screenshot of the bare bones application running on Win2K:

My App screenshot

My next step will be to add much more to the bare bones application. I want to explore as much of XUL as I can as fast as I can. For those that want to skip straight to the end, here is a ZIP of the My App application:

My App sample

Comments (4)

Mozilla Platform – Basic Desktop Application

After a short break, I am back to working with the Mozilla platform (XUL, JavaScript & XPCOM). I want to begin exploring the platform by building a basic desktop application using XULRunner. Given that Firefox, Thunderbird and the rest of the Mozilla suite is written using the platform, it a safe bet that it can be used to build a basic application. However, I know nearly nothing of the Mozilla platform, so I need to start somewhere.

I consider a basic desktop application to at least be able to support:

  • Main window, popup windows and dialogs (modal and non-modal)
  • Menus and toolbars (with images and themes)
  • Basic assortment of controls (edits, buttons, checkboxes, radiobuttons, lists, trees & tabs)
  • OS common dialogs (file open & save at a minimum)
  • Clipboard operations
  • Printing
  • Help system

Alright, I am off to build my basic application. I’ll update this post as I go. I wouldn’t go so far as to call it a tutorial, but I’ll link to any tutorials I find along the way.

Update:

  1. Getting Started with XULRunner
  2. UI Basics [Part 1]
  3. UI Basics [Part 2]

Comments (1)