I remember that this is a limitation of an the SWF runtime until AS2/
SWF8. Starting with AS3/SWF9 the behavior of managing visible objects
was modified:
http://my.safaribooksonline.com/0596526954/ID-d2450e71-Introduction529380
Anytime a MovieClip was created (in AS2), it was automatically added
into the visual hierarchy and consequently drawn by the renderer.
MovieClips weren't able to move to different places within the
hierarchy; instead, they first had to be destroyed and then
recreated before they could be positioned elsewhere in the display.
The new renderer (AS3/SWF9) is still hierarchical, but not as rigid,
and aims to simplify and optimize the rendering process. The new
rendering model centers on the display list concept and focuses on
the classes available in the flash.display package. The display list
is a hierarchy that contains all visible objects in the .swf movie.
Any object not on the display list is not drawn by the renderer.
That means, you can remove the object from a display list and add it
to a new display list. Here's a code example:
<canvas width="100%" height="800">
<view id="containerA" y="100" width="200" height="200"
bgcolor="blue">
<view id="targetObj" width="150" height="150" bgcolor="yellow">
<method name="whereAmI">
Debug.write("Parent for targetObj view: " + this.parent);
var s = this.getDisplayObject();
Debug.write(s);
Debug.write("Owner for targetObj view: ", s.parent.owner);
</method>
<button text="Click me!" onclick="parent.whereAmI()" />
</view>
</view>
<view id="containerB" x="400" y="100" width="200" height="200"
bgcolor="green">
</view>
<button text="move yellow view" onclick="moveView()">
<method name="moveView">
if ($as3) {
#passthrough {
Debug.write(containerA.getDisplayObject());
var spriteA = containerA.getDisplayObject();
spriteA.removeChild(targetObj.getDisplayObject());
var spriteB = containerB.getDisplayObject();
spriteB.addChild(targetObj.getDisplayObject());
}#
} else if ($as2) {
Debug.warn("Moving display objects from one movieclip to
another not supported in AS3");
}
</method>
</button>
</canvas>
Run this in SWF: you can move the yellow view from the blue to the
green box. #containerA is still listed as parent, even if the yellow
view has been attached to #containerB, but the owner reference changes.
@Henry: Do you have any idea what impact such an action of would have
on the OL view system?
- Raju
On Oct 17, 2009, at 7:18 PM, P T Withington wrote:
There is a `placement` attribute, and a `determinePlacement` method
that can be overridden by a class, but both of these expect the
final placement of a node to be determined at construct time. I
don't know if this restriction is inherent to LzNode, or was a
restriction due to some ancient runtime (e.g., swf5). It might be
possible to make placement dynamic. Clearly any parent/child
dependencies would have to be tracked and adjusted as part of this.
<state> is sort of a half-step to this, in that it can dynamically
remove and add child views, but state does _not_ guarantee the child
view's state information is preserved. In effect a state destroys
and re-creates the child views it controls each time.
You can modulate the `visible` attribute of a view to hide/reveal it
and all its children. Modulating the visibility _does_ preserve the
hidden views state.
I'd be interested in seeing an example of an application where views
need to move.
On 2009-10-16, at 20:39, Rami Ojares / AMG Oy wrote:
Hi,
Would it even be theoretically possible to make parent attribute of
node read/write.
Now moving nodes around means destroying old ones and creating new
ones under new parent.
This becomes a nightmare when the nodes have all kinds of
connections to other nodes.
I know this is a BIG issue but I wondered if this would be even
theoretically possible and what it would require.
Now that I do it manually I will have to maintain two way links
between dependencies.
Example:
- A depends on B (a is listening to events from B)
If I move B I have to know who is listening so I can update the
delegates to listen to events from the new B node
If I could move B without destroying it and creating a new one, the
delegates would not need updating.
- rami