Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
NW.js Essentials

You're reading from  NW.js Essentials

Product type Book
Published in May 2015
Publisher
ISBN-13 9781785280863
Pages 192 pages
Edition 1st Edition
Languages

Table of Contents (17) Chapters

NW.js Essentials
Credits
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
1. Meet NW.js 2. NW.js Native UI APIs 3. Leveraging the Power of Node.js 4. Data Persistence Solutions and Other Browser Web APIs 5. Let's Put It All Together 6. Packaging Your Application for Distribution 7. Automated Packaging Tools 8. Let's Debug Your Application 9. Taking Your Application to the Next Level Index

Chapter 2. NW.js Native UI APIs

As we have seen in the first chapter, it is incredibly easy to build desktop applications out of a simple HTML page but, in order to really understand the power of NW.js, we have to push it a step further. We know that Node.js takes care of dealing with low-level system functionality while WebKit handles the window GUI and all the stuff you'd usually do in a web application, but there is still something missing.

In order to create a decent user experience, we need to give our users the feeling that they are dealing with a native desktop application with the ability to handle multiple windows, access the clipboard, or hide in the system tray. To sum up, our application needs to be fully integrated with the OS GUI.

This cannot be done by WebKit because of the API boundaries, nor can it be done by Node.js as it doesn't have access to the GUI, but fortunately, NW.js gives us the full thing, adding on top of the others a new layer of JavaScript APIs that can interact...

The App API – the core of your applications


Eventually, we can dive deep into the actual code behind NW.js applications. The app API provides a useful set of functionalities, which you can leverage to access main information and events of your application. We shall start describing, one by one, all the functionalities provided.

Opening a file in your application natively

There are many ways to open files in an NW.js application; in this section, we're going to deal with the opening of binded file types. Let's say you're developing a text editor; you'd probably want .txt files to be associated with it.

Actually, the real binding is made on the packaging step described in Chapter 6, Packaging Your Application for Distribution, but to open a file using the OS functionality (for example, through the Open with contextual menu), we need to first be able to read the arguments passed when the application gets started.

As a matter of fact, when you choose to open a given file with an application, here...

The Window API – working with windows on NW.js


On NW.js, the Window API is nothing more than a wrapper of the DOM's window object giving an additional layer of functionality to play with the application windows. Many of the window methods described are inherited by the DOM window object. As we stated earlier, window is also an instance of Node.js EventEmitter giving you the ability to listen and respond to window events such as move or resize.

Instantiating a new window object

There are many ways to instantiate a window object. When you need to refer to the current window, all you have to do is to call the Window.get([window_object]) method leaving the attribute empty, as follows:

var gui = require('nw.gui');
var currentWindow = gui.Window.get();

In order to instantiate a different window object, you can proceed with passing the DOM window object to it through the get method:

var gui = require('nw.gui');
var extraWindow = gui.Window.get(
  window.open('window.html');
);

Otherwise, use the Window...

The Screen API – screen geometry functions


The Screen API has been lately added in order to better handle window sizing and positioning on single or multiple screens. Run the following code:

var gui = require('nw.gui');
gui.Screen.Init(); // Screen API is a Singleton
var screens = gui.Screen.screens;

You'll get an array of screen objects. Each screen object has the following structure:

screen {
  // unique id for a screen
  id : 69673536,

  // physical screen resolution
  bounds : {
    x : 0,
    y : 0,
    width : 1280,
    height : 800
  },

  // useable area within the screen bound
  work_area : {
    x : 0,
    y : 23,
    width : 1280,
    height : 773
  },
  scaleFactor : 1,
  isBuiltIn : false
}

You can easily access any of these properties in order to improve the user experience. Let's say, for example, that you want to position your window in the top-right corner of the screen. On Microsoft Windows, you would probably proceed as follows:

var gui = require('nw.gui'),
  currentWindow...

The Menu API – handling window and context menus


In NW.js, menus can be used in three different contexts:

  • Contextual menus: This is displayed when right-clicking an element inside the application.

  • Window menus: On Microsoft Windows and Linux, you can have one per window; however, in Mac OS X, you can have one, which will be shown on the System taskbar, per application.

  • Tray icon menus: This is displayed when clicking on a tray icon usually on the right side of the OS taskbar.

In this chapter, we're going to deal with the first two contexts. For tray icon menus, the same basic rules apply, but refer to the Tray API section to learn more about it.

The contextual menu

In order to instance a new menu on NW.js, we should proceed as follows:

var gui = require('nw.gui');
var menu = new gui.Menu();

Once the menu has been created, we have to append one or more MenuItem objects to it:

menu.append(new gui.MenuItem({
  label: 'Menu Item'
}));

We have three different types of menu items: normal (default value...

File dialogs – opening and saving files


Before talking about file dialogs, I have to do a little introduction. It is probably obvious, but while in the browser, file dialogs allow you to upload or download files, in NW.js, they do nothing but pass the path of the selected folder or files. So, any following operation will be done on the original file, not on a copy.

WebKit enables you to open file dialogs through the file input field but with many limitations due to security concerns. In NW.js, those limitations have been removed, and the default file input fields have been enhanced in order to give a full native user experience.

A faster way to open a file dialog is to add an event listener to the file input field as follows:

<input id="fileDialog" type="file">
<script>
document.querySelector('#fileDialog')
  .addEventListener("change", function() {
    var filePath = this.value;
    alert(filePath);
  });
</script>

In the preceding example, a default file input field will...

Opening files through file dragging


Many native desktop applications provide an alternative way to open files by just dragging them over the application. In order to implement this functionality, we can take advantage of HTML5 APIs. As this is actually beyond the purpose of the book but still very useful, I will report an example to simplify the task:

<div id="dropFileHere">Drop File Here</div>

<style>
#dropFileHere { display: block;background: #f00; }
#dropFileHere.hover { background: #0f0; }
</style>

<script>
  // Prevent default drop file behaviors
  window.ondragover = function(e) { e.preventDefault(); };
  window.ondrop = function(e) { e.preventDefault(); };

  var holder = document.getElementById('dropFileHere');
  holder.ondragenter = function() { this.className = 'hover'; };
  holder.ondragleave = function() { this.className = ''; };
  holder.ondrop = function(e) {
    e.preventDefault();
    this.className = '';
    for (var i = 0; i < e.dataTransfer...

The Tray API – hide your application in plain sight


The system tray is a small area of the screen, usually placed on the right-hand side of the system taskbar, which contains a set of icons belonging to long-running applications or services that don't fit into the taskbar, which, otherwise, will be overcrowded.

In order to associate one or more tray icons to your application, you'll have to instance a Tray object as follows:

var gui = require('nw.gui');
var tray = new gui.Tray({
  icon: 'icon.png'
});

On Microsoft Windows and Linux, once you have an instance of the tray, you can add a tooltip assigning the Tray.tooltip property, change the icon at runtime using Tray.icon, or assign a menu to Tray.menu.

Tip

The NW.js Tray API doesn't work on all Linux distributions as, at the moment, it is still using GTKStatusIcon instead of the newer AppIndicator. However, there's an open issue on GitHub, so this might change in future releases.

In order to show the menu, you'll have to right-click on the icon...

The Clipboard API – accessing the system clipboard


NW.js' Clipboard API lets you read and write plain text from the system clipboard. There are three main methods to access the content of the clipboard. Clipboard.set(data) enables you to copy some text data into the clipboard, the Clipboard.get() method allows you to retrieve that data, and Clipboard.clear() allows you to clear it up. The following is a simple example:

var gui = require('nw.gui'),
  clipboard = gui.Clipboard.get();
// Copy
clipboard.set('I love NW.js :)');
// Paste
var data = clipboard.get('text');
// Clear
clipboard.clear();

Note

The NW.js Clipboard API is still pretty young. At the moment, you can only access plain text and only from the system clipboard. The selection clipboard in X11 is not supported.

Tip

In order to do cut, copy, and paste, you can rely on document.execCommand('cut'), document.execCommand('copy') and document.execCommand('paste').

The Shell API – platform-dependent desktop functions


The Shell API is made of a set of methods that allow you to leverage platform-related tasks:

  • Shell.openExternal(String URI) : This will open any given URI (http://, mailto:, and so on) with the default system application if one has been associated; otherwise, nothing will happen.

  • Shell.openItem(String file_path): This will open any given file with the default system application if one has been associated; otherwise, the Open with dialog will be shown.

  • Shell.showItemInFolder(String path): This will open the given path inside the system file explorer/finder.

Here's a simple example to open Google.com on your default browser:

var gui = require('nw.gui');
gui.Shell.openExternal('http://www.google.com');

Summary


In this chapter, I did my best to introduce you to the use of NW.js Native UI APIs. We played with windows, menus, tray icons, and many more OS-related functions. I often used a cookbook style because I firmly believe that the best way to learn is by example, the way we learned when we were little kids. Unfortunately, I could not dwell on all the APIs, but I tried to deal with those that I consider most important for the purposes of the book.

Now that you have a decent understanding of how to interact with your application GUI, we can move to the next topic—Node.js. You're probably already experts in the field but, in the context of NW.js programming, Node.js must be approached in a slightly different way than usual. You will learn how to target and deal with path processing on multiple platforms, use modules, and pass objects between WebKit and Node.js. Let's not waste any more time and move on to Chapter 3, Leveraging the Power of Node.js.

lock icon The rest of the chapter is locked
You have been reading a chapter from
NW.js Essentials
Published in: May 2015 Publisher: ISBN-13: 9781785280863
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime}