| Subcribe via RSS

NativeWindow – using AIR windows with Actionscript (part 3 of 3)

August 10th, 2008 Posted in AIR, Actionscript 3.0, Tutorials

In the first part of this post I covered each public property exposed by an instance of NativeWindow, before continuing to look at each public method in part two. In this final part of the series I’ll go through each of the different events dispatched by a NativeWindow during its lifetime.

Event.ACTIVATE

This event is sent out when the window is activated. The event doesn’t go through a capture phase, and it won’t bubble up the Display List. Some examples of when your window may dispatch this event include:

  • When the NativeWindow is first created and activated
  • When your application contains multiple NativeWindows and the user clicks on a window which previously was not the active window, giving it focus and bringing it to the front, the window will dispatch Event.ACTIVATE
  • When you switch to another running application elsewhere on the system (an AIR application, or otherwise) and then switch back to this window, the event will be dispatched

Event.DEACTIVATE

Similarly, this event is sent out when the window is deactivated. Again, the event doesn’t go through a capture phase, and it won’t bubble up the Display List. Some examples of when your window may dispatch this event include:

  • When your application contains multiple NativeWindows and the user clicks on a window which previously was not the active window, giving it focus and bringing it to the front, the window which previously was active and had the focus will dispatch Event.DEACTIVATE
  • When you switch to another running application elsewhere on the system (an AIR application, or otherwise), the previously active window will dispatch this event

Event.CLOSING
Event.CLOSE

I have grouped these two events as they are rather obviously connected. If the user clicks the exit button in the system chrome, for example, the sequence of events will be:

  • An Event.CLOSING event is dispatched.
  • If this event is not cancelled (by calling the event’s preventDefault method) then the window will be closed, using NativeWindow.close () which was discussed in the previous part of this post
  • Once the window has been closed, an Event.CLOSE event will be dispatched

As mentioned in the previous part of this series, if you want to implement your own “close” functionality, perhaps by creating your own application chrome, you should follow this same logic to give other objects elsewhere in your application a chance to cancel the closing operation if necessary.

NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING
NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE

Again, these events are related in a similar way to Event.CLOSING and Event.CLOSE. The events are dispatched as part of one of the following operations:

  • Maximizing a window which was previously un-maximized
  • Minimizing a window which was previously un-minimized
  • Restoring a window from a maximized or minimized state

Unlike Event.CLOSING / Event.CLOSE, these events are defined within a subclass of Event, suggesting that there may be some added goodies within the event object that we can examine. As expected, there are a couple of properties available to tell us a little more about what is happening – to be more precise, the event object will tell us the value of the current state, and the value of the state we are moving to.

This is information is available by examining the NativeWindowDisplayStateEvent.beforeDisplayState and NativeWindowDisplayStateEvent.afterDisplayState properties. Both properties will be a string, matching one of the constants defined in the NativeWindowDisplayState class. These are:

  • NativeWindowDisplayState.MAXIMIZED
  • NativeWindowDisplayState.MINIMIZED
  • NativeWindowDisplayState.NORMAL

So, for example, when a user clicks the maximize button in the system chrome, the sequence of events will be:

  • A NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING event is dispatched.
  • If this event is not cancelled (by calling the event’s preventDefault method) then the state change will continue
  • Once the display state has updated, a NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE event will be dispatched

NativeWindowBoundsEvent.MOVING
NativeWindowBoundsEvent.MOVE

These events are dispatched whenever the position of the window within the system desktop is moved. This could be for one of a number of reasons:

  • A system-controlled move operation, for example the user dragging the window around with the system chrome
  • If the window is maximized
  • If the window is minimized
  • If the window is restored from maximized, or minimized state
  • If the window is moved programmatically, by setting the x, y, or bounds properties

Again, the events here are defined in a custom subclass of Event, and this time the hidden treasures available to use are the beforeBounds and afterBounds properties, which obviously tell the us the “old” and “new” positions (and sizes, if we’re interested) of the window.

The sequence of events which would happen as part of a move operation would be:

  • A NativeWindowBoundsEvent.MOVING event is dispatched.
  • If this event is not cancelled (by calling the event’s preventDefault method) then the move operation will continue
  • Once the window has been moved, a NativeWindowBoundsEvent.MOVE event will be dispatched

It’s worth noting that when a window is being dragged around by the user, it will repeatedly go through this cycle, moving the window in small steps. If at any stage, one of the NativeWindowBoundsEvent.MOVING events is cancelled, the move operation will terminate. This includes moves triggered by the NativeWindow.startMove () method discussed in the previous part of the post.

NativeWindowBoundsEvent.RESIZING
NativeWindowBoundsEvent.RESIZE

The events listed here work similarly to those dispatched as part of the move operation, although this time they apply to resize operations. Resize operations may occur for one of a number of reasons:

  • A system-controlled resize operation, for example the user resizing the window via the system resize handles
  • If the window is maximized
  • If the window is minimised
  • If the window is restored from maximized, or minimized state
  • If the window is resized programmatically, by setting the width, height or bounds properties

The event type is the same as with the move operation, giving us access to the “old” and “new” sizes of the window. The sequence of events works in the same way too:

  • A NativeWindowBoundsEvent.RESIZING event is dispatched.
  • If this event is not cancelled (by calling the event’s preventDefault method) then the resize operation will continue
  • Once the window has been resized, a NativeWindowBoundsEvent.RESIZE event will be dispatched

Lastly, as with the move operation, when a window is being resized by the user, it will repeatedly go through this cycle, resizing the window in small steps. If at any stage, one of the NativeWindowBoundsEvent.RESIZING events is cancelled, the resize operation will terminate. This includes resizes triggered by the NativeWindow.startResize () method discussed in the previous part of the post.

That’s all of ‘em

So that’s all of the events covered now. You can see how to handle various different operations that will happen during the lifetime of your window. You can react to (and cancel, if you wish) moves, resizes and the closing of your window. Most importantly, if creating your own application chrome, or implementing your own close/resize/move functionality, you should try and keep these operations cancelable. It’ll make things much easier down the line if, for example, you want to stop the user closing the window before the save their work.

Conclusion

I’ve now gone through all of the properties, methods and events exposed by a NativeWindow. As you can see, the API is fairly thorough, but extremely simple to use. It makes it easy to create, move, resize, hide, and reorder your windows, and to control how your windows will look and behave. I will try and carry this all through into an example at some point, but for now I hope this explanation has been fairly useful. Gimme a shout if there’s anything I’ve missed……

3 Responses to “NativeWindow – using AIR windows with Actionscript (part 3 of 3)”

  1. unhitched Says:

    great post! But here’s a question for you:

    When closing windows in AIR apps, is it necessary to invalidate the window to allow for GC?

    And is there a difference to the above between creating windows using the NativeWindow class as opposed to creating an mx:Window in Flex?

    (ok two questions)


  2. lowpitch Says:

    ello,

    You don’t need to invalidate the window when you’re done with it. In theory, if you call close () on it, and there are no other references to the NativeWindow anywhere else, it should be eligable for garbage collection. Also, any DisplayObjects that were on the window’s stage should also be garbage collected, again assuming there are no other references to them.

    Regarding mx:Window / mx.core.Window, it’s basically a wrapper for NativeWindow with some other Flex good stuff thrown in. Also check out the useFlexChrome property – if set to true, for some reason the standard looking window is visually slightly different. There’s a status bar at the bottom, and for me the default background colour is vaguely different. mx:Window also throws out some other events (e.g. when network connection status changes). If you have a little look in the mx.core.Window class you should be able to see what’s going on fairly easily.


  3. unhitched Says:

    Thanks I’ll do some digging


Leave a Reply