Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Adobe AIR Developer Center / AIR Quick Starts for HTML/JavaScript developers /

Customizing the look and feel of a window

by Joe Ward

Joe Ward

Modified

10 June 2010

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
Adobe AIR

Requirements

Prerequisite knowledge

General experience building HTML-based applications is suggested. For more details on getting started with this Quick Start, refer to Building the Quick Start sample applications with HTML.

 

Additional Requirements

  • Adobe AIR SDK

User level

Intermediate

Required products

  • Adobe AIR

Sample files

  • CustomChromeHTML.zip
  • CustomChromeHTML.air

When you turn off system chrome for a window, you gain tremendous creative possibilities, but you also lose the automatic management of window size, position, and display state that the operating system provides for standard windows. The Custom Chrome example application illustrates how to take advantage of some of the creative advantages of providing your own chrome and how to replace the window management services that are no longer provided by the operating system.

In addition, the application demonstrates how to map a portion of the application to a non-application sandbox and how to set up a bridge between a parent document in the application sandbox and a child document in a non-application sandbox.

Custom chrome window
Figure 1. The Custom Chrome example application demonstrates alternatives to the default system chrome.

Note: This is a sample application provided, as is, for instructional purposes.

This sample application includes the following files:

  • html/index.html: The main application file.
  • images/: A directory containing the images used for the custom chrome
  • css/chrome.css: The application style sheet used to define the styles for the custom chrome.
  • js/WindowControl.js: Functions for controlling the window in response to user interaction with the chrome elements.
  • js/AIRAliases.js: The standard AIR alias script which defines shorter references for the AIR APIs.
  • sandbox/: The directory containing the parts of the application mapped to a non-application sandbox
  • sandbox/html/child.html: The main page of the sandboxed part of the application.
  • sandbox/js/CanvasLissajousAnimation.js: Draws a simple animation using the Canvas API.
  • sandbox/js/ContextMenu.js: Defines the code for a DHTML context menu.
  • sandbox/images/: The images used in the sandboxed portion of the application.
  • CustomChromeHTML-app.xml: The AIR application descriptor file.
  • Sample AIR icon files

Types of chrome

The Custom Chrome example uses four general types of window chrome:

  • buttons: Anchor tags styled with images as buttons to close, maximize, minimize, and restore the window.
  • move handles: Styled div tags with background images and mouse-down events as "drag bars" to allow moving the window around the desktop.
  • resize grippers: Styled div tag with a background image and the mouse-down event to allow resizing the window. The Custom Chrome example only implements resizing from the bottom-right corner, but AIR supports resizing from each edge and corner of a window.
  • background: draws an irregular background using div tags. Colored transparency is achieved by using transparent PNG graphics for the background.
  • client area: Defined by a div tag containing an iframe. The client area overlaps part of the background. The example content, which is mapped to a remote sandbox, is loaded into the iframe.

Figure 2 shows an exploded view of the Custom Chrome application, showing the individual chrome elements.

Custom chrome window
Figure 2. An exploded view of the custom chrome.

Understanding the code

To code a window in AIR that does not use system chrome, you add <systemChrome>false</systemChrome> to the <initialWindow> element of the application descriptor file. To allow the user to move, resize, or change the display state of the window, You must then add your own chrome to the window. This example demonstrates how to add your own chrome using standard HTML, CSS, and JavaScript, as well as how to use the AIR NativeWindow functions for controlling the window from your custom chrome.

Defining the application structure

The Custom Chrome application is structured in two parts. The first part defines the window chrome and contains the code that calls AIR APIs to move, resize, close, and change the display state of the window. The second part, is essentially the “client area” of the window and defines the application proper. In Custom Chrome, this application is a simple animation drawn using the Canvas API.

The first part, defined in html/index.html, loads the second part, sandbox/html/child.html, using an iFrame:

<iframe id="application" src="html/child.html" sandboxRoot="http://localhost/" documentRoot="app:/sandbox/" frameBorder="0" width="100%" height="100%" onDOMInitialize="setBridge()"> </iframe>

This two-part structure allows the main part of the application to be easily mapped to the appropriate sandbox without disturbing the operation of the chrome elements. For example, if the application displayed a map from a remote server, and the page included its own JavaScript functions to control the map, then you could change the sandboxRoot attribute to the domain of the remote server. On the other hand, if the application called AIR APIs directly, you could remove the sandboxRoot property altogether so that the content remained in the application sandbox. In neither case, does the code for the chrome have to be changed because it always runs in the application sandbox.

The example content used in Custom Chrome could run in any sandbox, including the application sandbox. For demonstration purposes, it is mapped to the remote, http://localhost/, sandbox.

When setting the sandboxRoot attribute, be careful not to forget the URL scheme. You can use the http: or https: schemes to map content to a remote sandbox, and the file: scheme to map content to the local-with-filesystem sandbox. If you leave out the scheme, however, the content remains in the application sandbox, and you may be scratching your head as to why certain JavaScript functions only allowed outside the application sandbox unexpectedly fail.

Creating the sandbox bridge

When you map content out of the application sandbox, it can no longer call AIR APIs. The Custom Chrome application needs to access AIR APIs from outside the application sandbox for two features. The first is the Source Viewer feature, triggered by a DHTML context menu; the second, useful for debugging, is the AIR trace() function. To allow content in the application sandbox to interact with content in a non-application sandbox, and vice-versa, you can set up a parent or child sandbox bridge.

Each bridge goes in a single direction. The parent bridge allows the child content to call functions and access properties in the parent, application-sandboxed document. This is the type of bridge used in Custom Chrome. The child bridge allows the parent document to call functions and access properties in the child document. In both cases, code accessing the bridge can only access the properties and methods of a single object, which is assigned to the parentSandboxBridge or childSandboxBridge property of the JavaScript Window object. Custom Chrome creates an object called Bridge and creates two member functions, viewSource() and trace():

var Bridge = {}; Bridge.viewSource = function(){ SourceViewer.getDefault().viewSource(); } Bridge.trace = function(string){ air.trace(string); }

Custom Chrome sets the parentSandboxBridge property of the child.html document in response to the dominitialize event of the iframe with setBridge() function defined in WindowControl.js:

function setBridge(){ var childApp = document.getElementById("application").contentWindow; childApp.parentSandboxBridge = Bridge; }

The bridge can be created by the parent document at anytime, but in order for the scripts in the child document to access the bridge before the load event is handled, you must use the dominitialize event.

Defining the chrome elements

Each chrome element has two parts, an HTML element, which places the element into the DOM and assigns an id, and one or more CSS styles, which specify the position and images to use for the chrome element. In addition, event listeners are added to the button and drag handles either by using the onClick attribute or by looking up the element id in JavaScript.

The CSS position:fixed style makes it easy to position the chrome elements relative to the window borders. You can use the top, bottom, left, and right properties to “glue” an edge of a chrome element a specified distance from the edge of the window. The chrome element then automatically repositions itself, resizing if necessary, when the window is resized. For example, the following styles are used for the top, right slice of the background:

.background { position:fixed; background-image:url("../images/background.png"); } #backgroundRight {left:99; right:25; top:44; height:75;}

Because both the left and right properties are set, the slice resizes horizontally. Because the top property is set to 44 and the height is set to 75, the slice always remains 44 pixels from the top of the window and 75 pixels high.

Note: AIR does not support the CSS opacity property. If you set a background color on an element, the background will be completely opaque. To simulate tinted transparency, you can use a PNG graphic of the desired color and opacity as the background image for the element.

Button chrome

The window buttons are defined in the main html file using anchor tags:

<a href="#" id="close" class="button" onClick="onClose()"></a>

The onClick event attribute attaches the button to the relevant event handler function. The anchor element is positioned and supplied with images using the corresponding CSS styles:

.button { position:fixed; } a#close { top:7px; right:40px; width:51px; height:41px; background:url("../images/buttons/close_over.png") } a#close:link {background:url("../images/buttons/close_up.png")} a#close:visited {background:url("../images/buttons/close_up.png")} a#close:hover {background:url("../images/buttons/close_over.png")} a#close:active {background:url("../images/buttons/close_down.png")}

Move handle and resize gripper chrome

The move handles and resize gripper are defined with div elements in the main html file:

<div id="topDragBar"></div> <div id="bottomGroup"> <div id="bottomDragBar"></div> <div id="resizeGripper"></div> </div>

They are positioned using CSS styles. For example, the top bar used to move the window is styled with the following selector:

#topDragBar { position:fixed; right:0; top:0; width:211; height:157; background:url(../images/handles/topHandle.png); }

A mouseDown event handler is added to each element in the initialize() function:

var topBar = document.getElementById("topDragBar"); topBar.addEventListener("mousedown",onMove,true);

Allowing cancellation of window operations

