Sencha Inc. | HTML5 Apps

Blog

Using Native APIs in Sencha Desktop Packager

June 18, 2013 | Ariya Hidayat

Using Native APIs in Sencha Desktop PackagerSencha Desktop Packager lets you to take an existing web application and deploy it as a desktop application. You can also integrate with the native platform by using additional APIs to create menus, show file dialogs, and access the file system. In this blog post, we’ll show a simple text editor to demonstrate the use of these native APIs.

If you’re new to Sencha Desktop Packager, watch the 3-minute walkthrough. If you don’t have Desktop Packager yet, download the 30-day trial edition, available for Windows, OS X, and Linux. At any time, you can always refer to the online documentation.

Basic Structure

A simple text editor is mainly comprised of a text field. This can be accomplished with the following simple index.html:

 
  <html>
  <head>
  <style>
  body { margin: 0 }
  textarea {
    height: 100%; width: 100%;
    border: none; outline: none;
    font-family: Menlo, 'Courier New', monospace;
  }
  </style>
  </head>
  <body>
  <textarea id="text">
  </textarea>
  </body></html>
 

To package it, we need a corresponding manifest file which looks like the following:

 
{
    "organizationName": "Sencha",
    "applicationName": "Text Editor",
    "versionString": "1.0",
    "outputPath": "TextEditor",
    "webAppPath": "src/",
    "settings": {
        "mainWindow": {
            "autoShow": true
        }
    }
}
 

Assuming that the manifest file is called texteditor.json and index.html is placed under src/ subdirectory, building it as a desktop application is as easy as running:

 
ionpackage texteditor.json
 

The application is created under TextEditor/ subdirectory. Launch it and you will see a window with an empty text field, just as you would expect in a text editor.

Adding Native Menu

Obviously, a text editor is not very useful if the user cannot open an existing file. The first step towards this is to build an interface which allows the user to perform some actions. We will start by adding a menu bar and a File menu. This extra logic will be implemented in a JavaScript file, ui.js, which should be placed in the same src/ subdirectory. Here, we use Ion.ui.MenuBar (of the main window) to construct the menu bar and populate it.

 
function createUI() {
  var fileMenu = Ion.ui.mainWindow.menuBar.addMenu('&File');
  fileMenu.addMenuItem('Open', function(){}, 'Ctrl+O');
  fileMenu.addSeparator();
  fileMenu.addMenuItem('Save', function(){}, 'Ctrl+S');
}
 

This particular function, createUI, needs to be invoked from the main index.html. For this example, it is enough to call that from the document’s onLoad handler. Of course, do not forget to add a new script tag to include ui.js.

If you now repackage the application by running ionpackage texteditor.json again, the main window will have a menu bar. Clicking on the File menu will show its items, each with its corresponding shortcut as we specified in our createUI() function. Pretty straightforward, isn’t it?

Using Native APIs with Sencha Desktop Packager

Using File Dialogs

Unfortunately, the new menu items are still useless since they don’t perform any meaningful action. This can be changed by having a real handler for both menu items. We need to tweak our JavaScript logic to look like this:

 
var filename;
 
function createUI() {
  var fileMenu = Ion.ui.mainWindow.menuBar.addMenu('&File');
  fileMenu.addMenuItem('Open', handleOpen, 'Ctrl+O');
  fileMenu.addSeparator();
  fileMenu.addMenuItem('Save', handleSave, 'Ctrl+S');
}
 

Instead of an empty function, now pass handleOpen and handleSave for the Open and Save menu items, respectively. As the first step, we can invoke the native file dialog whenever the user wants to open a file. This is implemented via Ion.ui.browseFiles as follows (the same can be done for the Save menu item, it is left as an exercise for the reader).

 
function handleOpen() {
   Ion.io.browseFiles({
     caption: 'Load Text File',
     path: filename,
     filters: [['Text Files', '*.txt']],
     type: 'open'
   });
}
 

When the Open menu item is clicked, a file dialog pops up to allow the user to choose a file, as illustrated in the following screenshot.

Using Native APIs with Sencha Desktop Packager

Accessing Files

A file dialog in and of itself does not do much. While the application now knows which file the user selected, it still needs to do something with it. Thanks to the Desktop Packager file system API, we can add some more logic to read the file contents. For this particular case, we use Ion.io.readFile.

 
function handleOpen() {
  var result, content;
 
  result = Ion.io.browseFiles({
    caption: 'Load Text File',
    path: filename,
    filters: [['Text Files', '*.txt']],
    type: 'open'
  });
 
  if (result.success) {
    content = Ion.io.readFile(result.value);
    if (content.success) {
      document.getElementById('text').value = content.data;
      filename = result.value;
    }
  }
}
 

With the above new implementation of handleOpen, our little text editor finally has a fully functional user interface to load the contents from a text file selected by the user via the open file dialog.

Last but not least, if you need to troubleshoot your packaged app, take advantage of the Desktop Packager remote debugging feature. Having a console in the debugger allows you to analyze the application logic as well as play with the native APIs.

Happy packaging!

Add your comment:

Comments are Gravatar enabled. Your email address will not be shown.

Commenting is not available in this channel entry.