| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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); |
| } |
| } |
| } |