Creating NativeWindows in AIR and displaying Flex content in them

Thanks to Daniel Dura for event getting me on the right path to making this work!

In AIR, you can create new popup windows buy using the NativeWindow object. This gives you the ability to do something like a fullscreen projector from your application. The concept rocks, but in beta right now, it’s not fully implemented and there are some hacks you have to do to get your content to show up in the new NativeWindow.

When I first started trying to load my custom component, I couldn’t see a thing even after using Daniel’s suggestion of adding it to the main application’s display list. It seems that percentage values were being ignored and the size of the canvas being added was being set to 0x0 because of it. That made it invisible obviously.

So, I figured maybe if we wrapped it in another container, set that containers width/height, maybe that would light things up. That *did* help, but I was still tracing out the window size and it was showing up at 400×200, which was wrong since I’d called maximize() on the window. Naturally, I’m thinking there’s an event to let us know when it’s fullscreen, and there is of course:

[as]flash.events.NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE [/as]

You have to wait for that to fire, so you can get the correct window size. You use that to set the size of your container canvas, and then the children’s percentage settings work as you’d expect. At this point, I added my custom component (SlideShowViewer) to the container, but NOT to the NativeWindow’s stage just yet.

Now, adding it to the main application’s display list will initialize the component to work correctly (be careful not to add it to the main applications stage, use application.addChild())
[as]
mx.core.Application.application.addChild(container);
mx.core.Application.application.removeChild(container);[/as]

Daniel had added it first to a hiddenCanvas on stage, but I didnt’ want something just sitting around for this purpose and this works just fine.

Finally, add container to the NativeWindow’s stage and all should be good.

In the constructor:
[as]public function SlideShowWindow(initOptions:NativeWindowInitOptions)
{
super(initOptions);
addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, handleDisplayChange);
addEventListener(Event.ACTIVATE, init);
}[/as]

[as]protected function handleDisplayChange(e:NativeWindowDisplayStateEvent):void
{
container.width = width;
container.height = height;

slideShowViewer = new SlideShowViewer();
container.addChild(slideShowViewer);

mx.core.Application.application.addChild(container);
mx.core.Application.application.removeChild(container);
stage.addChild(container);

//trace(“DISPLAY CHANGE”, this.width, this.height, slideShowViewer.width, slideShowViewer.height);
}[/as]

  1. Check out mx.core.Window. It’s fully Flexified.

  2. I agree. mx.core.Window is a good choice. You can subclass that with your content in it, and then simply instantiate and open it:

    var myWin : MyWindow = new MyWindow();
    myWin.open();

  3. what’s the difference between that and NativeWindow though? if I have a menu system in AIR, would Window go full screen over that and any system chrome on the app?

  4. is there an example which shows how to create your own native window as the main application window in flex?

    • Craig Soich
    • June 3rd, 2009

    John,

    I’m having the same problem with the content (in a container) not initializing in my nativeWindow. However, I’m authoring in flash, and :
    mx.core.Application.application.addChild(container);
    mx.core.Application.application.removeChild(container);
    does not work. I can’t find a flash analog to Application.

    any thoughts (other than “start programming in Flex”?)

    Thanks!

    • @craig

      did you used the NativeWindow method activate() ?
      And did you put the container in the stage of the NativeWindow?

    • Simon
    • July 27th, 2009

    mx.core.Application only applies to Flex. With AIR, you need to use mx.core.WindowedApplication, I believe.

    • Craig Soich
    • July 27th, 2009

    Wow. It’s been a while since I solved this, & I don’t remember how I did it, exactly. I used:

    be.boulevart.air.utils.ScreenManager

    to handle making them windows fullscreen and putting them on the right monitors.

    I made the windows by:
    var options:NativeWindowInitOptions = new NativeWindowInitOptions();
    options.systemChrome = NativeWindowSystemChrome.NONE;
    var nw1:NativeWindow=new NativeWindow(options);

    I moved all of my content to a sprite called StageContents, and did this:
    nw1.stage.addChild(stageContents);

    for the second window, I took a bitmap copy of stageContents every frame, and drew it into an object placed in nw2, called stageRepeater, by:
    nw2.stage.addChild(stageRepeater);

    and in the render routine:
    stageRepeater.bitmapData.draw(stageContents);

    Be advised that you’ll have no mouse interactivity in the second window, since a control really isn’t there.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s