| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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.utils |
| { |
| import flash.display.DisplayObject; |
| import flash.display.DisplayObjectContainer; |
| import flash.display.Stage; |
| import flash.display.StageDisplayState; |
| import flash.geom.ColorTransform; |
| import flash.geom.Matrix; |
| import flash.geom.Point; |
| import flash.geom.Rectangle; |
| |
| import mx.core.IFlexDisplayObject; |
| import mx.core.ILayoutElement; |
| import mx.core.mx_internal; |
| import mx.managers.ISystemManager; |
| |
| use namespace mx_internal; |
| |
| [ExcludeClass] |
| |
| /** |
| * Helper functionality for working with pop-ups. |
| */ |
| public class PopUpUtil |
| { |
| |
| /** |
| * Calculates the position for a pop-up in sanboxRoot coordinates (the pop-up coordinate space). |
| * |
| * @param component The component that defines the component coordinate space. |
| * |
| * @param systemManager The systemManager that defines the SandboxRoot. Typically component.systemManager. |
| * |
| * @param popUpWidth The width of the popup, in SandboxRoot coordinates (i.e. popUp.width). |
| * |
| * @param popUpHeight The height of the popup, in SandboxRoot coordinates (i.e. popUp.height). |
| * |
| * @param verticalCenter The desired distance from the center of the popUp to the top edge of the |
| * component. In component coordinates. For example, to center relative to the |
| * component, pass component.heihgt / 2. To disable centering, pass NaN. |
| * |
| * @param popUpPosition The position of the pop-up, specified in SandboxRoot coordinates (i.e. pupUp.x, popUp.y) |
| * |
| * @param regPoint The position of the popUp, specified in the component's coordinate space. This is ignored if |
| * popUpPosition is specified. |
| * |
| * @param ensureOnScreen When true, will check against the visible screen of the application and adjust the position |
| * if necessary. |
| * |
| * @return The position of the pop-up in SandboxRoot coordinates. |
| */ |
| public static function positionOverComponent(component:DisplayObject, |
| systemManager:ISystemManager, // The component's systemManager |
| popUpWidth:Number, // in sandboxRoot coordinates |
| popUpHeight:Number, // in sandboxRoot coordinates |
| verticalCenter:Number = NaN, // in component coordinates, if NaN, it's ignored |
| popUpPosition:Point = null, // in sandboxRoot coordinates, if specified, regPoint is ignored |
| regPoint:Point = null, // in component coordinates, if not specified defaults to (0,0) |
| ensureOnScreen:Boolean = true):Point |
| { |
| // Original code: |
| // var toolTip:IToolTip = event.toolTip; |
| // |
| // // Calculate global position of label. |
| // var sm:ISystemManager = systemManager.topLevelSystemManager; |
| // var sbRoot:DisplayObject = sm.getSandboxRoot(); |
| // var screen:Rectangle = sm.getVisibleApplicationRect(null, true);; |
| // var pt:Point = new Point(0, 0); |
| // pt = label.localToGlobal(pt); |
| // pt = sbRoot.globalToLocal(pt); |
| // |
| // toolTip.move(pt.x, pt.y + (height - toolTip.height) / 2); |
| // |
| // var screenRight:Number = screen.x + screen.width; |
| // pt.x = toolTip.x; |
| // pt.y = toolTip.y; |
| // pt = sbRoot.localToGlobal(pt); |
| // if (pt.x + toolTip.width > screenRight) |
| // toolTip.move(toolTip.x - (pt.x + toolTip.width - screenRight), toolTip.y); |
| |
| // Refactored for correctness when there's scale in play: |
| |
| // var sm:ISystemManager = systemManager.topLevelSystemManager; |
| // var sbRoot:DisplayObject = sm.getSandboxRoot(); |
| // |
| // // Calculate sbRoot position of label. |
| // var pt:Point = new Point(0, 0); |
| // pt = sbRoot.globalToLocal(localToGlobal(pt)); // point in sbRoot coordinates |
| // |
| // // Screen in sbRoot cooridnates |
| // var screen:Rectangle = sm.getVisibleApplicationRect(null, true); |
| // var screenRight:Number = sbRoot.globalToLocal(screen.bottomRight).x; |
| // |
| // // Height in sbRoot coordinates |
| // var h:Number = sbRoot.globalToLocal(localToGlobal(new Point(0, height))).y; |
| // |
| // // Center vertically, make sure tooltip doesn't overlap right edge of the screen |
| // var x:Number = Math.min(pt.x, screenRight - toolTip.width); |
| // var y:Number = pt.y + (h - toolTip.height) / 2; |
| // toolTip.move(x, y); |
| |
| // Would translate to: |
| |
| // var toolTip:IToolTip = event.toolTip; |
| // var pt:Point = PopUpUtil.positionOverComponent(DisplayObject(label), |
| // systemManager, |
| // toolTip.width, |
| // toolTip.height, |
| // height / 2); |
| // toolTip.move(pt.x, pt.y); |
| |
| |
| var sm:ISystemManager = systemManager.topLevelSystemManager; |
| var sbRoot:DisplayObject = sm.getSandboxRoot(); |
| |
| // Find the position of the popup in sandboxRoot coordinates |
| var x:Number = 0; |
| var y:Number = 0; |
| |
| if (popUpPosition) |
| { |
| // Already in sandboxRoot coordinates |
| x = popUpPosition.x; |
| y = popUpPosition.y; |
| } |
| else |
| { |
| // If not specified, regPoint defaults to component's (0,0). |
| if (!regPoint) |
| regPoint = new Point(0, 0); |
| |
| // Convert to sandboxRoot coordinates |
| var position:Point = sbRoot.globalToLocal(component.localToGlobal(regPoint)); |
| x = position.x; |
| y = position.y; |
| } |
| |
| // Do we need to center vertically? |
| if (!isNaN(verticalCenter)) |
| { |
| // verticalCenter is in component coordinates, convert to sandboxRoot |
| var vc:Number = sbRoot.globalToLocal(component.localToGlobal(new Point(0, verticalCenter))).y; |
| y = vc - popUpHeight / 2; |
| } |
| |
| if (ensureOnScreen) |
| { |
| // Convert screen to sandboxRoot cooridnates |
| var screen:Rectangle = sm.getVisibleApplicationRect(null, true); |
| var topLeft:Point = sbRoot.globalToLocal(screen.topLeft); |
| var bottomRight:Point = sbRoot.globalToLocal(screen.bottomRight); |
| |
| // clamp position, don't round |
| x = Math.max(topLeft.x, Math.min(bottomRight.x - popUpWidth, x)); |
| y = Math.max(topLeft.y, Math.min(bottomRight.y - popUpHeight, y)); |
| } |
| |
| return new Point(x, y); |
| } |
| |
| /** |
| * Apply transforms from a popUp owner to the popUp. |
| * |
| * @param owner Pop-up owner |
| * @param systemManager The systemManager that defines the SandboxRoot. Typically component.systemManager. |
| * @param popUp The pop-up to apply the owner's transform to. |
| * @param popUpPoint Absolute position of the pop-up in the global coordinate space. |
| * @param colorTransform The owner's color transform |
| */ |
| public static function applyPopUpTransform(owner:DisplayObjectContainer, |
| colorTransform:ColorTransform, |
| systemManager:ISystemManager, |
| popUp:IFlexDisplayObject, |
| popUpPoint:Point):void |
| { |
| var m:Matrix = MatrixUtil.getConcatenatedMatrix(owner, systemManager.getSandboxRoot()); |
| |
| // the transformation doesn't take the fullScreenRect in to account |
| // if we are in fulLScreen mode. This code will throw a RTE if run from inside of a sandbox. |
| try |
| { |
| var smStage:Stage = systemManager.stage; |
| if (smStage && smStage.displayState != StageDisplayState.NORMAL && smStage.fullScreenSourceRect) |
| { |
| popUpPoint.x += smStage.fullScreenSourceRect.x; |
| popUpPoint.y += smStage.fullScreenSourceRect.y; |
| } |
| } |
| catch (e:Error) |
| { |
| // Ignore the RTE |
| } |
| |
| // Position the popUp. |
| m.tx = Math.round(popUpPoint.x); |
| m.ty = Math.round(popUpPoint.y); |
| if (popUp is ILayoutElement) |
| ILayoutElement(popUp).setLayoutMatrix(m,false); |
| else if (popUp is DisplayObject) |
| DisplayObject(popUp).transform.matrix = m; |
| |
| // apply the color transformation, but restore alpha value of popup |
| var oldAlpha:Number = DisplayObject(popUp).alpha; |
| var tmpColorTransform:ColorTransform = colorTransform; |
| if (tmpColorTransform != null) |
| { |
| tmpColorTransform.alphaMultiplier = oldAlpha; |
| tmpColorTransform.alphaOffset = 0; |
| DisplayObject(popUp).transform.colorTransform = tmpColorTransform; |
| } |
| |
| } |
| } |
| } |
| |