/*****************************************************
*
* Copyright 2009 Adobe Systems Incorporated. All Rights Reserved.
*
*****************************************************
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
*
* The Initial Developer of the Original Code is Adobe Systems Incorporated.
* Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems
* Incorporated. All Rights Reserved.
*
*****************************************************/
package org.osmf.layout
{
import flash.display.DisplayObject;
import flash.display.Sprite;
import org.osmf.events.DisplayObjectEvent;
/**
* @private
*
* Dispatched when a layout target is being set as a layout renderer's container.
*
* LayoutRendererBase dispatches this event on the target being set as its container.
*
* Implementations that are to be used as layout renderer containers are required
* to listen to the event in order to maintain a reference to their layout
* renderer, so it can be correctly parented on the container becoming a child
* of another container.
*
* @eventType org.osmf.layout.LayoutTargetEvent.SET_AS_LAYOUT_RENDERER_CONTAINER
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="setAsLayoutRendererContainer",type="org.osmf.layout.LayoutTargetEvent")]
/**
* @private
*
* Dispatched when a layout target is being un-set as a layout renderer's container.
*
* LayoutRendererBase dispatches this event on the target being unset as its container.
*
* Implementations that are to be used as layout renderer containers are required
* to listen to the event in order to reset the reference to their layout renderer.
*
* @eventType org.osmf.layout.LayoutTargetEvent.UNSET_AS_LAYOUT_RENDERER_CONTAINER
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="unsetAsLayoutRendererContainer",type="org.osmf.layout.LayoutTargetEvent")]
/**
* @private
*
* Dispatched when a layout target is added as a target to a layout renderer.
*
* LayoutRendererBase dispatches this event on a target when it gets added to
* its list of targets.
*
* Implementations that are to be used as layout renderer containers
* are required to listen to the event in order to invoke <code>setParent</code>
* on the renderer that they are the container for.
*
* Failing to do so will break the rendering tree, resulting in unneccasary
* layout recalculations, as well as unexpected size and positioning of the target.
*
* @eventType org.osmf.layout.LayoutTargetEvent.ADD_TO_LAYOUT_RENDERER
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="addToLayoutRenderer",type="org.osmf.layout.LayoutTargetEvent")]
/**
* @private
*
* Dispatched when a layout target is removed as a target from a layout renderer.
*
* LayoutRendererBase dispatches this event on a target when it gets removed from
* its list of targets.
*
* Implementations that are to be used as layout renderer containers
* are required to listen to the event in order to invoke <code>setParent</code>
* on the renderer that they are the container for. In case of removal, the
* parent should be set to null, unless the target has already been assigned
* as the container of another renderer.
*
* Failing to do so will break the rendering tree, resulting in unneccasary
* layout recalculations, as well as unexpected size and positioning of the target.
*
* @eventType org.osmf.layout.LayoutTargetEvent.REMOVE_FROM_LAYOUT_RENDERER
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="removeFromLayoutRenderer",type="org.osmf.layout.LayoutTargetEvent")]
/**
* @private
*
* Dispatched when a layout renderer wishes its layout target container to
* stage a display object for one of its targets.
*
* @eventType org.osmf.layout.LayoutTargetEvent.ADD_CHILD_AT
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="addChildAt",type="org.osmf.layout.LayoutTargetEvent")]
/**
* @private
*
* Dispatched when a layout renderer wishes its layout target container to
* change the display index of the display object for one of its targets.
*
* @eventType org.osmf.layout.LayoutTargetEvent.SET_CHILD_INDEX
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="setChildIndex",type="org.osmf.layout.LayoutTargetEvent")]
/**
* @private
*
* Dispatched when a layout renderer wishes its layout target container to
* remove the display object for one of its targets.
*
* @eventType org.osmf.layout.LayoutTargetEvent.REMOVE_CHILD
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
[Event(name="removeChild",type="org.osmf.layout.LayoutTargetEvent")]
/**
* LayoutTargetSprite defines a Sprite-based ILayoutTarget implementation.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public class LayoutTargetSprite extends Sprite implements ILayoutTarget
{
/**
* Constructor.
*
* @param layoutMetadata The LayoutMetadata to use to layout this
* sprite. Optional.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function LayoutTargetSprite(layoutMetadata:LayoutMetadata=null)
{
_layoutMetadata = layoutMetadata || new LayoutMetadata();
renderers = new LayoutTargetRenderers(this);
addEventListener(LayoutTargetEvent.ADD_CHILD_AT, onAddChildAt);
addEventListener(LayoutTargetEvent.SET_CHILD_INDEX, onSetChildIndex);
addEventListener(LayoutTargetEvent.REMOVE_CHILD, onRemoveChild);
mouseEnabled = true;
mouseChildren = true;
super();
}
// ILayoutTarget
//
/**
* A reference to the display object that represents the target. A
* client may use this reference to position or parent the target.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function get displayObject():DisplayObject
{
return this;
}
/**
* The metadata that's used to hold information about the layout
* of this layout target.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
**/
public function get layoutMetadata():LayoutMetadata
{
return _layoutMetadata;
}
/**
* Defines the width of the element without any transformations being
* applied. For a JPG with an original resolution of 1024x768, this
* would be 1024 pixels. A client may use this value to (for example)
* keep ratio on scaling the element.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function get measuredWidth():Number
{
return _measuredWidth;
}
/**
* Defines the height of the element without any transformations being
* applied. For a JPG with an original resolution of 1024x768, this
* would be 768 pixels. A client may use this value to (for example)
* keep ratio on scaling the element.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function get measuredHeight():Number
{
return _measuredHeight;
}
/**
* Method that informs the implementation that it should reassess its
* measuredWidth and measuredHeight fields:
*
* @param deep True if the measurement request is to be forwarded to
* the target's potential inner layout system. The forwarding should take
* place up front the target measuring itself.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function measure(deep:Boolean = true):void
{
if (deep && renderers.containerRenderer)
{
renderers.containerRenderer.measure();
}
var newMeasuredWidth:Number;
var newMeasuredHeight:Number;
if (renderers.containerRenderer)
{
// The measured dimensions can be fetched from the sprite's own
// layout renderer. Since measurement takes place bottom to top,
// the renderer should already be up to date for this pass:
newMeasuredWidth = renderers.containerRenderer.measuredWidth;
newMeasuredHeight = renderers.containerRenderer.measuredHeight;
}
else
{
// The sprite is a leaf. Fetch the size from the sprite itself:
newMeasuredWidth = super.width / scaleX;
newMeasuredHeight = super.height / scaleY;
}
if ( newMeasuredWidth != _measuredWidth
|| newMeasuredHeight != _measuredHeight
)
{
var event:DisplayObjectEvent
= new DisplayObjectEvent
( DisplayObjectEvent.MEDIA_SIZE_CHANGE, false, false
, null , null
, _measuredWidth , _measuredHeight
, newMeasuredWidth , newMeasuredHeight
);
_measuredWidth = newMeasuredWidth;
_measuredHeight = newMeasuredHeight;
dispatchEvent(event);
}
}
/**
* Method that informs the implementation that it should update its
* display to adjust to the given available width and height.
*
* @param availableWidth
* @param availableHeight
* @param deep True if the layout request is to be forwarded to
* the target's potential inner layout system. The forwarding should take
* place only after the target has laid itself out.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function layout(availableWidth:Number, availableHeight:Number, deep:Boolean = true):void
{
if (renderers.containerRenderer == null)
{
super.width = availableWidth;
super.height = availableHeight;
}
else if (deep)
{
renderers.containerRenderer.layout(availableWidth, availableHeight);
}
}
/**
* @private
*/
public function validateNow():void
{
if (renderers.containerRenderer)
{
renderers.containerRenderer.validateNow();
}
}
// Protected
//
/**
* @private
**/
protected function onAddChildAt(event:LayoutTargetEvent):void
{
addChildAt(event.displayObject, event.index);
}
/**
* @private
**/
protected function onRemoveChild(event:LayoutTargetEvent):void
{
removeChild(event.displayObject);
}
/**
* @private
**/
protected function onSetChildIndex(event:LayoutTargetEvent):void
{
setChildIndex(event.displayObject, event.index);
}
// Overrides
//
/**
* @private
**/
override public function set width(value:Number):void
{
_layoutMetadata.width = value;
}
/**
* @private
**/
override public function get width():Number
{
return _measuredWidth;
}
/**
* @private
**/
override public function set height(value:Number):void
{
_layoutMetadata.height = value;
}
/**
* @private
**/
override public function get height():Number
{
return _measuredHeight;
}
// Private
//
private var _layoutMetadata:LayoutMetadata;
private var _measuredWidth:Number = NaN;
private var _measuredHeight:Number = NaN;
private var renderers:LayoutTargetRenderers;
}
}