Apollo Alpha 1 Documentation - collected by Jimbob | Back to MY RESOURCES


Working with windows

Back to: Apollo Documentation home page

You use the classes provided by the Apollo windowing API to create and manipulate windows. To begin, refer to Apollo window basics and then to the following topics, which explain the common windowing tasks:

If you're developing Apollo applications using Flex, you can refer to the following topics:

The Apollo windowing API contains the following classes:

In addition, window string constants are defined in the following classes in the flash.display package:


Contents
  1. Apollo window basics
    1. Window chrome
    2. Limitations in the Alpha Release
  2. Creating windows
    1. Creating a new NativeWindow
    2. Creating a new HTML window
    3. Adding content to a window
      1. Loading a SWF or image:
      2. Loading HTML content:
    4. Example: Creating windows with MXML and ActionScript
  3. Creating transparent windows
    1. Transparency in an MXML application window
  4. Manipulating windows
    1. Getting a NativeWindow instance
    2. Maximizing a window
    3. Minimizing a window
    4. Restoring a window
    5. Closing a window
    6. Allowing cancellation of window operations
    7. Example: Minimizing, maximizing, restoring and closing a window
    8. Example: Resizing and moving windows
  5. Listening for window events
  6. Using full-screen window mode

Apollo window basics

Apollo provides an easy-to-use, cross-platform window API for creating native operating system windows using Flash, Flex, and HTML programming techniques.

With Apollo, you have a wide latitude in developing the look-and-feel of your application. The windows you create can look like a standard desktop application, matching Apple style when run on the Mac, and conforming to Microsoft conventions when run on Windows. Or you can use the skinnable, extendible chrome provided by the Flex framework to establish your own style no matter where your application is run. You can even draw your own windows with vector and bitmap artwork with full support for transparency and alpha blending against the desktop. Tired of rectangular windows? Draw a round one.

There are two types of windows that you can use in an Apollo application. Windows created with the NativeWindow class use the Flash stage and display list. To add a visual object to the window, you add the object to the display list of the window’s stage. Windows created with JavaScript use HTML, CSS, and JavaScript to display content. To add a visual object to the window, you insert that content into the DOM (or use any other common browser-related technique).

The first window of your application is automatically created for you by Apollo based on the parameters specified in the rootContent element of the application descriptor file. The type of window Apollo creates is based on the main content file referenced in the rootContent element. If the root content is a SWF file, a NativeWindow is created and the SWF is loaded into the window. If the root content is an HTML file, an HTML window is created and the HTML is loaded.

Apollo windows use an event-based programming model. Changing any properties or calling methods that may affect the display or behavior of application components dispatches notification events that interested components can listen for. For example, when the system chrome maximize button is clicked by a user the following sequence of events occurs:

  1. The user clicks the maximize button.
  2. A displayStateChanging event is dispatched by the window
  3. If no registered listeners cancel the event, the window is maximized
  4. A displayStateChange event is dispatched by the window to notify listeners that the change has been made.
    In addition, events for related changes are dispatched:
  5. A move event is dispatched if the top, left corner of the window moved because of the maximize operation.
  6. A resize event is dispatched if the window size changed because of the maximize operation

A similar sequence of events is dispatched for minimizing, restoring, closing, moving, and resizing a window.

For detailed information about the window API classes, methods, properties, and events, see the Apollo ActionScript 3.0 Language Reference.

Note: An Apollo application can use the window-like Flex components TitleWindow and Alert. However, these objects are not related to the Apollo NativeWindow class. None of the window concepts, programming techniques or API descriptions presented here apply.

Window chrome

Window chrome is the set of controls that allow users to manipulate a window in the desktop environment. For an Apollo application, you have the following three choices for window chrome:

Limitations in the Alpha Release

The following window-related features are not supported in this Alpha release:

Creating windows

Apollo provides three primary means for creating applications windows:

Note: you can create new NativeWindows from JavaScript code (through the Apollo-added window.runtime property), and new HTML windows from ActionScript (through the HTMLControl).

Creating a new NativeWindow

To create a new NativeWindow, create a NativeWindowInitOptions object and pass it to the NativeWindow constructor.

ActionScript example:

var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.systemChrome = NativeWindowSystemChrome.STANDARD;
options.transparent = false;

var newWin:NativeWindow = new NativeWindow(false, options);

JavaScript example:

var options = new runtime.flash.display.NativeWindowInitOptions();
options.systemChrome = runtime.flash.display.NativeWindowSystemChrome.STANDARD;
options.transparent = false;

var newWin = new runtime.flash.display.NativeWindow(false, options);

The first parameter of the NativeWindow constructor specifies whether the window should be visible as soon as it is created. To avoid displaying the intermediate states of the window as you set its bounds, position, and contents, set this parameter to false. When you have finished initializing the window, set the NativeWindow.visible property to true. The second parameter is a NativeWindowInitOptions object. This object sets those properties of a window that cannot be changed after the window has been created.

Note: Setting systemChrome="standard" and transparent="true" is not a supported combination in this Apollo Alpha release.

Once the window is created, you may initialize its properties and load content into the window using the stage property and Flash display list techniques.

Creating a new HTML window

To create a new HTML window use the JavaScript Window.open() method. A window with system chrome will be created to display the content at the specified URL.

JavaScript example:

  newWindow = window.open("InvokeEvent.html", "logWindow", "height=600,width=400,top=10,left=10");

Note: the window created does not automatically have the Apollo window.runtime property exposed. To create this property in the new window, create a new runtime property on the window object and assign it the value of the opening window's runtime property:

  window.runtime = window.opener.runtime;

Adding content to a window

To add content to a window, add display objects to the window stage. You can create display objects dynamically or load existing content with the flash.display.Loader class.

Loading a SWF or image:

You can load Flash or images into the display list of a NativeWindow using the flash.display.Loader class.

//newWindow is a NativeWindow instance
var loader:Loader = new Loader();
var loaderContext:LoaderContext = new LoaderContext(false, new ApplicationDomain());

//set the stage so display objects are added to the top-left and not scaled				
newWindow.stage.align = "TL";
newWindow.stage.scaleMode = "noScale";
newWindow.stage.addChild( loader );

//urlString is the URL of the content to load
loader.load( new URLRequest(urlString) );

Note: set loaderContext.applicationDomain = new ApplicationDomain(); when loading this into a new window.

You cannot load visual objects for display on an HTML window in this manner (just use IMG tags for images), but you can load a SWF file that contains library code for use in an HTML-based application.

Older SWF files created using ActionScript 1 or 2 will share global state such as class definitions, singletons, and global variables if they are loaded into the same window. If such a SWF relies on untouched global state to work correctly, it cannot be loaded more than once into the same window, or loaded into the same window as another SWF using overlapping class definitions and variables. This content can be loaded into separate windows.

Loading HTML content:

To load HTML content into a NativeWindow, you must add an HTMLControl to the window stage and load the HTML content into the HTMLControl.

//newWindow is a NativeWindow instance
var htmlView:HTMLControl = new HTMLControl();
html.width = newWindow.width;
html.height = newWindow.height;

//set the stage so display objects are added to the top-left and not scaled
newWindow.stage.align = "TL";
newWindow.stage.scaleMode = "noScale";
newWindow.stage.addChild( htmlView );

//set exposeRuntime=true to allow JavaScript on the page to reference ActionScript classes
htmlView.exposeRuntime = true;

//urlString is the URL of the HTML page to load
htmlView.load( new URLRequest(urlString) );

To load an HTML page into an HTML window, use a JavaScript method such as window.open.

To load an HTML page into a Flex application, you can use the Flex HTMLComponent.

See Adding HTML content to SWF-based applications

Example: Creating windows with MXML and ActionScript

The following example illustrates how to create new windows. The example uses MXML to provide a user interface for setting properties for the new windows. The window creation code is ActionScript within the mx:Script block of the MXML file. Simple Sprite objects are created as the content of the new windows.

<?xml version="1.0" encoding="utf-8"?>
<mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" applicationComplete="init();">
    <mx:Script>
        <![CDATA[
        //initialize this window			
        public function init():void {
            var launchWindow:NativeWindow = this.stage.window; 
            launchWindow.x = 400;
            launchWindow.y = 400;
            launchWindow.width = 350;
            launchWindow.height = 310;
        }
			
        //create a new window
        public function createNewWindow():void {
            //create the options
            var options:NativeWindowInitOptions =
                 new NativeWindowInitOptions();
            options.transparent = transparentOption.selected;
            options.systemChrome = Chrome.selectedValue.toString();
            if(standardChrome.selected){
                //not a supported combination in M3
                options.transparent = false; 
            }
				
            //create the window
            var newWindow:NativeWindow = new NativeWindow(false,options);
            newWindow.visible = false;
            newWindow.title = titleString.text;
            newWindow.x = Number(xPosition.text);
            newWindow.y = Number(yPosition.text);
            newWindow.width = Number(widthValue.text);
            newWindow.height = Number(heightValue.text);
				
            //add a sprite to the window
            newWindow.stage.align = "TL";
            newWindow.stage.scaleMode = "noScale";
            var client:Sprite = new Sprite();
            with(client.graphics){
                beginFill(0x234578,.7);
                    drawRect(0,0,newWindow.width,newWindow.height);
                endFill();
                beginFill(0x558721,.7);
                    drawCircle(100,100,75);
                    drawCircle(175,100,75);
                    drawCircle(133,175,75);
                endFill();
            }
            newWindow.stage.addChild(client);

            //add double-click handler to close the window
            client.doubleClickEnabled = true;
            client.addEventListener(MouseEvent.DOUBLE_CLICK,
                        function(e:MouseEvent):void{e.target.stage.window.close();});
	
            //show the window
            newWindow.visible = true;
        }	
        ]]>
    </mx:Script>
	
    <mx:Label text="Title" x="32" y="10"/>
    <mx:TextInput id="titleString" text="Title" editable="true" x="83" y="10" width="210"/>

    <mx:Label text="x" x="42" y="40"/>
    <mx:TextInput width="58" id="xPosition" text="10" x="83" y="40"/>

    <mx:Label text="y" x="42" y="70"/>
    <mx:TextInput width="58" id="yPosition" text="10" x="83" y="70"/>

    <mx:Label text="width" x="180" y="40"/>
    <mx:TextInput width="58" id="widthValue" text="400" x="235" y="40"/>

    <mx:Label text="height" x="173" y="66"/>
    <mx:TextInput width="58" id="heightValue" text="350" editable="true" x="235" y="66"/>

    <mx:CheckBox id="transparentOption" label="Transparent" width="114" 
                 selected="false" enabled="true" x="119" y="188"/>

    <mx:Label x="117" y="104" text="System Chrome:" width="127"/>
    <mx:VBox height="50" width="125" x="119" y="130">
        <mx:RadioButtonGroup id="Chrome"/>
        <mx:RadioButton label="standard chrome"  value="standard" 
                        groupName="Chrome" id="standardChrome" 
                        selected="true" enabled="true"/>
        <mx:RadioButton label="no chrome" value="none" groupName="Chrome" id="noChrome"/>
    </mx:VBox>

    <mx:Button label="Create Window" id="createWindowButton" x="119" y="221"
        click="createNewWindow();"/>
	
</mx:ApolloApplication>

Creating transparent windows

Note: In this Alpha release of Apollo, transparency is not supported for the initial window created for HTML-based applications, nor for windows created using the JavaScript window.open() method.

To allow alpha blending of a window with the desktop or other windows, set the window's transparent property to true. The transparent property must be set before the window is created and cannot be changed. The transparent property is set in the NativeWindowInitOptions object used to create a window. (For the initial window created for your application, the initialization options are taken from attributes of the rootContent element in the application descriptor file.)

A transparent window has no default background. Any window area not occupied by a display object will be invisible. If a display object has an alpha setting of less than one, then any thing below the object will show through, including other display objects in the same window, other windows, and the desktop. Rendering large alpha-blended areas can be slow, so the effect should be used conservatively.

Transparent windows are useful when you want to create:

Transparency in an MXML application window

If your Flex application uses CSS style properties that set a background image or color, your window will not be transparent. Likewise, if the Application tag in your MXML file defines a background color, this setting will override a transparent window mode. To ensure the transparency of your application window, include the following code in your style sheet or in the <mx:Style> element that is contained in your application MXML file:

Application
{
    background-image:"";
    background-color:"";
}

These declarations suppress the appearance of background color and image in the application window.

Manipulating windows

This section highlights using the properties and methods of the NativeWindow class to manipulate the appearance and behavior of application windows.

Getting a NativeWindow instance

To manipulate a window, you must first get the window instance. You can get a window instance from one of the following places:

Note: In the Apollo Alpha release, there is no sure way to get the instance of the application window automatically created for an HTML-based application. To change the appearance of an HTML window, use the JavaScript Window properties and methods.

Because the Flex Application and ApolloApplication objects are display objects, you can easily reference the application window in an MXML file as follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init();">
    <mx:Script>
      <![CDATA[
          import flash.display.NativeWindow;

          public function init():void{
              var appWindow:NativeWindow = this.stage.window;
              //set window properties
              appWindow.visible = true;
          }
      ]]>
    </mx:Script>
</ApolloApplication

Note: Until the ApolloApplication component is added to the window stage by the Flex framework, the component's stage property will be null. This behavior is consistent with that of the Flex Application component, but does mean that it is not possible to access the stage or the NativeWindow instance in listeners for events that occur earlier in the initialization cycle of the ApolloApplication component, such as creationComplete.

Maximizing a window

To maximize the window, use the NativeWindow.maximize() method.

myWindow.maximize();

Minimizing a window

To minimize the window, use the NativeWindow.minimize() method.

myWindow.minimize();

Restoring a window

Restoring a window returns it to the size that it was before it was either minimized or maximized.

To restore the window, use the NativeWindow.restore() method.

myWindow.restore();

Closing a window

To close a window, use the NativeWindow.close method.

Closing a window unloads the contents of the window, but if other objects have references to this content, the content objects will not be destroyed. The NativeWindow.close() method executes asynchronously, the application that is contained in the window continues to run during the closing process. The close method dispatches a close event when the close operation is complete. The NativeWindow object is still valid, but accessing most properties and methods on a closed window will generate an IllegalOperationError. You can check the closed property of a window to test whether a window has been closed.

If the shell.autoExit property is true, which is the default, then the application exits when its last window closes.

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 appropriate events. 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, 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. To notify components in your application before a window change is actually made, your application logic can dispatch the relevant notification event using the dispatchEvent() method of the window. For example, the following logic implements a cancelable event handler for a window close button:

public function onCloseCommand(event:MouseEvent):void{
    var closingEvent:Event = new Event(Event.CLOSING,true,true);
    dispatchEvent(closing);
    if(!closingEvent.isDefaultPrevented()){
        win.close();
    }
}

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

Example: Minimizing, maximizing, restoring and closing a window

The following short MXML application demonstrates the Window maximize(), minimize(), restore(), and close() methods.

<?xml version="1.0" encoding="utf-8"?>

<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical"
    xmlns:ns1="http://www.adobe.com/2006/apollo">
    
   
    <mx:Script>
    <![CDATA[
    public function minimizeWindow():void
    {
    	this.stage.window.minimize();
    }

    public function maximizeWindow():void
    {
        this.stage.window.maximize();
    }          
    
    public function restoreWindow():void
    {
        this.stage.window.restore();
    }          

    public function closeWindow():void
    {
        this.stage.window.close();
    }

    ]]>
    </mx:Script>

	<mx:VBox>
           <mx:Button label="Minimize" click="minimizeWindow()"/>
           <mx:Button label="Restore" click="restoreWindow()"/>
           <mx:Button label="Maximize" click="maximizeWindow()"/>
           <mx:Button label="Close" click="closeWindow()"/>
        </mx:VBox>

</mx:Application>

Example: Resizing and moving windows

An Apollo application can initiate a system-controlled operation to resize or move its containing window. The process that is used to complete the operation depends on whether the call to the method that completes the operation is made from within a mouseDown event.

Note: To resize or move a window, you must first obtain a reference to the NativeWindow instance. For information about how to obtain a window reference, see Getting a NativeWindow instance.

To resize a window, use the NativeWindow.startResize() method. This method triggers a system-controlled resizing of the window. When this method is called from a mouseDown event, the resizing process is mouse-driven and completes when the operating system receives a mouseUp event. A call to the NativeWindow.startResize() method that is not made from a mouseDown event triggers a system-controlled resizing operation that may be mouse-driven or keyboard-driven but remains consistent with the default resizing sequence for the operating system.

To move a window without resizing it, use the NativeWindow.startMove() method. Like the startResize() method, when the startMove() method is called from a mouseDown event, the move process is mouse-driven and completes when the operating system receives a mouseUp event. A call to the NativeWindow.startMove() method that is not made from a mouseDown event triggers a system-controlled move that may be mouse-driven or keyboard-driven but remains consistent with the default move sequence for the operating system.

For more information about the startResize and startMove methods, see the Apollo ActionScript 3.0 Language Reference.

The following example shows how to initiate resizing and moving operations on a window:

package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.display.NativeWindowResize;

    public class NativeWindowResizeExample extends Sprite
    {
        public function NativeWindowResizeExample():void
        {
            // Fills a background area.
            this.graphics.beginFill(0xFFFFFF);
            this.graphics.drawRect(0, 0, 400, 300);
            this.graphics.endFill();
            
            // Creates a square area where a mouse down will trigger a resize.
            var resizeHandle:Sprite = createSprite(0xCCCCCC, 20, this.width - 20, this.height - 20);
            resizeHandle.addEventListener(MouseEvent.MOUSE_DOWN, onStartResize);
            
            // Creates a square area where a mouse down will trigger a move.
            var moveHandle:Sprite = createSprite(0xCCCCCC, 20, this.width - 20, 0);
            moveHandle.addEventListener(MouseEvent.MOUSE_DOWN, onStartMove);
        }
        
        public function createSprite(color:int, size:int, x:int, y:int):Sprite
        {
            var s:Sprite = new Sprite();
            s.graphics.beginFill(color);
            s.graphics.drawRect(0, 0, size, size);
            s.graphics.endFill();
            s.x = x;
            s.y = y;
            this.addChild(s);    
            return s;        
        }
    
        public function onStartResize(event:MouseEvent):void
        {
                this.stage.window.startResize(NativeWindowResize.BOTTOM_RIGHT);
        }

        public function onStartMove(event:MouseEvent):void
        {
                this.stage.window.startMove();
        }
    }
}

Listening for window events

To listen for the events dispatched by a window, register a listener with the window instance. For example, to listen for the closing event, register a listener with the window as follows:

myWindow.addEventListener(flash.Events.CLOSING, onClosingEvent);

When an event is dispatched, the target property references the window sending the event.

Most window events have two related messages. The first message signals that a window change is imminent (and can be canceled), while the second message signals that the change has occurred. For example, when a user clicks the close button of a window, the closing event message is dispatched. If no listeners cancel the event, the window closes and the close event is dispatched to any listeners.

Events in the flash.events package:

NativeWindowBoundsEvent:

Use the beforeBounds and afterBounds properties to determine the window bounds before and after the impending or completed change.

NativeWindowDisplayStateEvent:

Use the beforeDisplayState and afterDisplayState properties to determine the window display state before and after the impending or completed change.

NativeWindowErrorEvent:

Dispatched when a window operation has attempted to set the window position or size to an invalid value.

Using full-screen window mode

For the Alpha 1 release of Apollo, setting the displayState property of the Stage to StageDisplayState.FULL_SCREEN puts the window in full-screen mode, and keyboard input is permitted in this mode. (In SWF content running in a browser, keyboard input is not permitted). To exit full-screen mode, the user presses the Escape key.

For example, the following Flex code defines a simple Apollo application that sets up a simple full-screen terminal:

 <?xml version="1.0" encoding="utf-8"?>
 <mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" 
     layout="vertical" 
     applicationComplete="init()" backgroundColor="0x003030" focusRect="false">
     <mx:Script>
         <![CDATA[
             private function init():void 
             {
                 stage.displayState = StageDisplayState.FULL_SCREEN;
                 focusManager.setFocus(terminal);
                 terminal.text = "Welcome to the dumb terminal app. Press the ESC key to exit..\n";
                 terminal.selectionBeginIndex = terminal.text.length;
                 terminal.selectionEndIndex = terminal.text.length;
             }
         ]]>
     </mx:Script>
     <mx:TextArea 
         id="terminal" 
         height="100%" width="100%" 
         scroll="false"
         backgroundColor="0x003030" 
         color="0xCCFF00" 
         fontFamily="Lucida Console" 
         fontSize="44"/>
 </mx:ApolloApplication>



Back to: Apollo Documentation home page


collected by Jimbob 2007.05