When a window uses system chrome, user interaction with the window can be canceled by listening for and canceling the default behavior of the relevant event. For example, when a user clicks the system chrome close button, the closing event is dispatched. If any registered listener calls the preventDefault() method of the event, perhaps because it contains unsaved data, then the window will not close.

When a window does not use system chrome, notification events for intended changes are not automatically dispatched before the change is made. Hence, if you call the methods for closing a window, changing the window state, or set any of the window bounds properties, the change cannot be canceled.

In AIR, most objects are capable of dispatching events, including the NativeWindow object. To notify components in your application before a window change is actually made, your application logic can dispatch the appropriate notification event using the dispatchEvent() method of the native window. For example, the following logic implements a cancelable event handler for a window close button:

function onClose(){ var closing = new air.Event(air.Event.CLOSING, true, true); window.nativeWindow.dispatchEvent(closing); if(!closing.isDefaultPrevented()){ nativeWindow.close(); } }

Note: Although the dispatchEvent() method returns false if the event preventDefault() method is called by a listener, it can also return false for other reasons. It is better to explicitly use the isDefaultPrevented() method to test whether the window change should be canceled.

Initializing the window

To initialize the window, Custom Chrome calls the initialize() function in response to the load event dispatched by the body element:

function initialize(){ var topBar = document.getElementById("topDragBar"); topBar.addEventListener("mousedown",onMove,true); var bottomBar = document.getElementById("bottomDragBar"); bottomBar.addEventListener("mousedown",onMove,true); var resizeGripper = document.getElementById("resizeGripper"); resizeGripper.addEventListener("mousedown",onResize,true); maxButton = document.getElementById("maximize"); restoreButton = document.getElementById("restore"); nativeWindow.addEventListener(air.NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, onDisplayStateChange); }

The function finds the chrome elements by id so that they can be referenced in the control code and adds event listeners. Even though the system chrome title bar and buttons are not displayed, users can still change minimize, maximize, and restore the window through the operating system by other means (such as the Alt+Space menu on Windows). Therefore, Custom Chrome listens for changes in the window display state by adding an event listener to the window using the nativeWindow property of the JavaScript Window object. This property, which AIR automatically adds to all pages running within the application sandbox, is essentially an interface to the desktop window object.

Resizing and moving a window

Calling the startResize() or startMove() methods of a window starts a system-mediated window change. The user's mouse or keyboard actions are used to change the window bounds. In this case, each incremental change is preceded by an automatically generated moving or resizing event. If any listeners cancel these events, the move or resize sequence is terminated and no further changes are made to the window.

Custom Chrome uses the following functions to start a move and a resize:

var onMove = function(event){ nativeWindow.startMove(); } var onResize = function(event){ nativeWindow.startResize(air.NativeWindowResize.BOTTOM_RIGHT); }

The parameter passed to the startResize() method determines how the resize operation proceeds and should match the location of the chrome element which triggered the resize operation. Since the resize gripper is located in the bottom, right corner of the window, the function is called using the bottomRight resize type. The constants for the permitted values for the parameter are defined by the NativeWindowResize class and correspond to each of the corners and edges of the window.

Controlling the window display state

The window display state can be controlled using the maximize(), minimize(), and restore() methods of the NativeWindow object. When you call one of these methods directly, no displayStateChanging event is dispatched, so to allow other components to prepare for the change, Custom Chrome dispatches the event itself. For example the function for maximizing the window is defined as follows:

function onMaximize(){ var maximizing = new air.NativeWindowDisplayStateEvent( air.NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, true, true, window.nativeWindow.displayState, air.NativeWindowDisplayState.MAXIMIZED); window.nativeWindow.dispatchEvent(maximizing); if(!maximizing.isDefaultPrevented()){ nativeWindow.maximize(); } }

Closing the window

Custom Chrome closes the window using the close() method of the NativeWindow object. Calling the close method directly doesn't generate a cancelable closing event automatically, so it is a good idea to dispatch the closing event before calling close(). This allows other components of the application to prepare for or even veto the close operation if, for example, there is still data to save:

function onClose(){ var closing = new air.Event(air.Event.CLOSING, true, true); window.nativeWindow.dispatchEvent(closing); if(!closing.isDefaultPrevented()){ window.close(); } }

There is overlap between the window control functions provided by the JavaScript Window object and those provided by the AIR NativeWindow object. You can, for example, close a window with either window.close() or window.nativeWindow.close(). When such overlap exists, use whichever method you find most convenient.

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement