tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/3073-multiple-windowsRobotlegs: Discussion 2013-06-17T16:47:56Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-12T16:31:00Z2013-06-13T09:29:08ZMultiple windows<div><p>hi,</p>
<p>I am going to work on an AIR app built in RL 1 and I need to
work with multiple windows that share models and services.<br>
there are a couple of threads here that suggest that this would be
made easier in RL 2, like here:<br>
<a href=
"http://knowledge.robotlegs.org/discussions/questions/578-multiple-windows-in-air-application">
http://knowledge.robotlegs.org/discussions/questions/578-multiple-w...</a></p>
<p>Is this the case? And if so, does that work with multiple
contexts or smt like simpler mediation of the context views in the
windows?<br>
And, I know this is hard to say, but would it be worthwhile to
migrate from RL 1 to RL 2 for this - not so complicated -
project?</p>
<p>Is there any info somewhere on this specific topic? And is there
something like a migration guide for converting a RL1 to a RL2
project?</p>
<p>thanks!</p>
<p>Jeff.</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-13T09:34:48Z2013-06-13T14:52:40ZMultiple windows<div><p>Hi Jeff,</p>
<p>Your post got stuck in the spam queue for some weird reason.</p>
<p>Yes, it’s easier to work with popups and AIR Windows in
rl2.<br>
The ViewManager takes care of everything ;)</p>
<p>Mapping:</p>
<pre>
<code>mediatorMap.map(SomeWindowView).toMediator(SomeWindowMediator);</code>
</pre>
<p>Oppening the Window:</p>
<pre>
<code> var someWindow:SomeWindowView = new SomeWindowView();
viewManager.addContainer(someWindow);
someWindow.open();</code>
</pre>
<p>Closing and removing the Window</p>
<p>SomeWindow.mxml</p>
<pre>
<code>protected function window1_closeHandler(event:Event):void
{
this.owner.removeChild(this);
//the owner is WindowedSystemManager
}</code>
</pre>
<p>SomeWindowMediator</p>
<pre>
<code>override public function destroy():void
{
viewManager.removeContainer(view);
super.destroy();
}</code>
</pre>
<p>If it’s not clear, let me know.</p>
<p>See Shaun’s answer regarding the ViewManager:<br>
<a href=
"http://knowledge.robotlegs.org/discussions/robotlegs-2/553-viewmanager-what-is-it-for#comment_21538819">
http://knowledge.robotlegs.org/discussions/robotlegs-2/553-viewmana...</a></p>
<blockquote>
<p>And, I know this is hard to say, but would it be worthwhile to
migrate from RL 1 to RL 2 for this - not so complicated -
project?</p>
</blockquote>
<p>Yes, it’s definitely worthwhile to migrate from rl1 to
rl2!! :)</p>
<blockquote>
<p>Is there any info somewhere on this specific topic? And is there
something like a migration guide for converting a RL1 to a RL2
project?</p>
</blockquote>
<p>There is no ‘real’ tutorial yet. The rl2
documentation is on github:<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/tree/master/src/robotlegs/bender">
https://github.com/robotlegs/robotlegs-framework/tree/master/src/ro...</a></p>
<p>Also, see my answer in the linked thread:<br>
<a href=
"http://knowledge.robotlegs.org/discussions/questions/2209-mediator-maps-value-twice#comment_26311878">
http://knowledge.robotlegs.org/discussions/questions/2209-mediator-...</a></p>
<p>Does this help?</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T11:33:53Z2013-06-14T11:33:53ZMultiple windows<div><p>Thanks, Ondina, great info, I'll look into RL2 then ;)</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T12:16:30Z2013-06-14T12:16:30ZMultiple windows<div><p>Cool:)</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T14:01:05Z2013-06-14T14:04:17ZMultiple windows<div><p>I am trying to simply open a new NativeWindow in an AIR project
and I wonder what sort of object the SomeWindowView is in your
example above. Is that a regular view based on Sprite, which an
open() method, or is that method somehow built in in RL?<br>
And how does working with the ViewManager work wit
NativeWindow?</p>
<p>In other words, how does your example code relate to smt like
the following code:<br></p>
<pre>
<code>var viewB:ViewB = new ViewB();
var nw =new NativeWindow(new NativeWindowInitOptions);
nw.width=1024;
nw.height=576;
nw.stage.addChild(viewB);
nw.stage.scaleMode = StageScaleMode.NO_SCALE;
nw.activate();</code>
</pre>
<p>And are there by any chance any additional features built in to
work with native windows, like setting their positions or going
fullscreen?</p>
<p>I assume I need to map the ViewManager before I can use/inject
it, is this a good way to do that?<br>
<code>context.injector.map(ViewManager).asSingleton();</code></p>
<p>thanks,<br>
Jeff.</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T14:32:38Z2013-06-14T14:34:59ZMultiple windows<div><p>SomeWindowView is a spark.components.Window (The Window is a
top-level container for additional windows in an AIR desktop
application.) in my example.</p>
<p>I haven’t tried rl2 with a NativeWindow yet. I have an old
rl1 project, where I used a NativeWidow with the modular utility.
I’ll have to try it out with rl2 too and report back over the
weekend, if that’s ok with you :)</p>
<blockquote>
<p>I assume I need to map the ViewManager before I can use/inject
it, is this a good way to do that?
'context.injector.map(ViewManager).asSingleton();'</p>
</blockquote>
<p>You don’t need to map the ViewManager. If the
ViewManagerExtension has been installed, you’ll have access
to the ViewManager wherever you inject it:<br>
[Inject] public var viewManager:IViewManager;</p>
<p>Since the ViewManagerExtension is included in the MVCSBundle,
you don’t have to install it separately.</p>
<p>ViewManagerExtension<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/ViewManagerExtension.as">
https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<p>MVCSBundle<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/bundles/mvcs/MVCSBundle.as">
https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T15:02:11Z2013-06-14T15:02:11ZMultiple windows<div><p>okay, I can now access ViewManager without mapping it. Thanks
for looking into it, no hurry, I will also report my findings. By
the way, I'm working in a pure as3 project, no flex.</p>
<p>thanks, also for your fast replies :)<br>
Jeff.</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T15:09:45Z2013-06-14T15:13:38ZMultiple windows<div><p>Just to clarify: I'm curious about RL2 and the possible benefits
of this ViewManager, because I want to share data among the initial
native window and a new native window. Both windows show part of a
game, with some shared logic and some 'window-specific' logic if
that makes any sense. From what I read ViewManager - or RL2 in
general - eases the process of mediation without having to use
multiple contexts, but I don't see yet how exactly.</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T15:21:50Z2013-06-14T15:21:50ZMultiple windows<div><p>In rl1 I used this script:<br>
<a href=
"http://www.ben-morris.com/howto-add-flex-mx-controls-to-a-nativewindow-for-adobe-air">
http://www.ben-morris.com/howto-add-flex-mx-controls-to-a-nativewin...</a></p>
<p>NativeContentView is just a ‚normal’ display object,
in my case a Group.</p>
<p>I’ve mapped NativeContentView to
NativeContentMediator.</p>
<pre>
<code>var nativeWindow:ExtendedNativeWindow;
//* Set up the NativeWindow options
var options:NativeWindowInitOptions=new NativeWindowInitOptions();
//* Create the NativeWindow
nativeWindow=new ExtendedNativeWindow(options);
//* Set the height, width and position
nativeWindow.width=400;
nativeWindow.height=300;
nativeWindow.x=(Screen.mainScreen.bounds.width - 400) / 2;
nativeWindow.y=(Screen.mainScreen.bounds.height - 300) / 2;
nativeWindow.stage.scaleMode=StageScaleMode.NO_SCALE;
nativeWindow.stage.align=StageAlign.TOP_LEFT;
//* Create an instance of the content for the NativeWindow
var content:NativeContentView=new NativeContentView();
//* Pass the content into the native window
nativeWindow.addChildControls(content);
//here you could let the ViewManager add the content, but I haven’t tried it yet!!!
viewManager.addContainer(content);
//* Activate the window
nativeWindow.activate();</code>
</pre>
<p>I’m running out of time for today, so to be continued
(including answering your last question about the ViewManager) in
the next days :)</p>
<p>See ya</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-14T17:17:04Z2013-06-14T17:17:41ZMultiple windows<div><p>Well, I seem to have got smt working where I can open a new
native window using the view manager. I simply map the view in the
config class:<br></p>
<pre>
<code>mediatorMap.map(ViewA).toMediator(ViewAMediator);</code>
</pre>
<p>and open a native window in a command where I also add the view
to the view manager, which makes it possible to dispatch (and
listen for) signals through the mediator. Without adding it to the
view manager no working signals.</p>
<pre>
<code>var viewA:ViewA = new ViewA();
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.renderMode = NativeWindowRenderMode.DIRECT;
var nw:NativeWindow =new NativeWindow(options);
nw.width=1024;
nw.height=576;
viewManager.addContainer(viewA);
// trace(viewManager.containers[1] );//outputs View A
nw.stage.addChild(viewA );
nw.stage.scaleMode = StageScaleMode.NO_SCALE;
// nw.stage.displayState = StageDisplayState.FULL_SCREEN;
nw.activate();</code>
</pre>
<p>Btw, this only works when I add the view to the view manager
before I add it to<br>
the stage of the native window.</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-15T06:50:53Z2013-06-15T06:50:53ZMultiple windows<div><p>Hey Jeff,</p>
<p>You’re right. The view has to be added to the viewManager
<strong>before</strong> it gets added to the stage, otherwise the
viewManager cannot know when the view is added to the
stage…<br>
I was in a hurry when I pasted the rl1 code, and I just placed the
line for viewManager in there without thinking too much about it.
Sorry for that.</p>
<p>Same rule applies to popups:<br></p>
<pre>
<code>//1 instantiate a title window
var titleWindowInstance:SomePopUpView = new SomePopUpView();
//2 add the TitleWindow to the viewManager
viewManager.addContainer(titleWindowInstance);
//3 then add it to the popupmanager
PopUpManager.addPopUp(titleWindowInstance, FlexGlobals.topLevelApplication as DisplayObject);</code>
</pre>
<p>I haven’t had time to try it out yet, but I wonder how
your code works. In my example from rl1 I used the
ExtendedNativeWindow, where WindowedSystemManager is the one adding
the component to the window.</p>
<blockquote>
<p>Adobe: You cannot add Flex components directly to the display
list of a NativeWindow instance. Instead, use the Flex
mx:WindowedApplication and mx:Window components to create your
windows and add the other Flex components as children of those
objects. You can add Flex-based SWF content directly to a
NativeWindow window as long as the SWF file is loaded into its own
application domain and is application content.</p>
</blockquote>
<p>So, either you use something similar to the
ExtendedNativeWindow, or you simply do this:</p>
<pre>
<code>var viewA:ViewA = new ViewA();
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.renderMode = NativeWindowRenderMode.DIRECT;
viewManager.addContainer(viewA);//1
var systemManager:WindowedSystemManager = new WindowedSystemManager(viewA);//2
nw.stage.addChild(systemManager );//3
nw.activate();//4</code>
</pre>
<blockquote>
<p>Just to clarify: I'm curious about RL2 and the possible benefits
of this ViewManager, because I want to share data among the initial
native window and a new native window. Both windows show part of a
game, with some shared logic and some 'window-specific' logic if
that makes any sense.</p>
</blockquote>
<p>We’ll talk about this later today or tomorrow. Now
I’m going to go out to enjoy the sun:)</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-15T07:47:41Z2013-06-15T08:11:01ZMultiple windows<div><p>hi Ondina,</p>
<p>I'm working in a pure as3 project so I'm not using the
WindowedSystemManager nor do I want to add flex components to the
new window, just as3 content. So I simply map my view to a
mediator, create and open a new native window, add the content (a
sprite view) to its stage and before that also to the view
manager.</p>
<p>Adding it to the view manager makes it possible to make use of
the view-mediator mapping. I can dispatch events(signals) and
listen for them in both directions (app < > new window), so
I'm quite happy with that.</p>
<p>Closing the window also works albeit in a way that may feel a
bit like a workaround. I save the instance of the new window in a
model, so that I later can access it from any other command and
call smt like<br></p>
<pre>
<code>[Inject]
public var wnModel:WindowModel;</code>
</pre>
<pre>
<code>wnModel.myWindow.close();</code>
</pre>
So I can indeed establish communication between the initial and new
window and hopefully it will also work when I want to switch
between views in the new window, smt I will try next, by adding
other views to the manager.
<p>Enjoy the sun!</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-15T17:35:38Z2013-06-15T17:35:38ZMultiple windows<div><p>Oh, yes, you told me already in one of your posts that your
project is a pure as3 one! I totally forgot about that.</p>
<p>I also forgot to tell you that you have to remove the view from
the viewManager when it’s removed from stage.</p>
<p>viewManager.removeContainer(view);</p>
<p>Thanks for sharing your findings.<br>
I hope to get more time tomorrow to play around with the
NativeWindow in rl2. I’m curious how it behaves in terms of
garbage collection in a Flex and a pure as3 project. Is your
example working fine? Does ViewA get gc-ed?</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-16T17:57:39Z2013-06-16T17:57:39ZMultiple windows<div><p>Here, my findings:</p>
<p>NativeWindow in a pure as3 project behaves as expected.<br>
As you mentioned, it is possible to add a view (extending Sprite)
to the stage of a NativeWindow. The view gets gc-ed after closing
the window.</p>
<p>The following is probably not interesting to you, but since
there are also Flex users who might read this thread in the future,
I thought it might be worth sharing my findings:</p>
<p>Adding Flex components to a NativeWindow is a pain in
the…code.<br>
It’s easy to add a component to the native window using the
WindowedSystemManager, as previously mentioned in my posts, but the
view doesn’t get gc-ed after closing the window. And
that’s because there is kind of circular reference between
View and WindowedSystemManager that keeps the view in memory.
I’ve been trying several things to solve this, but to no
avail. My brain hurts already… so, I’m giving up.</p>
<p>My suggestion for Flex users: instead of a NativeWindow use a
spark.Window, which works just fine, at least in my experience.</p>
<p>So, Jeff, if you think your questions have been answered, you
can close the discussion.</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T07:01:44Z2013-06-17T07:03:21ZMultiple windows<div><p>hi Ondina,</p>
<p>thanks for testing, I also tested some more:<br>
Adding multiple views to a new native window that all have their
own mediator, this works fine<br>
Adding child (nested) views to a view added to a new native window,
with their own mediators, which also works fine.</p>
<p>I have one question though. The first test works when I add the
views at the same time, for instance in a startup command. I map
the views and mediators in my config class. But when I try to add a
view later, for instance in another command, the view is being
added but there is no mediation. Do I need to manually mediate that
view? And if so, how do i do that in RL2 (not even sure about RL1,
never did that)? A code snippet would be great,</p>
<p>thanks,<br>
Jeff.</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T09:21:36Z2013-06-17T10:33:11ZMultiple windows<div><p>Hi Jeff,</p>
<p>I just tried to add a second view to the nw in a pure as3
project. You need to tell the viewManager about it, so you’ll
have to inject the viewManager into the command that is adding the
view:</p>
<pre>
<code>var anotherView:AnotherView = new AnotherView();
viewManager.addContainer(anotherView);
nw.stage.addChild(anotherView );</code>
</pre>
<p>AnotherMediator will be created, if you mapped AnotherView to
it.</p>
<p>The problem is, AnotherView doesn’t get removed from the
NativeWindow after closing it, therefore its mediator doesn’t
get destroyed. So, both, AnotherView and AnotherMediator,
aren’t eligible for gc.</p>
<p>I’d need more time to investigate this( in a Flex project
as well )<br>
I’ll let you know how it goes.</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T09:49:20Z2013-06-17T09:49:20ZMultiple windows<div><p>You are right, mediaton does get initialized, I had a typo in my
code. And I see the same thing with the other view still existing.
I seem to be able to remove it from the view manager, but it is
still on that window's stage. But this may be an AIR problem and
not so much a RL issue?</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T10:34:31Z2013-06-17T10:34:31ZMultiple windows<div><blockquote>
<p>But this may be an AIR problem</p>
</blockquote>
<p>Yes, that's what I think too.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T11:17:51Z2013-06-17T11:17:51ZMultiple windows<div><p>I’ve tested it with a spark.Window, and it works fine. I
can add an additional view to it, and after closing the Window,
both views and their mediators get gc-ed.<br>
I added an event handler for the CLOSE event in the Window, where I
removed all its children and I also removed the Window from its
owner, which is the WindowedSystemManager.<br>
I’ll post the code later on, but that doesn’t help
<em>you</em> very much, because you’re using the
NativeWindow. So, Flex or no Flex, it seems the NativeWindow is the
problem.</p>
<p>I don’t know yet if there is a way to remove the children
from the NativeWindow. When I close the nw, it seems there is only
one child, and that is the first one added, even though after I add
the second child, the nw has indeed 2 children…weird. If you
find a solution, I’d be curious to know about it, and it
would help others as well.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T11:53:40Z2013-06-17T11:53:40ZMultiple windows<div><p>Correction: It works with NativeWindow, too. When you remove the
children from the nw, you should use a while loop, not a for
loop.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T12:25:46Z2013-06-17T12:25:46ZMultiple windows<div><p>Code snippets for pure as3 NativeWindow:</p>
<p>In config:</p>
<pre>
<code>mediatorMap
.map(SomeView)
.toMediator(SomeMediator);
mediatorMap
.map(AnotherView)
.toMediator(AnotherMediator);</code>
</pre>
<p>Open the window and add SomeView:</p>
<pre>
<code>protected function onOpenWindow():void
{
var someView:SomeView = new SomeView();
var options:NativeWindowInitOptions = new NativeWindowInitOptions();
options.renderMode = NativeWindowRenderMode.DIRECT;
nw = new NativeWindow(options);
nw.addEventListener(Event.CLOSING, onWindowClosing);
nw.width = 500;
nw.height = 500;
viewManager.addContainer(someView);
nw.stage.addChild(someView);
nw.stage.scaleMode = StageScaleMode.NO_SCALE;
nw.activate();
}</code>
</pre>
<p>Add another view:</p>
<pre>
<code>protected function onAddViewToNW():void
{
var anotherView:AnotherView = new AnotherView();
viewManager.addContainer(anotherView);
nw.stage.addChild(anotherView );
}</code>
</pre>
<p>Removing Window’s children:</p>
<pre>
<code>protected function onWindowClosing(event:Event):void
{
while(nw.stage.numChildren>0)
{
nw.stage.removeChildAt(0);
}
}</code>
</pre>
<p>SomeView on removed from stage (same for AnotherView)</p>
<pre>
<code>protected function onRemoveFromstage(event:Event):void
{
//remove all event listeners
removeEventListener(Event.ADDED_TO_STAGE, onAddedTostage);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromstage);
//remove children
while(nw.stage.numChildren>0)
{
nw.stage.removeChildAt(0);
}
}</code>
</pre>
<p>SomeMediator (same for AnotherMediator):</p>
<pre>
<code>override public function destroy():void
{
viewManager.removeContainer(view);
super.destroy();
}</code>
</pre></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T12:30:39Z2013-06-17T12:30:39ZMultiple windows<div><p>Yes, I got it working too. Great, now I can have multiple
windows partly sharing the same data in only one context. I leave
it to you to close this thread...</p></div>JeffW.tag:robotlegs.tenderapp.com,2009-10-18:Comment/272887792013-06-17T12:51:16Z2013-06-17T12:51:16ZMultiple windows<div><blockquote>
<p>Yes, I got it working too. Great, now I can have multiple
windows partly sharing the same data in only one context. I leave
it to you to close this thread...</p>
</blockquote>
<p>Awesome :)</p>
<p>Flex usage with spark Window</p>
<p>Mappings as above.</p>
<p>Opening a Window:</p>
<pre>
<code>private var someWindow:SomeWindowView;
private function onOpenWindow(event:ShellNavigatorEvent):void
{
someWindow = new SomeWindowView();
viewManager.addContainer(someWindow);
someWindow.addElement(new SomeView());
someWindow.addEventListener(Event.CLOSING, onWindowClose);
someWindow.width = 500;
someWindow.height = 500;
someWindow.open();
}</code>
</pre>
<p>Add another view to the opened window:</p>
<pre>
<code>private function onAddViewToWindow(event:ShellNavigatorEvent):void
{
someWindow.addElement(new AnotherView());
}</code>
</pre>
<p>Closing handler:</p>
<pre>
<code>protected function onWindowClose(event:Event):void
{
someWindow=null;
}</code>
</pre>
<p>SomeWindowView on closing</p>
<pre>
<code>protected function window1_closeHandler(event:Event):void
{
//remove all event listeners
removeEventListener(Event.CLOSE, window1_closeHandler);
removeAllElements();
this.owner.removeChild(this);//owner == WindowedSystemManager
}</code>
</pre>
<p>SomeView and AnotherView</p>
<pre>
<code>protected function onRemovedFromoStage(event:Event):void
{
//remove all event listeners
removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromoStage);
removeAllElements();
}</code>
</pre>
<p>SomeMediator and AnotherMediator</p>
<pre>
<code>override public function destroy():void
{
viewManager.removeContainer(view);
super.destroy();
}</code>
</pre>
<p>Now I’m done ;) Discussion closed.</p></div>Ondina D.F.