blob: 64a2048168611e13191098f80fc0d6b00377ed40 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package mx.core
{
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.Point;
import mx.utils.MatrixUtil;
[ExcludeClass]
/**
* @private
* Helper class to implement the ILayoutElement interface for IUIComponent
* classes.
*/
public class LayoutElementUIComponentUtils
{
include "../core/Version.as";
public function LayoutElementUIComponentUtils()
{
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
// When changing these constants, make sure you change
// the constants with the same name in UIComponent
private static const DEFAULT_MAX_WIDTH:Number = 10000;
private static const DEFAULT_MAX_HEIGHT:Number = 10000;
/**
* @return Returns the preferred width (untransformed) of the IUIComponent.
* Takes into account measured width, explicit width, explicit min width
* and explicit max width.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
private static function getPreferredUBoundsWidth(obj:IUIComponent):Number
{
// explicit trumps measured. measuredWidth should already be
// constraint between min & max during measure phase.
var result:Number = obj.getExplicitOrMeasuredWidth();
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
result = (obj.scaleX == 0) ? 0 : result / obj.scaleX;
}
return result;
}
/**
* @return Returns the preferred height (untransformed) of the IUIComponent.
* Takes into account measured height, explicit height, explicit min height
* and explicit max height.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
private static function getPreferredUBoundsHeight(obj:IUIComponent):Number
{
// explicit trumps measured. measuredWidth should already be
// constraint between min & max during measure phase.
var result:Number = obj.getExplicitOrMeasuredHeight();
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
result = (obj.scaleY == 0) ? 0 : result / obj.scaleY;
}
return result;
}
private static function getMinUBoundsWidth(obj:IUIComponent):Number
{
// explicit trumps explicitMin trumps measuredMin.
// measuredMin is restricted by explicitMax.
var minWidth:Number;
if (!isNaN(obj.explicitMinWidth))
{
minWidth = obj.explicitMinWidth;
}
else
{
minWidth = isNaN(obj.measuredMinWidth) ? 0 : obj.measuredMinWidth;
if (!isNaN(obj.explicitMaxWidth))
minWidth = Math.min(minWidth, obj.explicitMaxWidth);
}
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
minWidth = (obj.scaleX == 0) ? 0 : minWidth / obj.scaleX;
}
return minWidth;
}
private static function getMinUBoundsHeight(obj:IUIComponent):Number
{
// explicit trumps explicitMin trumps measuredMin.
// measuredMin is restricted by explicitMax.
var minHeight:Number;
if (!isNaN(obj.explicitMinHeight))
{
minHeight = obj.explicitMinHeight;
}
else
{
minHeight = isNaN(obj.measuredMinHeight) ? 0 : obj.measuredMinHeight;
if (!isNaN(obj.explicitMaxHeight))
minHeight = Math.min(minHeight, obj.explicitMaxHeight);
}
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
minHeight = (obj.scaleY == 0) ? 0 : minHeight / obj.scaleY;
}
return minHeight;
}
private static function getMaxUBoundsWidth(obj:IUIComponent):Number
{
// explicit trumps explicitMax trumps Number.MAX_VALUE.
var maxWidth:Number;
if (!isNaN(obj.explicitMaxWidth))
maxWidth = obj.explicitMaxWidth;
else
maxWidth = DEFAULT_MAX_WIDTH;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
maxWidth = (obj.scaleX == 0) ? 0 : maxWidth / obj.scaleX;
}
return maxWidth;
}
private static function getMaxUBoundsHeight(obj:IUIComponent):Number
{
// explicit trumps explicitMax trumps Number.MAX_VALUE.
var maxHeight:Number;
if (!isNaN(obj.explicitMaxHeight))
maxHeight = obj.explicitMaxHeight;
else
maxHeight = DEFAULT_MAX_HEIGHT;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
maxHeight = (obj.scaleY == 0) ? 0 : maxHeight / obj.scaleY;
}
return maxHeight;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getPreferredBoundsWidth(obj:IUIComponent,transformMatrix:Matrix):Number
{
var width:Number = getPreferredUBoundsWidth(obj);
if (transformMatrix)
{
width = MatrixUtil.transformSize(width, getPreferredUBoundsHeight(obj), transformMatrix).x;
}
return width;
}
public static function getPreferredBoundsHeight(obj:IUIComponent,transformMatrix:Matrix):Number
{
var height:Number = getPreferredUBoundsHeight(obj);
if (transformMatrix)
{
height = MatrixUtil.transformSize(getPreferredUBoundsWidth(obj), height, transformMatrix).y;
}
return height;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getMinBoundsWidth(obj:IUIComponent, transformMatrix:Matrix):Number
{
var width:Number = getMinUBoundsWidth(obj);
if (transformMatrix)
{
width = MatrixUtil.transformSize(width, getMinUBoundsHeight(obj), transformMatrix).x;
}
return width;
}
public static function getMinBoundsHeight(obj:IUIComponent,transformMatrix:Matrix):Number
{
var height:Number = getMinUBoundsHeight(obj);
if (transformMatrix)
{
height = MatrixUtil.transformSize(getMinUBoundsWidth(obj), height, transformMatrix).y;
}
return height;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getMaxBoundsWidth(obj:IUIComponent, transformMatrix:Matrix):Number
{
var width:Number = getMaxUBoundsWidth(obj);
if (transformMatrix)
{
width = MatrixUtil.transformSize(width, getMaxUBoundsHeight(obj), transformMatrix).x;
}
return width;
}
public static function getMaxBoundsHeight(obj:IUIComponent, transformMatrix:Matrix):Number
{
var height:Number = getMaxUBoundsHeight(obj);
if (transformMatrix)
{
height = MatrixUtil.transformSize(getMaxUBoundsWidth(obj), height, transformMatrix).y;
}
return height;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getBoundsXAtSize(obj:IUIComponent, width:Number, height:Number, transformMatrix:Matrix):Number
{
if (!transformMatrix)
return obj.x;
var fitSize:Point = MatrixUtil.fitBounds(width, height, transformMatrix,
obj.explicitWidth,
obj.explicitHeight,
getPreferredUBoundsWidth(obj),
getPreferredUBoundsHeight(obj),
getMinUBoundsWidth(obj),
getMinUBoundsHeight(obj),
getMaxUBoundsWidth(obj),
getMaxUBoundsHeight(obj));
// If we couldn't fit at all, default to the minimum size
if (!fitSize)
fitSize = new Point(getMinUBoundsWidth(obj), getMinUBoundsHeight(obj));
var pos:Point = new Point();
MatrixUtil.transformBounds(fitSize.x, fitSize.y,
transformMatrix,
pos);
return pos.x;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getBoundsYAtSize(obj:IUIComponent, width:Number, height:Number, transformMatrix:Matrix):Number
{
if (!transformMatrix)
return obj.y;
var fitSize:Point = MatrixUtil.fitBounds(width, height, transformMatrix,
obj.explicitWidth,
obj.explicitHeight,
getPreferredUBoundsWidth(obj),
getPreferredUBoundsHeight(obj),
getMinUBoundsWidth(obj),
getMinUBoundsHeight(obj),
getMaxUBoundsWidth(obj),
getMaxUBoundsHeight(obj));
// If we couldn't fit at all, default to the minimum size
if (!fitSize)
fitSize = new Point(getMinUBoundsWidth(obj), getMinUBoundsHeight(obj));
var pos:Point = new Point();
MatrixUtil.transformBounds(fitSize.x, fitSize.y,
transformMatrix,
pos);
return pos.y;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getLayoutBoundsWidth(obj:IUIComponent,transformMatrix:Matrix):Number
{
var width:Number = obj.width;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
width = (obj.scaleX == 0) ? 0 : width / obj.scaleX;
}
if (transformMatrix)
{
var height:Number = obj.height;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
height = (obj.scaleY == 0) ? 0 : height / obj.scaleY;
}
// By default the IUIComponent's registration point is the same
// as its untransformed border top-left corner, which is (0,0).
width = MatrixUtil.transformBounds(width, height,
transformMatrix,
new Point()).x;
}
return width;
}
public static function getLayoutBoundsHeight(obj:IUIComponent,transformMatrix:Matrix):Number
{
var height:Number = obj.height;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
height = (obj.scaleY == 0) ? 0 : height / obj.scaleY;
}
if (transformMatrix)
{
var width:Number = obj.width;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
width = (obj.scaleX == 0) ? 0 : width / obj.scaleX;
}
// By default the IUIComponent's registration point is the same
// as its untransformed border top-left corner, which is (0,0).
height = MatrixUtil.transformBounds(width, height,
transformMatrix,
new Point()).y;
}
return height;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function getLayoutBoundsX(obj:IUIComponent,transformMatrix:Matrix):Number
{
if (transformMatrix == null)
return obj.x;
var width:Number = obj.width;
var height:Number = obj.height;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
width = (obj.scaleX == 0) ? 0 : width / obj.scaleX;
height = (obj.scaleY == 0) ? 0 : height / obj.scaleY;
}
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
var pos:Point = new Point();
MatrixUtil.transformBounds(width, height,
transformMatrix,
pos);
return pos.x;
}
public static function getLayoutBoundsY(obj:IUIComponent,transformMatrix:Matrix):Number
{
if (transformMatrix == null)
return obj.y;
var width:Number = obj.width;
var height:Number = obj.height;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
width = (obj.scaleX == 0) ? 0 : width / obj.scaleX;
height = (obj.scaleY == 0) ? 0 : height / obj.scaleY;
}
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
var pos:Point = new Point();
MatrixUtil.transformBounds(width, height,
transformMatrix,
pos);
return pos.y;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function setLayoutBoundsPosition(obj:IUIComponent,x:Number, y:Number, transformMatrix:Matrix):void
{
if (transformMatrix)
{
//race("Setting actual position to " + x + "," + y);
//race("\tcurrent x/y is " + obj.x + "," + obj.y);
//race("\tcurrent actual position is " + actualPosition.x + "," + actualPosition.y);
x = x - getLayoutBoundsX(obj,transformMatrix) + obj.x;
y = y - getLayoutBoundsY(obj,transformMatrix) + obj.y;
}
obj.move(x, y);
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public static function setLayoutBoundsSize(obj:IUIComponent,width:Number,
height:Number,
transformMatrix:Matrix):void
{
if (!transformMatrix)
{
if (isNaN(width))
width = getPreferredUBoundsWidth(obj);
if (isNaN(height))
height = getPreferredUBoundsHeight(obj);
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
width *= obj.scaleX;
height *= obj.scaleY;
}
obj.setActualSize(width, height);
return;
}
var fitSize:Point = MatrixUtil.fitBounds(width, height, transformMatrix,
obj.explicitWidth,
obj.explicitHeight,
getPreferredUBoundsWidth(obj),
getPreferredUBoundsHeight(obj),
getMinUBoundsWidth(obj),
getMinUBoundsHeight(obj),
getMaxUBoundsWidth(obj),
getMaxUBoundsHeight(obj));
// If we couldn't fit at all, default to the minimum size
if (!fitSize)
fitSize = new Point(getMinUBoundsWidth(obj), getMinUBoundsHeight(obj));
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
// We are already taking scale into account from the transform,
// so adjust here since IUIComponent mixes it with width/height
obj.setActualSize(fitSize.x * obj.scaleX, fitSize.y * obj.scaleY);
}
else
obj.setActualSize(fitSize.x, fitSize.y);
}
}
}