📄 percentagesizeutil.as
字号:
/** * 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 Original Code is part of the Open Source Flex 3 SDK Downloads * (http://opensource.adobe.com/wiki/display/flexsdk/Downloads) * * The Initial Developer of the Original Code is Adobe Systems Incorporated * (see original files for appropriate copyright notices) * * Contributor(s): Yahoo! Inc. * * Copyright (c) 2008 Yahoo! Inc. All Rights Reserved. */package com.yahoo.astra.layout.modes{ import flash.display.DisplayObject; /** * Utility functions used for determining pixel-based sizes from percentage-based sizes. * * @author Josh Tynjala and Adobe Systems Inc. */ public class PercentageSizeUtil { //-------------------------------------- // Static Methods //-------------------------------------- /** * This function sets the width of each child so that the widths add up * to spaceForChildren. Each child is set to its preferred width if its * percentWidth is zero. If it's percentWidth is a positive number the * child grows depending on the size of its parent. The height of each * child is set to its preferred height. The return value is any extra * space that's left over after growing all children to their maxWidth. */ public static function flexChildWidthsProportionally(children:Array, configurations:Array, totalWidth:Number, totalHeight:Number):Number { var spaceToDistribute:Number = totalWidth; var totalPercentWidth:Number = 0; var childInfoArray:Array = []; // If the child is flexible, store information about it in the // childInfoArray. For non-flexible children, just set the child's // width and height immediately. // // Also calculate the sum of all widthFlexes, and calculate the // sum of the width of all non-flexible children. var childCount:int = children.length; for(var i:int = 0; i < childCount; i++) { var child:DisplayObject = DisplayObject(children[i]); var config:Object = configurations[i]; if(!config.includeInLayout) { //skip non-configuration children continue; } var percentWidth:Number = config.percentWidth; var percentHeight:Number = config.percentHeight; var height:Number = NaN; if(!isNaN(percentHeight)) { height = Math.max(config.minHeight, Math.min(config.maxHeight, ((percentHeight >= 100) ? totalHeight : totalHeight * percentHeight / 100))); } if(!isNaN(percentWidth)) { totalPercentWidth += percentWidth; var childInfo:ChildInfo = new ChildInfo(); childInfo.percent = percentWidth; childInfo.min = config.minWidth; childInfo.max = config.maxWidth; childInfo.opposite = height; childInfo.child = child; childInfoArray.push(childInfo); } else { //var width:Number = child.width; // if scaled and zoom is playing, best to let the sizes be non-integer // otherwise the rounding creates an error that accumulates in some components like List if(child.scaleX == 1 && child.scaleY == 1) { if(!isNaN(height)) { child.height = Math.floor(height); } } else { if(!isNaN(height)) { child.height = height; } } // Need to account for the actual child width since // setActualSize may trigger a Resize effect, which // could change the size of the component. spaceToDistribute -= child.width; } } // Distribute the extra space among the children. if(totalPercentWidth) { spaceToDistribute = flexChildrenProportionally(totalWidth, spaceToDistribute, totalPercentWidth, childInfoArray); // Set the widths and heights of the flexible children childCount = childInfoArray.length; for(i = 0; i < childCount; i++) { childInfo = ChildInfo(childInfoArray[i]); child = childInfo.child; // if scaled and zoom is playing, best to let the sizes be non-integer // otherwise the rounding creates an error that accumulates in some components like List if(child.scaleX == 1 && child.scaleY == 1) { child.width = Math.floor(childInfo.size); if(!isNaN(childInfo.opposite)) { child.height = Math.floor(childInfo.opposite); } } else { child.width = childInfo.size; if(!isNaN(childInfo.opposite)) { child.height = childInfo.opposite; } } } distributeExtraWidth(children, configurations, totalWidth); } return spaceToDistribute; } /** * This function sets the height of each child * so that the heights add up to spaceForChildren. * Each child is set to its preferred height * if its percentHeight is zero. * If its percentHeight is a positive number, * the child grows (or shrinks) to consume its share of extra space. * The width of each child is set to its preferred width. * The return value is any extra space that's left over * after growing all children to their maxHeight. */ public static function flexChildHeightsProportionally(children:Array, configurations:Array, totalWidth:Number, totalHeight:Number):Number { var spaceToDistribute:Number = totalHeight; var totalPercentHeight:Number = 0; var childInfoArray:Array = []; // If the child is flexible, store information about it in the // childInfoArray. For non-flexible children, just set the child's // width and height immediately. // // Also calculate the sum of all percentHeights, and calculate the // sum of the height of all non-flexible children. var childCount:int = children.length; for(var i:int = 0; i < childCount; i++) { var child:DisplayObject = DisplayObject(children[i]); var config:Object = configurations[i]; if(!config.includeInLayout) { //skip children that aren't in the layout continue; } var percentWidth:Number = config.percentWidth; var percentHeight:Number = config.percentHeight; var width:Number = NaN; if(!isNaN(percentWidth)) { width = Math.max(config.minWidth, Math.min(config.maxWidth, ((percentWidth >= 100) ? totalWidth : totalWidth * percentWidth / 100))); } if(!isNaN(percentHeight)) { totalPercentHeight += percentHeight; var childInfo:ChildInfo = new ChildInfo(); childInfo.percent = percentHeight; childInfo.min = config.minHeight; childInfo.max = config.maxHeight; childInfo.opposite = width; childInfo.child = child; childInfoArray.push(childInfo); } else { if(child.scaleX == 1 && child.scaleY == 1) { if(!isNaN(width)) { child.width = Math.floor(width); } } else { if(!isNaN(width)) { child.width = width; } } // Need to account for the actual child height since // setActualSize may trigger a Resize effect, which // could change the size of the component. spaceToDistribute -= child.height; } } // Distribute the extra space among the children. if(totalPercentHeight) { spaceToDistribute = flexChildrenProportionally(totalHeight, spaceToDistribute, totalPercentHeight, childInfoArray); // Set the widths and heights of the flexible children childCount = childInfoArray.length; for(i = 0; i < childCount; i++) { childInfo = ChildInfo(childInfoArray[i]); child = childInfo.child; // if scaled and zoom is playing, best to let the sizes be non-integer // otherwise the rounding creates an error that accumulates in some components like List if(child.scaleX == 1 && child.scaleY == 1) { if(!isNaN(childInfo.opposite)) { child.width = Math.floor(childInfo.opposite); } child.height = Math.floor(childInfo.size); } else { if(!isNaN(childInfo.opposite)) { child.width = childInfo.opposite; } child.height = childInfo.size; } } distributeExtraHeight(children, configurations, totalHeight); } return spaceToDistribute; } /** * This function distributes excess space among the flexible children. * It does so with a view to keep the children's overall size * close the ratios specified by their percent. * * @param spaceForChildren The total space for all children * * @param spaceToDistribute The space that needs to be distributed * among the flexible children. * * @param childInfoArray An array of Objects. When this function * is called, each object should define the following properties: * - percent: the percentWidth or percentHeight of the child (depending * on whether we're growing in a horizontal or vertical direction) * - min: the minimum width (or height) for that child * - max: the maximum width (or height) for that child * * @return When this function finishes executing, a "size" property * will be defined for each child object. The size property contains * the portion of the spaceToDistribute to be distributed to the child. * Ideally, the sum of all size properties is spaceToDistribute. * If all the children hit their minWidth/maxWidth/minHeight/maxHeight * before the space was distributed, then the remaining unused space * is returned. Otherwise, the return value is zero. */ public static function flexChildrenProportionally(spaceForChildren:Number, spaceToDistribute:Number, totalPercent:Number, childInfoArray:Array):Number { // The algorithm iterivately attempts to break down the space that // is consumed by "flexible" containers into ratios that are related // to the percentWidth/percentHeight of the participating containers. var numChildren:int = childInfoArray.length; var flexConsumed:Number; // space consumed by flexible compontents var done:Boolean; // We now do something a little tricky so that we can // support partial filling of the space. If our total // percent < 100% then we can trim off some space. var unused:Number = spaceToDistribute - (spaceForChildren * totalPercent / 100); if(unused > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -