You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ma...@apache.org on 2013/10/08 02:29:18 UTC
[1/8] temp commit move experimental callout to spark
Updated Branches:
refs/heads/callout [created] 891df7581
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/components/ContentBackgroundAppearance.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/ContentBackgroundAppearance.as b/frameworks/projects/spark/src/spark/components/ContentBackgroundAppearance.as
new file mode 100644
index 0000000..13f0f0a
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/components/ContentBackgroundAppearance.as
@@ -0,0 +1,72 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.components
+{
+
+/**
+ * The ContentBackgroundAppearance class defines the constants for the
+ * allowed values of the <code>contentBackgroundAppearance</code> style of
+ * Callout.
+ *
+ * @see spark.components.Callout#style:contentBackgroundAppearance
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public final class ContentBackgroundAppearance
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Applies a shadow and mask to the contentGroup.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const INSET:String = "inset";
+
+ /**
+ * Applies mask to the contentGroup.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const FLAT:String = "flat";
+
+ /**
+ * Disables both the <code>contentBackgroundColor</code> style and
+ * contentGroup masking. Use this value when Callout's contents should
+ * appear directly on top of the <code>backgroundColor</code> or when
+ * contents provide their own masking.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const NONE:String = "none";
+}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/core/ContainerDestructionPolicy.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/core/ContainerDestructionPolicy.as b/frameworks/projects/spark/src/spark/core/ContainerDestructionPolicy.as
new file mode 100644
index 0000000..2ae91f1
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/core/ContainerDestructionPolicy.as
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.core
+{
+/**
+ * The ContainerCreationPolicy class defines the constant values
+ * for the <code>destructionPolicy</code> property of spark view
+ * classes.
+ *
+ * @see spark.components.supportClasses.ViewNavigatorBase#destructionPolicy
+ * @see spark.components.View#destructionPolicy
+ *
+ * @langversion 3.0
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+public final class ContainerDestructionPolicy
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * The lifespan of the container's children is automatically
+ * managed by the container based on the container's own
+ * heuristic.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public static const AUTO:String = "auto";
+
+ /**
+ * The container never destroys its children.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public static const NEVER:String = "never";
+}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/spark-manifest.xml
----------------------------------------------------------------------
diff --git a/frameworks/spark-manifest.xml b/frameworks/spark-manifest.xml
index 5574a7d..5ae7f02 100644
--- a/frameworks/spark-manifest.xml
+++ b/frameworks/spark-manifest.xml
@@ -53,6 +53,8 @@
<component id="ButtonBarHorizontalLayout" class="spark.components.supportClasses.ButtonBarHorizontalLayout"/>
<component id="ButtonBase" class="spark.components.supportClasses.ButtonBase"/>
<component id="CallAction" class="spark.effects.CallAction"/>
+ <component id="Callout" class="spark.components.Callout"/>
+ <component id="CalloutButton" class="spark.components.CalloutButton"/>
<component id="CellPosition" class="spark.components.gridClasses.CellPosition"/>
<component id="CellRegion" class="spark.components.gridClasses.CellRegion"/>
<component id="CheckBox" class="spark.components.CheckBox"/>
[6/8] FIXED https://issues.apache.org/jira/browse/FLEX-33350 - mobile
Callout moved to spark - Added borderColor and borderThickness styles to
Callout - Desktop & Mobile Callout uses same s:Callout - MobileSkin
refactored - new ActionScriptSkinBase cl
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/skins/spark/CalloutSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/skins/spark/CalloutSkin.as b/frameworks/projects/spark/src/spark/skins/spark/CalloutSkin.as
new file mode 100644
index 0000000..d3b1357
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/skins/spark/CalloutSkin.as
@@ -0,0 +1,743 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.skins.spark
+{
+
+import flash.display.BlendMode;
+import flash.display.GradientType;
+import flash.display.Graphics;
+import flash.display.Sprite;
+import flash.events.Event;
+
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+import mx.events.EffectEvent;
+import mx.events.FlexEvent;
+import mx.utils.ColorUtil;
+
+import spark.components.ArrowDirection;
+import spark.components.Callout;
+import spark.components.ContentBackgroundAppearance;
+import spark.components.Group;
+import spark.core.SpriteVisualElement;
+import spark.effects.Fade;
+import spark.primitives.RectangularDropShadow;
+import spark.skins.ActionScriptSkinBase;
+import spark.skins.spark.assets.CalloutContentBackground;
+import spark.skins.spark.supportClasses.CalloutArrow;
+
+
+use namespace mx_internal;
+
+/**
+ * The default skin class for the Spark Callout component in mobile
+ * applications.
+ *
+ * <p>The <code>contentGroup</code> lies above a <code>backgroundColor</code> fill
+ * which frames the <code>contentGroup</code>. The position and size of the frame
+ * adjust based on the host component <code>arrowDirection</code>, leaving
+ * space for the <code>arrow</code> to appear on the outside edge of the
+ * frame.</p>
+ *
+ * <p>The <code>arrow</code> skin part is not positioned by the skin. Instead,
+ * the Callout component positions the arrow relative to the owner in
+ * <code>updateSkinDisplayList()</code>. This method assumes that Callout skin
+ * and the <code>arrow</code> use the same coordinate space.</p>
+ *
+ * @see spark.components.Callout
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public class CalloutSkin extends ActionScriptSkinBase
+{
+ mx_internal static const BACKGROUND_GRADIENT_BRIGHTNESS_TOP:int = 15;
+
+ mx_internal static const BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM:int = -60;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function CalloutSkin()
+ {
+ super();
+
+ dropShadowAlpha = 0.7;
+
+ // default DPI_160
+ backgroundCornerRadius = 6;
+ contentBackgroundInsetClass = CalloutContentBackground;
+ backgroundGradientHeight = 83;
+ frameThickness = 6;
+ arrowWidth = 26;
+ arrowHeight = 13;
+ contentCornerRadius = 4;
+ dropShadowBlurX = 12;
+ dropShadowBlurY = 12;
+ dropShadowDistance = 2;
+ highlightWeight = 0.5;
+
+ /*
+ backgroundCornerRadius = 8;
+ contentBackgroundInsetClass = CalloutContentBackground;
+ backgroundGradientHeight = 110;
+ frameThickness = 6;
+ arrowWidth = 26;
+ arrowHeight = 13;
+ contentCornerRadius = 5;
+ dropShadowBlurX = 16;
+ dropShadowBlurY = 16;
+ dropShadowDistance = 3;
+ highlightWeight = 1;
+ */
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @copy spark.skins.spark.ApplicationSkin#hostComponent
+ */
+ public var hostComponent:Callout;
+
+ /**
+ * Enables a RectangularDropShadow behind the <code>backgroundColor</code> frame.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var dropShadowVisible:Boolean = true;
+
+ /**
+ * Enables a vertical linear gradient in the <code>backgroundColor</code> frame. This
+ * gradient fill is drawn across both the arrow and the frame. By default,
+ * the gradient brightens the background color by 15% and darkens it by 60%.
+ *
+ * @default true
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var useBackgroundGradient:Boolean = true;
+
+ /**
+ * Corner radius used for the <code>contentBackgroundColor</code> fill.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var contentCornerRadius:uint;
+
+ /**
+ * A class reference to an FXG class that is layered underneath the
+ * <code>contentGroup</code>. The instance of this class is sized to match the
+ * <code>contentGroup</code>.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var contentBackgroundInsetClass:Class;
+
+ /**
+ * Corner radius of the <code>backgroundColor</code> "frame".
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var backgroundCornerRadius:Number;
+
+ /**
+ * The thickness of the <code>backgroundColor</code> "frame" that surrounds the
+ * <code>contentGroup</code>.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var frameThickness:Number;
+
+ /**
+ * Color of the border stroke around the <code>backgroundColor</code> "frame".
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ mx_internal var borderColor:uint = 0;
+
+ /**
+ * Thickness of the border stroke around the <code>backgroundColor</code>
+ * "frame".
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ mx_internal var borderThickness:Number = NaN;
+
+ /**
+ * Width of the arrow in vertical directions. This property also controls
+ * the height of the arrow in horizontal directions.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var arrowWidth:Number;
+
+ /**
+ * Height of the arrow in vertical directions. This property also controls
+ * the width of the arrow in horizontal directions.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var arrowHeight:Number;
+
+ /**
+ * @private
+ * Instance of the contentBackgroundClass
+ */
+ mx_internal var contentBackgroundGraphic:SpriteVisualElement;
+
+ /**
+ * @private
+ * Tracks changes to the skin state to support the fade out tranisition
+ * when closed;
+ */
+ mx_internal var isOpen:Boolean;
+
+ private var backgroundGradientHeight:Number;
+
+ private var contentMask:Sprite;
+
+ private var backgroundFill:SpriteVisualElement;
+
+ private var dropShadow:RectangularDropShadow;
+
+ private var dropShadowBlurX:Number;
+
+ private var dropShadowBlurY:Number;
+
+ private var dropShadowDistance:Number;
+
+ private var dropShadowAlpha:Number;
+
+ private var fade:Fade;
+
+ private var highlightWeight:Number;
+
+ //--------------------------------------------------------------------------
+ //
+ // Skin parts
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @copy spark.components.SkinnableContainer#contentGroup
+ */
+ public var contentGroup:Group;
+
+ /**
+ * @copy spark.components.Callout#arrow
+ */
+ public var arrow:UIComponent;
+
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ override protected function createChildren():void
+ {
+ super.createChildren();
+
+ if (dropShadowVisible)
+ {
+ dropShadow = new RectangularDropShadow();
+ dropShadow.angle = 90;
+ dropShadow.distance = dropShadowDistance;
+ dropShadow.blurX = dropShadowBlurX;
+ dropShadow.blurY = dropShadowBlurY;
+ dropShadow.tlRadius = dropShadow.trRadius = dropShadow.blRadius =
+ dropShadow.brRadius = backgroundCornerRadius;
+ dropShadow.mouseEnabled = false;
+ dropShadow.alpha = dropShadowAlpha;
+ addChild(dropShadow);
+ }
+
+ // background fill placed above the drop shadow
+ backgroundFill = new SpriteVisualElement();
+ addChild(backgroundFill);
+
+ // arrow
+ if (!arrow)
+ {
+ arrow = new CalloutArrow();
+ arrow.id = "arrow";
+ arrow.styleName = this;
+ addChild(arrow);
+ }
+
+ // contentGroup
+ if (!contentGroup)
+ {
+ contentGroup = new Group();
+ contentGroup.id = "contentGroup";
+ addChild(contentGroup);
+ }
+
+ borderThickness = getStyle("borderThickness");
+ borderColor = getStyle("borderColor");
+
+ }
+
+ /**
+ * @private
+ */
+ override protected function commitProperties():void
+ {
+ super.commitProperties();
+
+ // add or remove the contentBackgroundGraphic
+ var contentBackgroundAppearance:String = getStyle("contentBackgroundAppearance");
+
+ if (contentBackgroundAppearance == ContentBackgroundAppearance.INSET)
+ {
+ // create the contentBackgroundGraphic
+ if (!contentBackgroundGraphic && contentBackgroundInsetClass)
+ {
+ contentBackgroundGraphic = new contentBackgroundInsetClass() as SpriteVisualElement;
+
+ // with the current skin structure, contentBackgroundGraphic is
+ // always the last child
+ addChild(contentBackgroundGraphic);
+ }
+ }
+ else if (contentBackgroundGraphic)
+ {
+ // if already created, remove the graphic for "flat" and "none"
+ removeChild(contentBackgroundGraphic);
+ contentBackgroundGraphic = null;
+ }
+
+ // always invalidate to accomodate arrow direction changes
+ invalidateSize();
+ invalidateDisplayList();
+ }
+
+ /**
+ * @private
+ */
+ override protected function measure():void
+ {
+ super.measure();
+
+ var borderWeight:Number = isNaN(borderThickness) ? 0 : borderThickness;
+ var frameAdjustment:Number = (frameThickness + borderWeight) * 2;
+
+ var arrowMeasuredWidth:Number;
+ var arrowMeasuredHeight:Number;
+
+ // pad the arrow so that the edges are within the background corner radius
+ if (isArrowHorizontal)
+ {
+ arrowMeasuredWidth = arrowHeight;
+ arrowMeasuredHeight = arrowWidth + (backgroundCornerRadius * 2);
+ }
+ else if (isArrowVertical)
+ {
+ arrowMeasuredWidth = arrowWidth + (backgroundCornerRadius * 2);
+ arrowMeasuredHeight = arrowHeight;
+ }
+
+ // count the contentGroup size and frame size
+ measuredMinWidth = contentGroup.measuredMinWidth + frameAdjustment;
+ measuredMinHeight = contentGroup.measuredMinHeight + frameAdjustment;
+
+ measuredWidth = contentGroup.getPreferredBoundsWidth() + frameAdjustment;
+ measuredHeight = contentGroup.getPreferredBoundsHeight() + frameAdjustment;
+
+ // add the arrow size based on the arrowDirection
+ if (isArrowHorizontal)
+ {
+ measuredMinWidth += arrowMeasuredWidth;
+ measuredMinHeight = Math.max(measuredMinHeight, arrowMeasuredHeight);
+
+ measuredWidth += arrowMeasuredWidth;
+ measuredHeight = Math.max(measuredHeight, arrowMeasuredHeight);
+ }
+ else if (isArrowVertical)
+ {
+ measuredMinWidth += Math.max(measuredMinWidth, arrowMeasuredWidth);
+ measuredMinHeight += arrowMeasuredHeight;
+
+ measuredWidth = Math.max(measuredWidth, arrowMeasuredWidth);
+ measuredHeight += arrowMeasuredHeight;
+ }
+ }
+
+ /**
+ * @private
+ * SkinnaablePopUpContainer skins must dispatch a
+ * FlexEvent.STATE_CHANGE_COMPLETE event for the component to properly
+ * update the skin state.
+ */
+ override protected function commitCurrentState():void
+ {
+ super.commitCurrentState();
+
+ var isNormal:Boolean = (currentState == "normal");
+ var isDisabled:Boolean = (currentState == "disabled")
+
+ // play a fade out if the callout was previously open
+ if (!(isNormal || isDisabled) && isOpen)
+ {
+ if (!fade)
+ {
+ fade = new Fade();
+ fade.target = this;
+ fade.duration = 200;
+ fade.alphaTo = 0;
+ }
+
+ // BlendMode.LAYER while fading out
+ blendMode = BlendMode.LAYER;
+
+ // play a short fade effect
+ fade.addEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
+ fade.play();
+
+ isOpen = false;
+ }
+ else
+ {
+ isOpen = isNormal || isDisabled;
+
+ // handle re-opening the Callout while fading out
+ if (fade && fade.isPlaying)
+ {
+ // Do not dispatch a state change complete.
+ // SkinnablePopUpContainer handles state interruptions.
+ fade.removeEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
+ fade.stop();
+ }
+
+ if (isDisabled)
+ {
+ // BlendMode.LAYER to allow CalloutArrow BlendMode.ERASE
+ blendMode = BlendMode.LAYER;
+
+ alpha = 0.5;
+ }
+ else
+ {
+ // BlendMode.NORMAL for non-animated state transitions
+ blendMode = BlendMode.NORMAL;
+
+ if (isNormal)
+ alpha = 1;
+ else
+ alpha = 0;
+ }
+
+ stateChangeComplete();
+ }
+ }
+
+ /**
+ * @private
+ */
+ override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ super.drawBackground(unscaledWidth, unscaledHeight);
+
+ var frameEllipseSize:Number = backgroundCornerRadius * 2;
+
+ // account for borderThickness center stroke alignment
+ var showBorder:Boolean = !isNaN(borderThickness);
+ var borderWeight:Number = showBorder ? borderThickness : 0;
+
+ // contentBackgroundGraphic already accounts for the arrow position
+ // use it's positioning instead of recalculating based on unscaledWidth
+ // and unscaledHeight
+ var frameX:Number = Math.floor(contentGroup.getLayoutBoundsX() - frameThickness) - (borderWeight / 2);
+ var frameY:Number = Math.floor(contentGroup.getLayoutBoundsY() - frameThickness) - (borderWeight / 2);
+ var frameWidth:Number = contentGroup.getLayoutBoundsWidth() + (frameThickness * 2) + borderWeight;
+ var frameHeight:Number = contentGroup.getLayoutBoundsHeight() + (frameThickness * 2) + borderWeight;
+
+ var backgroundColor:Number = getStyle("backgroundColor");
+ var backgroundAlpha:Number = getStyle("backgroundAlpha");
+
+ var bgFill:Graphics = backgroundFill.graphics;
+ bgFill.clear();
+
+ if (showBorder)
+ bgFill.lineStyle(borderThickness, borderColor, 1, true);
+
+ if (useBackgroundGradient)
+ {
+ // top color is brighter if arrowDirection == ArrowDirection.UP
+ var backgroundColorTop:Number = ColorUtil.adjustBrightness2(backgroundColor,
+ BACKGROUND_GRADIENT_BRIGHTNESS_TOP);
+ var backgroundColorBottom:Number = ColorUtil.adjustBrightness2(backgroundColor,
+ BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM);
+
+ // max gradient height = backgroundGradientHeight
+ colorMatrix.createGradientBox(unscaledWidth, backgroundGradientHeight,
+ Math.PI / 2, 0, 0);
+
+ bgFill.beginGradientFill(GradientType.LINEAR,
+ [backgroundColorTop, backgroundColorBottom],
+ [backgroundAlpha, backgroundAlpha],
+ [0, 255],
+ colorMatrix);
+ }
+ else
+ {
+ bgFill.beginFill(backgroundColor, backgroundAlpha);
+ }
+
+ bgFill.drawRoundRect(frameX, frameY, frameWidth,
+ frameHeight, frameEllipseSize, frameEllipseSize);
+ bgFill.endFill();
+
+ // draw content background styles
+ var contentBackgroundAppearance:String = getStyle("contentBackgroundAppearance");
+
+ if (contentBackgroundAppearance != ContentBackgroundAppearance.NONE)
+ {
+ var contentEllipseSize:Number = contentCornerRadius * 2;
+ var contentBackgroundAlpha:Number = getStyle("contentBackgroundAlpha");
+ var contentWidth:Number = contentGroup.getLayoutBoundsWidth();
+ var contentHeight:Number = contentGroup.getLayoutBoundsHeight();
+
+ // all appearance values except for "none" use a mask
+ if (!contentMask)
+ contentMask = new SpriteVisualElement();
+
+ contentGroup.mask = contentMask;
+
+ // draw contentMask in contentGroup coordinate space
+ var maskGraphics:Graphics = contentMask.graphics;
+ maskGraphics.clear();
+ maskGraphics.beginFill(0, 1);
+ maskGraphics.drawRoundRect(0, 0, contentWidth, contentHeight,
+ contentEllipseSize, contentEllipseSize);
+ maskGraphics.endFill();
+
+ // reset line style to none
+ if (showBorder)
+ bgFill.lineStyle(NaN);
+
+ // draw the contentBackgroundColor
+ bgFill.beginFill(getStyle("contentBackgroundColor"),
+ contentBackgroundAlpha);
+ bgFill.drawRoundRect(contentGroup.getLayoutBoundsX(),
+ contentGroup.getLayoutBoundsY(),
+ contentWidth, contentHeight, contentEllipseSize, contentEllipseSize);
+ bgFill.endFill();
+
+ if (contentBackgroundGraphic)
+ contentBackgroundGraphic.alpha = contentBackgroundAlpha;
+ }
+ else // if (contentBackgroundAppearance == CalloutContentBackgroundAppearance.NONE))
+ {
+ // remove the mask
+ if (contentMask)
+ {
+ contentGroup.mask = null;
+ contentMask = null;
+ }
+ }
+
+ // draw highlight in the callout when the arrow is hidden
+ if (useBackgroundGradient && !isArrowHorizontal && !isArrowVertical)
+ {
+ // highlight width spans the callout width minus the corner radius
+ var highlightWidth:Number = frameWidth - frameEllipseSize;
+ var highlightX:Number = frameX + backgroundCornerRadius;
+ var highlightOffset:Number = (highlightWeight * 1.5);
+
+ // straight line across the top
+ bgFill.lineStyle(highlightWeight, 0xFFFFFF, 0.2 * backgroundAlpha);
+ bgFill.moveTo(highlightX, highlightOffset);
+ bgFill.lineTo(highlightX + highlightWidth, highlightOffset);
+ }
+ }
+
+ /**
+ * @private
+ */
+ override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ super.layoutContents(unscaledWidth, unscaledHeight);
+
+ // pad the arrow so that the edges are within the background corner radius
+ if (isArrowHorizontal)
+ {
+ arrow.width = arrowHeight;
+ arrow.height = arrowWidth + (backgroundCornerRadius * 2);
+ }
+ else if (isArrowVertical)
+ {
+ arrow.width = arrowWidth + (backgroundCornerRadius * 2);
+ arrow.height = arrowHeight;
+ }
+
+ setElementSize(backgroundFill, unscaledWidth, unscaledHeight);
+ setElementPosition(backgroundFill, 0, 0);
+
+ var frameX:Number = 0;
+ var frameY:Number = 0;
+ var frameWidth:Number = unscaledWidth;
+ var frameHeight:Number = unscaledHeight;
+
+ switch (hostComponent.arrowDirection)
+ {
+ case ArrowDirection.UP:
+ frameY = arrow.height;
+ frameHeight -= arrow.height;
+ break;
+ case ArrowDirection.DOWN:
+ frameHeight -= arrow.height;
+ break;
+ case ArrowDirection.LEFT:
+ frameX = arrow.width;
+ frameWidth -= arrow.width;
+ break;
+ case ArrowDirection.RIGHT:
+ frameWidth -= arrow.width;
+ break;
+ default:
+ // no arrow, content takes all available space
+ break;
+ }
+
+ if (dropShadow)
+ {
+ setElementSize(dropShadow, frameWidth, frameHeight);
+ setElementPosition(dropShadow, frameX, frameY);
+ }
+
+ // Show frameThickness by inset of contentGroup
+ var borderWeight:Number = isNaN(borderThickness) ? 0 : borderThickness;
+ var contentBackgroundAdjustment:Number = frameThickness + borderWeight;
+
+ var contentBackgroundX:Number = frameX + contentBackgroundAdjustment;
+ var contentBackgroundY:Number = frameY + contentBackgroundAdjustment;
+
+ contentBackgroundAdjustment = contentBackgroundAdjustment * 2;
+ var contentBackgroundWidth:Number = frameWidth - contentBackgroundAdjustment;
+ var contentBackgroundHeight:Number = frameHeight - contentBackgroundAdjustment;
+
+ if (contentBackgroundGraphic)
+ {
+ setElementSize(contentBackgroundGraphic, contentBackgroundWidth, contentBackgroundHeight);
+ setElementPosition(contentBackgroundGraphic, contentBackgroundX, contentBackgroundY);
+ }
+
+ setElementSize(contentGroup, contentBackgroundWidth, contentBackgroundHeight);
+ setElementPosition(contentGroup, contentBackgroundX, contentBackgroundY);
+
+ // mask position is in the contentGroup coordinate space
+ if (contentMask)
+ setElementSize(contentMask, contentBackgroundWidth, contentBackgroundHeight);
+ }
+
+ override public function styleChanged(styleProp:String):void
+ {
+ super.styleChanged(styleProp);
+
+ var allStyles:Boolean = !styleProp || styleProp == "styleName";
+
+ if (allStyles || (styleProp == "contentBackgroundAppearance"))
+ invalidateProperties();
+
+ if (allStyles || (styleProp == "backgroundAlpha"))
+ {
+ var backgroundAlpha:Number = getStyle("backgroundAlpha");
+
+ // Use BlendMode.LAYER to allow CalloutArrow to erase the dropShadow
+ // when the Callout background is transparent
+ blendMode = (backgroundAlpha < 1) ? BlendMode.LAYER : BlendMode.NORMAL;
+ }
+
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function get isArrowHorizontal():Boolean
+ {
+ return (hostComponent.arrowDirection == ArrowDirection.LEFT
+ || hostComponent.arrowDirection == ArrowDirection.RIGHT);
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function get isArrowVertical():Boolean
+ {
+ return (hostComponent.arrowDirection == ArrowDirection.UP
+ || hostComponent.arrowDirection == ArrowDirection.DOWN);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Event handlers
+ //
+ //--------------------------------------------------------------------------
+
+ private function stateChangeComplete(event:Event=null):void
+ {
+ if (fade && event)
+ fade.removeEventListener(EffectEvent.EFFECT_END, stateChangeComplete);
+
+ // SkinnablePopUpContainer relies on state changes for open and close
+ dispatchEvent(new FlexEvent(FlexEvent.STATE_CHANGE_COMPLETE));
+ }
+}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/skins/spark/assets/CalloutContentBackground.fxg
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/skins/spark/assets/CalloutContentBackground.fxg b/frameworks/projects/spark/src/spark/skins/spark/assets/CalloutContentBackground.fxg
new file mode 100644
index 0000000..8442b96
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/skins/spark/assets/CalloutContentBackground.fxg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+
+<Graphic version="2.0" xmlns="http://ns.adobe.com/fxg/2008"
+ scaleGridLeft="12" scaleGridRight="588" scaleGridTop="30" scaleGridBottom="388">
+
+ <!-- invisible fix for scaling -->
+ <Rect x="0" y="399" width="600" height="1">
+ <fill>
+ <SolidColor color="#ffffff" alpha="0"/>
+ </fill>
+ </Rect>
+
+ <!-- Content Shading Top -->
+ <Rect x="0" y="0" width="600" height="20"
+ topLeftRadiusX="10" topLeftRadiusY="10"
+ topRightRadiusX="10" topRightRadiusY="10">
+ <fill>
+ <LinearGradient rotation="90">
+ <GradientEntry ratio="0" color="#000000" alpha="0.6"/>
+ <GradientEntry ratio="0.5" color="#000000" alpha="0"/>
+ </LinearGradient>
+ </fill>
+ </Rect>
+
+ <!-- Content Highlight -->
+ <Rect x="1" y="1" width="598" height="398"
+ radiusX="10" radiusY="10">
+ <stroke>
+ <SolidColorStroke color="#FFFFFF" alpha="0.8"
+ weight="2"/>
+ </stroke>
+ </Rect>
+</Graphic>
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/skins/spark/supportClasses/CalloutArrow.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/skins/spark/supportClasses/CalloutArrow.as b/frameworks/projects/spark/src/spark/skins/spark/supportClasses/CalloutArrow.as
new file mode 100644
index 0000000..825fd1e
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/skins/spark/supportClasses/CalloutArrow.as
@@ -0,0 +1,423 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.skins.spark.supportClasses
+{
+import flash.display.BlendMode;
+import flash.display.GradientType;
+import flash.display.Graphics;
+import flash.display.GraphicsPathCommand;
+import flash.display.Sprite;
+
+import mx.core.DPIClassification;
+import mx.core.FlexGlobals;
+import mx.core.IVisualElement;
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+import mx.utils.ColorUtil;
+
+import spark.components.Application;
+import spark.components.ArrowDirection;
+import spark.components.Callout;
+import spark.skins.ActionScriptSkinBase;
+import spark.skins.spark.CalloutSkin;
+
+use namespace mx_internal;
+
+/**
+ * The arrow skin part for CalloutSkin.
+ *
+ * @see spark.skin.mobile.CalloutSkin
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public class CalloutArrow extends UIComponent
+{
+ public function CalloutArrow()
+ {
+ super();
+
+ useBackgroundGradient = true;
+
+ var applicationDPI:Number = Application(FlexGlobals.topLevelApplication).applicationDPI;
+
+ // Copy DPI-specific values from CalloutSkin
+ switch (applicationDPI)
+ {
+ case DPIClassification.DPI_320:
+ {
+ // Note provisional may need changes
+ gap = 32;
+ backgroundGradientHeight = 440;
+ highlightWeight = 4;
+
+ break;
+ }
+ case DPIClassification.DPI_480:
+ {
+ // Note provisional may need changes
+ gap = 24;
+ backgroundGradientHeight = 330;
+ highlightWeight = 3;
+
+ break;
+ }
+ case DPIClassification.DPI_320:
+ {
+ gap = 16;
+ backgroundGradientHeight = 220;
+ highlightWeight = 2;
+
+ break;
+ }
+ case DPIClassification.DPI_240:
+ {
+ gap = 12;
+ backgroundGradientHeight = 165;
+ highlightWeight = 1;
+
+ break;
+ }
+ case DPIClassification.DPI_120:
+ {
+ // Note provisional may need changes
+ gap = 6;
+ backgroundGradientHeight = 83;
+ highlightWeight = 1;
+
+ break;
+ }
+ default:
+ {
+ // default DPI_160
+ gap = 8;
+ backgroundGradientHeight = 110;
+ highlightWeight = 1;
+
+ break;
+ }
+ }
+ }
+
+ /**
+ * A gap on the frame-adjacent side of the arrow graphic to avoid
+ * drawing past the CalloutSkin backgroundCornerRadius.
+ *
+ * <p>The default implementation matches the gap value with the
+ * <code>backgroundCornerRadius</code> value in <code>CalloutSkin</code>.</p>
+ *
+ * @see spark.skins.mobile.CalloutSkin#backgroundCornerRadius
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected var gap:Number;
+ /**
+ * @copy spark.skins.mobile.CalloutSkin#backgroundGradientHeight
+ */
+ protected var backgroundGradientHeight:Number;
+ /**
+ * @copy spark.skins.mobile.CalloutSkin#useBackgroundGradient
+ */
+ protected var useBackgroundGradient:Boolean;
+ /**
+ * @copy spark.skins.mobile.CalloutSkin#highlightWeight
+ */
+ private var highlightWeight:Number;
+ /**
+ * @private
+ * A sibling of the arrow used to erase the drop shadow in CalloutSkin
+ */
+ private var eraseFill:Sprite;
+
+ /**
+ * @private
+ */
+ override protected function createChildren():void
+ {
+ super.createChildren();
+
+ // eraseFill has the same position and arrow shape in order to erase
+ // the drop shadow under the arrow when backgroundAlpha < 1
+ eraseFill = new Sprite();
+ eraseFill.blendMode = BlendMode.ERASE;
+
+ // layer eraseFill below the arrow
+ parent.addChildAt(eraseFill, parent.getChildIndex(this));
+ }
+
+ /**
+ * @private
+ */
+ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+ graphics.clear();
+ eraseFill.graphics.clear();
+
+ var calloutSkin:Object = parent;
+ var hostComponent:Callout = calloutSkin.hostComponent;
+ var arrowDirection:String = hostComponent.arrowDirection;
+
+ if (arrowDirection == ArrowDirection.NONE)
+ return;
+
+ // when drawing the arrow, compensate for cornerRadius via padding
+ var arrowGraphics:Graphics = this.graphics;
+ var eraseGraphics:Graphics = eraseFill.graphics;
+ var arrowWidth:Number = unscaledWidth;
+ var arrowHeight:Number = unscaledHeight;
+ var arrowX:Number = 0;
+ var arrowY:Number = 0;
+ var arrowTipX:Number = 0;
+ var arrowTipY:Number = 0;
+ var arrowEndX:Number = 0;
+ var arrowEndY:Number = 0;
+
+ var borderThickness:Number = hostComponent.getStyle("borderThickness"); // does not inherit
+ var borderColor:uint = hostComponent.getStyle("borderColor"); // does not inherit
+ var showBorder:Boolean = !isNaN(borderThickness) && borderThickness > 0;
+ var borderWeight:Number = showBorder ? borderThickness : 0;
+
+ var borderHalf:Number = borderWeight / 2;
+ var isHorizontal:Boolean = false;
+
+ if ((arrowDirection == ArrowDirection.LEFT) ||
+ (arrowDirection == ArrowDirection.RIGHT))
+ {
+ isHorizontal = true;
+
+ arrowX = -borderHalf;
+ arrowY = gap;
+ arrowHeight = arrowHeight - (gap * 2);
+
+ arrowTipX = arrowWidth - borderHalf;
+ arrowTipY = arrowY + (arrowHeight / 2);
+
+ arrowEndX = arrowX;
+ arrowEndY = arrowY + arrowHeight;
+
+ // flip coordinates to point left
+ if (arrowDirection == ArrowDirection.LEFT)
+ {
+ arrowX = arrowWidth - arrowX;
+ arrowTipX = arrowWidth - arrowTipX;
+ arrowEndX = arrowWidth - arrowEndX;
+ }
+ }
+ else
+ {
+ arrowX = gap;
+ arrowY = -borderHalf;
+ arrowWidth = arrowWidth - (gap * 2);
+
+ arrowTipX = arrowX + (arrowWidth / 2);
+ arrowTipY = arrowHeight - borderHalf;
+
+ arrowEndX = arrowX + arrowWidth;
+ arrowEndY = arrowY;
+
+ // flip coordinates to point up
+ if (hostComponent.arrowDirection == ArrowDirection.UP)
+ {
+ arrowY = arrowHeight - arrowY;
+ arrowTipY = arrowHeight - arrowTipY;
+ arrowEndY = arrowHeight - arrowEndY;
+ }
+ }
+
+ var commands:Vector.<int> = new Vector.<int>(3, true);
+ commands[0] = GraphicsPathCommand.MOVE_TO;
+ commands[1] = GraphicsPathCommand.LINE_TO;
+ commands[2] = GraphicsPathCommand.LINE_TO;
+
+ var coords:Vector.<Number> = new Vector.<Number>(6, true);
+ coords[0] = arrowX;
+ coords[1] = arrowY;
+ coords[2] = arrowTipX
+ coords[3] = arrowTipY;
+ coords[4] = arrowEndX
+ coords[5] = arrowEndY;
+
+ var backgroundColor:Number = getStyle("backgroundColor");
+ var backgroundAlpha:Number = getStyle("backgroundAlpha");
+
+ if (useBackgroundGradient)
+ {
+ var backgroundColorTop:Number = ColorUtil.adjustBrightness2(backgroundColor,
+ CalloutSkin.BACKGROUND_GRADIENT_BRIGHTNESS_TOP);
+ var backgroundColorBottom:Number = ColorUtil.adjustBrightness2(backgroundColor,
+ CalloutSkin.BACKGROUND_GRADIENT_BRIGHTNESS_BOTTOM);
+
+ // translate the gradient based on the arrow position
+ ActionScriptSkinBase.colorMatrix.createGradientBox(unscaledWidth,
+ backgroundGradientHeight, Math.PI / 2, 0, -getLayoutBoundsY());
+
+ arrowGraphics.beginGradientFill(GradientType.LINEAR,
+ [backgroundColorTop, backgroundColorBottom],
+ [backgroundAlpha, backgroundAlpha],
+ [0, 255],
+ ActionScriptSkinBase.colorMatrix);
+ }
+ else
+ {
+ arrowGraphics.beginFill(backgroundColor, backgroundAlpha);
+ }
+
+ // cover the adjacent border from the callout frame
+ if (showBorder)
+ {
+ var coverX:Number = 0;
+ var coverY:Number = 0;
+ var coverWidth:Number = 0;
+ var coverHeight:Number = 0;
+
+ switch (arrowDirection)
+ {
+ case ArrowDirection.UP:
+ {
+ coverX = arrowX;
+ coverY = arrowY;
+ coverWidth = arrowWidth;
+ coverHeight = borderWeight;
+ break;
+ }
+ case ArrowDirection.DOWN:
+ {
+ coverX = arrowX;
+ coverY = -borderWeight;
+ coverWidth = arrowWidth;
+ coverHeight = borderWeight;
+ break;
+ }
+ case ArrowDirection.LEFT:
+ {
+ coverX = arrowX;
+ coverY = arrowY;
+ coverWidth = borderWeight;
+ coverHeight = arrowHeight;
+ break;
+ }
+ case ArrowDirection.RIGHT:
+ {
+ coverX = -borderWeight;
+ coverY = arrowY;
+ coverWidth = borderWeight;
+ coverHeight = arrowHeight;
+ break;
+ }
+ }
+
+ arrowGraphics.drawRect(coverX, coverY, coverWidth, coverHeight);
+ }
+
+ // erase the drop shadow from the CalloutSkin
+ if (backgroundAlpha < 1)
+ {
+ // move eraseFill to the same position as the arrow
+ eraseFill.x = getLayoutBoundsX()
+ eraseFill.y = getLayoutBoundsY();
+
+ // draw the arrow shape
+ eraseGraphics.beginFill(0, 1);
+ eraseGraphics.drawPath(commands, coords);
+ eraseGraphics.endFill();
+ }
+
+ // draw arrow path
+ if (showBorder)
+ {
+ arrowGraphics.lineStyle(borderThickness, borderColor, 1, true);
+ }
+
+
+ arrowGraphics.drawPath(commands, coords);
+ arrowGraphics.endFill();
+
+ // adjust the highlight position to the origin of the callout
+ var isArrowUp:Boolean = (arrowDirection == ArrowDirection.UP);
+ var offsetY:Number = (isArrowUp) ? unscaledHeight : -getLayoutBoundsY();
+
+ // highlight starts after the backgroundCornerRadius
+ var highlightX:Number = gap - getLayoutBoundsX();
+
+ // highlight Y position is based on the stroke weight
+ var highlightOffset:Number = (highlightWeight * 1.5);
+ var highlightY:Number = highlightOffset + offsetY;
+
+ // highlight width spans the callout width minus the corner radius
+ var highlightWidth:Number = IVisualElement(calloutSkin).getLayoutBoundsWidth() - (gap * 2);
+
+ if (isHorizontal)
+ {
+ highlightWidth -= arrowWidth;
+
+ if (arrowDirection == ArrowDirection.LEFT)
+ highlightX += arrowWidth;
+ }
+
+ // highlight on the top edge is drawn in the arrow only in the UP direction
+ if (useBackgroundGradient)
+ {
+ if (isArrowUp)
+ {
+ // highlight follows the top edge, including the arrow
+ var rightWidth:Number = highlightWidth - arrowWidth;
+
+ // highlight style
+ arrowGraphics.lineStyle(highlightWeight, 0xFFFFFF, 0.2 * backgroundAlpha);
+
+ // in the arrow coordinate space, the highlightX must be less than 0
+ if (highlightX < 0)
+ {
+ arrowGraphics.moveTo(highlightX, highlightY);
+ arrowGraphics.lineTo(arrowX, highlightY);
+
+ // compute the remaining highlight
+ rightWidth -= (arrowX - highlightX);
+ }
+
+ // arrow highlight (adjust Y downward)
+ coords[1] = arrowY + highlightOffset;
+ coords[3] = arrowTipY + highlightOffset;
+ coords[5] = arrowEndY + highlightOffset;
+ arrowGraphics.drawPath(commands, coords);
+
+ // right side
+ if (rightWidth > 0)
+ {
+ arrowGraphics.moveTo(arrowEndX, highlightY);
+ arrowGraphics.lineTo(arrowEndX + rightWidth, highlightY);
+ }
+ }
+ else
+ {
+ // straight line across the top
+ arrowGraphics.lineStyle(highlightWeight, 0xFFFFFF, 0.2 * backgroundAlpha);
+ arrowGraphics.moveTo(highlightX, highlightY);
+ arrowGraphics.lineTo(highlightX + highlightWidth, highlightY);
+ }
+ }
+ }
+}
+}
\ No newline at end of file
[2/8] temp commit move experimental callout to spark
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/components/Callout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/Callout.as b/frameworks/projects/spark/src/spark/components/Callout.as
new file mode 100644
index 0000000..8d81b4a
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/components/Callout.as
@@ -0,0 +1,1669 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.components
+{
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.events.Event;
+import flash.geom.ColorTransform;
+import flash.geom.Matrix;
+import flash.geom.Point;
+import flash.geom.Rectangle;
+
+import mx.core.DPIClassification;
+import mx.core.FlexGlobals;
+import mx.core.ILayoutElement;
+import mx.core.IVisualElement;
+import mx.core.LayoutDirection;
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+import mx.events.ResizeEvent;
+import mx.managers.SystemManager;
+import mx.utils.MatrixUtil;
+import mx.utils.PopUpUtil;
+
+use namespace mx_internal;
+
+//--------------------------------------
+// Styles
+//--------------------------------------
+
+/**
+ * Appearance of the <code>contentGroup</code>.
+ * Valid MXML values are <code>inset</code>,
+ * <code>flat</code>, and <code>none</code>.
+ *
+ * <p>In ActionScript, you can use the following constants
+ * to set this property:
+ * <code>ContentBackgroundAppearance.INSET</code>,
+ * <code>ContentBackgroundAppearance.FLAT</code> and
+ * <code>ContentBackgroundAppearance.NONE</code>.</p>
+ *
+ * @default ContentBackgroundAppearance.INSET
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+[Style(name="contentBackgroundAppearance", type="String", enumeration="inset,flat,none", inherit="no")]
+
+//--------------------------------------
+// Other metadata
+//--------------------------------------
+
+[IconFile("Callout.png")]
+
+/**
+ * The Callout container is a SkinnablePopUpContainer that functions as a pop-up
+ * with additional owner-relative positioning options similar to PopUpAnchor.
+ * Callout also adds an optional <code>arrow</code> skin part that visually
+ * displays the direction toward the owner.
+ *
+ * <p>The following image shows a Callout container labeled 'Settings':</p>
+ *
+ * <p>
+ * <img src="../../images/ca_calloutViewNav_ca.png" alt="Callout container" />
+ * </p>
+ *
+ * <p>You can also use the CalloutButton control to open a callout container.
+ * The CalloutButton control encapsulates in a single control the callout container
+ * and all of the logic necessary to open and close the callout.
+ * The CalloutButton control is then said to the be the owner, or host,
+ * of the callout.</p>
+ *
+ * <p>Callout uses the <code>horizontalPosition</code> and
+ * <code>verticalPosition</code> properties to determine the position of the
+ * Callout relative to the owner that is specified by the <code>open()</code>
+ * method.
+ * Both properties can be set to <code>CalloutPosition.AUTO</code> which selects a
+ * position based on the aspect ratio of the screen for the Callout to fit
+ * with minimal overlap with the owner and and minimal adjustments at the
+ * screen bounds.</p>
+ *
+ * <p>Once positioned, the Callout positions the arrow on the side adjacent
+ * to the owner, centered as close as possible on the horizontal or vertical
+ * center of the owner as appropriate. The arrow is hidden in cases where
+ * the Callout position is not adjacent to any edge.</p>
+ *
+ * <p>You do not create a Callout container as part of the normal layout
+ * of its parent container.
+ * Instead, it appears as a pop-up container on top of its parent.
+ * Therefore, you do not create it directly in the MXML code of your application.</p>
+ *
+ * <p>Instead, you create is as an MXML component, often in a separate MXML file.
+ * To show the component create an instance of the MXML component, and
+ * then call the <code>open()</code> method.
+ * You can also set the size and position of the component when you open it.</p>
+ *
+ * <p>To close the component, call the <code>close()</code> method.
+ * If the pop-up needs to return data to a handler, you can add an event listener for
+ * the <code>PopUp.CLOSE</code> event, and specify the returned data in
+ * the <code>close()</code> method.</p>
+ *
+ * <p>The Callout is initially in its <code>closed</code> skin state.
+ * When it opens, it adds itself as a pop-up to the PopUpManager,
+ * and transition to the <code>normal</code> skin state.
+ * To define open and close animations, use a custom skin with transitions between
+ * the <code>closed</code> and <code>normal</code> skin states.</p>
+ *
+ * <p>Callout changes the default inheritance behavior seen in Flex components
+ * and instead, inherits styles from the top-level application. This prevents
+ * Callout's contents from unintentionally inheriting styles from an owner
+ * (i.e. Button or TextInput) where the default appearance was desired and
+ * expected.</p>
+ *
+ * <p>The Callout container has the following default characteristics:</p>
+ * <table class="innertable">
+ * <tr><th>Characteristic</th><th>Description</th></tr>
+ * <tr><td>Default size</td><td>Large enough to display its children</td></tr>
+ * <tr><td>Minimum size</td><td>0 pixels</td></tr>
+ * <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr>
+ * <tr><td>Default skin class</td><td>spark.skins.mobile.CalloutSkin</td></tr>
+ * </table>
+ *
+ * @mxml <p>The <code><s:Callout></code> tag inherits all of the tag
+ * attributes of its superclass and adds the following tag attributes:</p>
+ *
+ * <pre>
+ * <s:Callout
+ * <strong>Properties</strong>
+ * horizontalPosition="auto"
+ * verticalPosition="auto"
+ *
+ * <strong>Styles</strong>
+ * contentBackgroundAppearance="inset"
+ * />
+ * </pre>
+ *
+ * @see spark.components.CalloutButton
+ * @see spark.skins.mobile.CalloutSkin
+ * @see spark.components.ContentBackgroundAppearance
+ * @see spark.components.CalloutPosition
+ *
+ * @includeExample examples/CalloutExample.mxml -noswf
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public class Callout extends SkinnablePopUpContainer
+{
+
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ private static var decomposition:Vector.<Number> = new <Number>[0,0,0,0,0];
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function Callout()
+ {
+ super();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Skin parts
+ //
+ //--------------------------------------------------------------------------
+
+ [Bindable]
+ [SkinPart(required="false")]
+
+ /**
+ * An optional skin part that visually connects the owner to the
+ * contentGroup.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public var arrow:UIComponent;
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ private var invalidatePositionFlag:Boolean = false;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // horizontalPosition
+ //----------------------------------
+
+ private var _horizontalPosition:String = CalloutPosition.AUTO;
+
+ [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
+
+ /**
+ * Horizontal position of the callout relative to the owner.
+ *
+ * <p>Possible values are <code>"before"</code>, <code>"start"</code>,
+ * <code>"middle"</code>, <code>"end"</code>, <code>"after"</code>,
+ * and <code>"auto"</code> (default).</p>
+ *
+ * @default CalloutPosition.AUTO
+ * @see spark.components.CalloutPosition
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get horizontalPosition():String
+ {
+ return _horizontalPosition;
+ }
+
+ /**
+ * @private
+ */
+ public function set horizontalPosition(value:String):void
+ {
+ if (value == _horizontalPosition)
+ return;
+
+ _horizontalPosition = value;
+
+ invalidatePosition();
+ }
+
+ //----------------------------------
+ // actualHorizontalPosition
+ //----------------------------------
+
+ private var _actualHorizontalPosition:String;
+
+ /**
+ * Fully resolved horizontal position after evaluating CalloutPosition.AUTO.
+ *
+ * <p>Update this property in <code>commitProperties()</code> when the
+ * explicit <code>horizontalPosition</code> is CalloutPosition.AUTO.
+ * This property must be updated in <code>updatePopUpPosition()</code>
+ * when attempting to reposition the Callout.</p>
+ *
+ * <p>Subclasses should read this property when computing the <code>arrowDirection</code>,
+ * the arrow position in <code>updateSkinDisplayList()</code>.</p>
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ mx_internal function get actualHorizontalPosition():String
+ {
+ if (_actualHorizontalPosition)
+ return _actualHorizontalPosition;
+
+ return horizontalPosition;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function set actualHorizontalPosition(value:String):void
+ {
+ _actualHorizontalPosition = value;
+ }
+
+ //----------------------------------
+ // verticalPosition
+ //----------------------------------
+
+ private var _verticalPosition:String = CalloutPosition.AUTO;
+
+ [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
+
+ /**
+ * Vertical position of the callout relative to the owner.
+ *
+ * <p>Possible values are <code>"before"</code>, <code>"start"</code>,
+ * <code>"middle"</code>, <code>"end"</code>, <code>"after"</code>,
+ * and <code>"auto"</code> (default).</p>
+ *
+ * @default CalloutPosition.AUTO
+ * @see spark.components.CalloutPosition
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get verticalPosition():String
+ {
+ return _verticalPosition;
+ }
+
+ /**
+ * @private
+ */
+ public function set verticalPosition(value:String):void
+ {
+ if (value == _verticalPosition)
+ return;
+
+ _verticalPosition = value;
+
+ invalidatePosition();
+ }
+
+ //----------------------------------
+ // actualVerticalPosition
+ //----------------------------------
+
+ private var _actualVerticalPosition:String;
+
+ /**
+ * Fully resolved vertical position after evaluating CalloutPosition.AUTO.
+ *
+ * <p>Update this property in <code>commitProperties()</code> when the
+ * explicit <code>verticalPosition</code> is CalloutPosition.AUTO.
+ * This property must be updated in <code>updatePopUpPosition()</code>
+ * when attempting to reposition the Callout.</p>
+ *
+ * <p>Subclasses should read this property when computing the <code>arrowDirection</code>,
+ * the arrow position in <code>updateSkinDisplayList()</code>.</p>
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ mx_internal function get actualVerticalPosition():String
+ {
+ if (_actualVerticalPosition)
+ return _actualVerticalPosition;
+
+ return verticalPosition;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function set actualVerticalPosition(value:String):void
+ {
+ _actualVerticalPosition = value;
+ }
+
+ //----------------------------------
+ // arrowDirection
+ //----------------------------------
+
+ private var _arrowDirection:String = ArrowDirection.NONE;
+
+ /**
+ * @private
+ * Indicates if arrow direction was flipped automatically.
+ */
+ private var arrowDirectionAdjusted:Boolean = false;
+
+ /**
+ * A read-only property that indicates the direction from the callout
+ * towards the owner.
+ *
+ * <p>This value is computed based on the callout position given by
+ * <code>horizontalPosition</code> and <code>verticalPosition</code>.
+ * Exterior and interior positions will point from the callout towards
+ * the edge of the owner. Corner and absolute center positions are not
+ * supported and will return a value of <code>"none".</code></p>
+ *
+ * @default none
+ *
+ * @see spark.components.ArrowDirection
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get arrowDirection():String
+ {
+ return _arrowDirection;
+ }
+
+ /**
+ * @private
+ * Invalidate skin when the arrowDirection changes. Dispatches an
+ * "arrowDirectionChanged" event when the property is set.
+ */
+ mx_internal function setArrowDirection(value:String):void
+ {
+ if (_arrowDirection == value)
+ return;
+
+ _arrowDirection = value;
+
+ // Instead of using skin states for each arrowDirection, the
+ // skin must override commitProperties() and account for
+ // arrowDirection on it's own.
+ skin.invalidateProperties();
+
+ // adjust margins based on arrow direction
+ switch (arrowDirection)
+ {
+ case ArrowDirection.DOWN:
+ {
+ // Set the marginBottom to zero to place the arrow adjacent to the keyboard
+ softKeyboardEffectMarginBottom = 0;
+ softKeyboardEffectMarginTop = margin;
+ break;
+ }
+ case ArrowDirection.UP:
+ {
+ // Arrow should already be adjacent to the owner or the top of
+ // the screen.
+ softKeyboardEffectMarginTop = 0;
+ softKeyboardEffectMarginBottom = margin;
+ break;
+ }
+ default:
+ {
+ softKeyboardEffectMarginBottom = margin;
+ softKeyboardEffectMarginTop = margin;
+ break;
+ }
+ }
+
+ if (hasEventListener("arrowDirectionChanged"))
+ dispatchEvent(new Event("arrowDirectionChanged"));
+ }
+
+ //----------------------------------
+ // margin
+ //----------------------------------
+
+ private var _margin:Number = NaN;
+
+ /**
+ * @private
+ * Defines a margin around the Callout to nudge it's position away from the
+ * edge of the screen.
+ */
+ mx_internal function get margin():Number
+ {
+ if (isNaN(_margin))
+ {
+ var dpi:Number = FlexGlobals.topLevelApplication["applicationDPI"];
+
+ if (dpi)
+ {
+ switch (dpi)
+ {
+ case DPIClassification.DPI_640:
+ {
+ _margin = 32;
+ break;
+ }
+ case DPIClassification.DPI_480:
+ {
+ _margin = 24;
+ break;
+ }
+ case DPIClassification.DPI_320:
+ {
+ _margin = 16;
+ break;
+ }
+ case DPIClassification.DPI_240:
+ {
+ _margin = 12;
+ break;
+ }
+ case DPIClassification.DPI_120:
+ {
+ _margin = 6;
+ break;
+ }
+ default:
+ {
+ // default DPI_160
+ _margin = 8;
+ break;
+ }
+ }
+ }
+ else
+ {
+ _margin = 8;
+ }
+ }
+
+ return _margin;
+ }
+
+ private var _explicitMoveForSoftKeyboard:Boolean = false;
+
+ /**
+ * @private
+ */
+ override public function get moveForSoftKeyboard():Boolean
+ {
+ // If no explicit setting, then automatically disable move when
+ // pointing up towards the owner.
+ if (!_explicitMoveForSoftKeyboard &&
+ (arrowDirection == ArrowDirection.UP))
+ {
+ return false;
+ }
+
+ return super.moveForSoftKeyboard;
+ }
+
+ /**
+ * @private
+ */
+ override public function set moveForSoftKeyboard(value:Boolean):void
+ {
+ super.moveForSoftKeyboard = value;
+
+ _explicitMoveForSoftKeyboard = true;
+ }
+
+ //----------------------------------
+ // calloutMaxWidth
+ //----------------------------------
+
+ private var _calloutMaxWidth:Number = NaN;
+
+ /**
+ * @private
+ */
+ mx_internal function get calloutMaxWidth():Number
+ {
+ return _calloutMaxWidth;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function set calloutMaxWidth(value:Number):void
+ {
+ if (_calloutMaxWidth == value)
+ return;
+
+ _calloutMaxWidth = value;
+
+ invalidateMaxSize();
+ }
+
+
+ //----------------------------------
+ // calloutMaxHeight
+ //----------------------------------
+
+ private var _calloutMaxHeight:Number = NaN;
+
+ /**
+ * @private
+ */
+ mx_internal function get calloutMaxHeight():Number
+ {
+ return _calloutMaxHeight;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function set calloutMaxHeight(value:Number):void
+ {
+ if (_calloutMaxHeight == value)
+ return;
+
+ _calloutMaxHeight = value;
+
+ invalidateMaxSize();
+ }
+
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ override public function get explicitMaxWidth():Number
+ {
+ if (!isNaN(super.explicitMaxWidth))
+ return super.explicitMaxWidth;
+
+ return calloutMaxWidth;
+ }
+
+ /**
+ * @private
+ */
+ override public function get explicitMaxHeight():Number
+ {
+ if (!isNaN(super.explicitMaxHeight))
+ return super.explicitMaxHeight;
+
+ return calloutMaxHeight;
+ }
+
+ /**
+ * @private
+ */
+ override protected function commitProperties():void
+ {
+ super.commitProperties();
+
+ // Do not commit position changes if closed (no owner) or owner was
+ // removed from the display list.
+ if (!owner || !owner.parent)
+ return;
+
+ // Compute actual positions when using AUTO
+ commitAutoPosition();
+
+ // Compute max size based on actual positions
+ commitMaxSize();
+
+ if (arrow)
+ {
+ // arrowDirection can be set in 2 ways: (1) horizontalPostion/verticalPosition
+ // changes and (2) flipping the axis to fit on screen.
+ if (!arrowDirectionAdjusted)
+ {
+ // Invalidate only when the arrow direction changes
+ var direction:String = determineArrowPosition(actualHorizontalPosition,
+ actualVerticalPosition);
+
+ if (arrowDirection != direction)
+ {
+ setArrowDirection(direction);
+
+ if (arrow)
+ arrow.visible = (arrowDirection != ArrowDirection.NONE);
+ }
+ }
+
+ // Always reset the arrow position
+ invalidateDisplayList();
+ }
+ }
+
+ /**
+ * @private
+ * Re-position the pop-up using actualHorizontalPosition and
+ * actualVerticalPosition.
+ */
+ override public function updatePopUpPosition():void
+ {
+ if (!owner || !systemManager)
+ return;
+
+ var popUpPoint:Point = calculatePopUpPosition();
+ var ownerComponent:UIComponent = owner as UIComponent;
+ var concatenatedColorTransform:ColorTransform =
+ (ownerComponent) ? ownerComponent.$transform.concatenatedColorTransform : null;
+
+ PopUpUtil.applyPopUpTransform(owner, concatenatedColorTransform,
+ systemManager, this, popUpPoint);
+ }
+
+ /**
+ * @private
+ *
+ * Cooperative layout
+ * @see spark.components.supportClasses.TrackBase#partAdded
+ */
+ override protected function partAdded(partName:String, instance:Object):void
+ {
+ super.partAdded(partName, instance);
+
+ if (instance == arrow)
+ arrow.addEventListener(ResizeEvent.RESIZE, arrow_resizeHandler);
+ }
+
+ /**
+ * @private
+ */
+ override protected function partRemoved(partName:String, instance:Object):void
+ {
+ super.partRemoved(partName, instance);
+
+ if (instance == arrow)
+ arrow.removeEventListener(ResizeEvent.RESIZE, arrow_resizeHandler);
+ }
+
+ /**
+ * @private
+ */
+ override public function open(owner:DisplayObjectContainer, modal:Boolean=false):void
+ {
+ if (isOpen)
+ return;
+
+ // reset state
+ invalidatePositionFlag = false;
+ arrowDirectionAdjusted = false;
+
+ // Add to PopUpManager, calls updatePopUpPosition(), and change state
+ super.open(owner, modal);
+
+ // Reposition the callout when the screen changes
+ var systemManagerParent:SystemManager = this.parent as SystemManager;
+
+ if (systemManagerParent)
+ systemManagerParent.addEventListener(Event.RESIZE, systemManager_resizeHandler);
+ }
+
+ /**
+ * @private
+ */
+ override public function close(commit:Boolean=false, data:*=null):void
+ {
+ if (!isOpen)
+ return;
+
+ var systemManagerParent:SystemManager = this.parent as SystemManager;
+
+ if (systemManagerParent)
+ systemManagerParent.removeEventListener(Event.RESIZE, systemManager_resizeHandler);
+
+ super.close(commit, data);
+ }
+
+ /**
+ * @private
+ */
+ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+ // Callout can be respositioned while open via SystemManager resize or
+ // explicit changes to horizontalPostion and verticalPosition.
+ if (isOpen && invalidatePositionFlag)
+ {
+ updatePopUpPosition();
+ invalidatePositionFlag = false;
+ }
+
+ // Position the arrow
+ updateSkinDisplayList();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private function invalidatePosition():void
+ {
+ arrowDirectionAdjusted = false;
+
+ invalidateProperties();
+
+ if (isOpen)
+ invalidatePositionFlag = true;
+ }
+
+ /**
+ * @private
+ * Force a new measurement when callout should use it's screen-constrained
+ * max size.
+ */
+ private function invalidateMaxSize():void
+ {
+ // calloutMaxWidth and calloutMaxHeight don't invalidate
+ // explicitMaxWidth or explicitMaxHeight. If callout's max size changes
+ // and explicit max sizes aren't set, then invalidate size here so that
+ // callout's max size is applied.
+ if (!canSkipMeasurement() && !isMaxSizeSet)
+ skin.invalidateSize();
+ }
+
+ /**
+ * Sets the bounds of <code>arrow</code>, whose geometry isn't fully
+ * specified by the skin's layout.
+ *
+ * <p>Subclasses can override this method to update the arrow's size,
+ * position, and visibility, based on the computed
+ * <code>arrowDirection</code>.</p>
+ *
+ * <p>By default, this method aligns the arrow on the shorter of either
+ * the <code>arrow</code> bounds or the <code>owner</code> bounds. This
+ * implementation assumes that the <code>arrow</code> and the Callout skin
+ * share the same coordinate space.</p>
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected function updateSkinDisplayList():void
+ {
+ var ownerVisualElement:IVisualElement = owner as IVisualElement;
+
+ // Sanity check to verify owner is still on the display list. If not,
+ // leave the arrow in the current position.
+ if (!arrow || !ownerVisualElement ||
+ (arrowDirection == ArrowDirection.NONE) ||
+ (!ownerVisualElement.parent))
+ return;
+
+ var isStartPosition:Boolean = false;
+ var isMiddlePosition:Boolean = false;
+ var isEndPosition:Boolean = false;
+
+ var position:String = (isArrowVertical) ? actualHorizontalPosition : actualVerticalPosition;
+
+ isStartPosition = (position == CalloutPosition.START);
+ isMiddlePosition = (position == CalloutPosition.MIDDLE);
+ isEndPosition = (position == CalloutPosition.END);
+
+ var isEndOfCallout:Boolean = (arrowDirection == ArrowDirection.DOWN)
+ || (arrowDirection == ArrowDirection.RIGHT);
+
+ var calloutWidth:Number = getLayoutBoundsWidth();
+ var calloutHeight:Number = getLayoutBoundsHeight();
+ var arrowWidth:Number = arrow.getLayoutBoundsWidth();
+ var arrowHeight:Number = arrow.getLayoutBoundsHeight();
+
+ // arrow X/Y in pop-up coordinates
+ var arrowX:Number = 0;
+ var arrowY:Number = 0;
+
+ // Max arrow positions
+ var maxArrowX:Number = calloutWidth - arrowWidth;
+ var maxArrowY:Number = calloutHeight - arrowHeight;
+
+ // Find the registration point of the owner
+ var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
+ var regPoint:Point = owner.localToGlobal(new Point());
+ regPoint = sandboxRoot.globalToLocal(regPoint);
+
+ if (isArrowVertical)
+ {
+ // Vertical arrows need horizontal alignment
+ var ownerX:Number = regPoint.x;
+ var ownerVisibleWidth:Number = (ownerVisualElement)
+ ? ownerVisualElement.getLayoutBoundsWidth() : owner.width;
+
+ // Edge cases when start/end of owner is not visible
+ if ((ownerX < 0) && (ownerVisibleWidth < screen.width))
+ ownerVisibleWidth = Math.max(ownerVisibleWidth + ownerX, 0);
+ else if ((ownerX >= 0) && ((ownerX + ownerVisibleWidth) >= screen.width))
+ ownerVisibleWidth = Math.max(screen.width - ownerX, 0);
+
+ ownerVisibleWidth = Math.min(ownerVisibleWidth, screen.width);
+
+ if (calloutWidth <= ownerVisibleWidth)
+ {
+ arrowX = (calloutWidth - arrowWidth) / 2;
+ }
+ else // if (calloutWidth > ownerWidth)
+ {
+ // Center the arrow on the owner
+ arrowX = (ownerVisibleWidth - arrowWidth) / 2;
+
+ // Add owner offset
+ if (ownerX > 0)
+ arrowX += Math.abs(ownerX - getLayoutBoundsX());
+
+ if (ownerX < margin)
+ arrowX -= (margin - ownerX);
+ }
+
+ // arrow should not extend past the callout bounds
+ arrowX = Math.max(Math.min(maxArrowX, arrowX), 0);
+
+ // Move the arrow to the bottom of the callout
+ if (isEndOfCallout)
+ arrowY = calloutHeight - arrowHeight;
+ }
+ else
+ {
+ // Horizontal arrows need vertical alignment
+ var ownerY:Number = regPoint.y;
+ var ownerVisibleHeight:Number = (ownerVisualElement)
+ ? ownerVisualElement.getLayoutBoundsHeight() : owner.height;
+
+ // Edge cases when start/end of owner is not visible
+ if ((ownerY < 0) && (ownerVisibleHeight < screen.height))
+ ownerVisibleHeight = Math.max(ownerVisibleHeight + ownerY, 0);
+ else if ((ownerY >= 0) && ((ownerY + ownerVisibleHeight) >= screen.height))
+ ownerVisibleHeight = Math.max(screen.height - ownerY, 0);
+
+ ownerVisibleHeight = Math.min(ownerVisibleHeight, screen.height);
+
+ if (calloutHeight <= ownerVisibleHeight)
+ {
+ arrowY = (calloutHeight - arrowHeight) / 2;
+ }
+ else // if (calloutHeight > ownerHeight)
+ {
+ // Center the arrow on the owner
+ arrowY = (ownerVisibleHeight - arrowHeight) / 2;
+
+ // Add owner offset
+ if (ownerY > 0)
+ arrowY += Math.abs(ownerY - getLayoutBoundsY());
+
+ if (ownerY < margin)
+ ownerY -= (margin - ownerY);
+ }
+
+ // arrow should not extend past the callout bounds
+ arrowY = Math.max(Math.min(maxArrowY, arrowY), 0);
+
+ // Move the arrow to the end of the callout
+ if (isEndOfCallout)
+ arrowX = calloutWidth - arrowWidth;
+ }
+
+ arrow.setLayoutBoundsPosition(Math.floor(arrowX), Math.floor(arrowY));
+ arrow.invalidateDisplayList();
+ }
+
+ /**
+ * @private
+ *
+ * Flip or clear the adjusted position when the callout bounds are outside
+ * the screen bounds.
+ */
+ mx_internal function adjustCalloutPosition(actualPosition:String, preferredPosition:String,
+ calloutStart:Number, calloutEnd:Number,
+ screenStart:Number, screenEnd:Number,
+ ownerStart:Number, ownerEnd:Number,
+ revert:Boolean=false):String
+ {
+ if (!actualPosition)
+ return null;
+
+ var adjustedPosition:String = null;
+ var calloutSize:Number = calloutEnd - calloutStart;
+
+ // Exterior space
+ var exteriorSpaceStart:Number = Math.max(0, ownerStart - screenStart);
+ var exteriorSpaceEnd:Number = Math.max(0, ownerEnd - screenEnd);
+
+ // Fallback to interior positions if using AUTO and callout can not
+ // fit in either exterior positions
+ var useInterior:Boolean = (preferredPosition == CalloutPosition.AUTO) &&
+ (exteriorSpaceStart < calloutSize) &&
+ (exteriorSpaceEnd < calloutSize);
+ var isExterior:Boolean = false;
+
+ // Flip to opposite position
+ switch (actualPosition)
+ {
+ case CalloutPosition.BEFORE:
+ {
+ isExterior = true;
+
+ if (calloutStart < screenStart)
+ adjustedPosition = CalloutPosition.AFTER;
+
+ break;
+ }
+ case CalloutPosition.AFTER:
+ {
+ isExterior = true;
+
+ if (calloutEnd > screenEnd)
+ adjustedPosition = CalloutPosition.BEFORE;
+
+ break;
+ }
+ case CalloutPosition.END:
+ {
+ if (calloutStart < screenStart)
+ adjustedPosition = CalloutPosition.START;
+ break;
+ }
+ case CalloutPosition.START:
+ {
+ if (calloutEnd > screenEnd)
+ adjustedPosition = CalloutPosition.END;
+ break;
+ }
+ // case CalloutPosition.MIDDLE:
+ // Nudge instead of flipping
+ }
+
+ // Use interior position if exterior flipping was necessary
+ if (useInterior && adjustedPosition && isExterior)
+ {
+ // Choose the exterior position with the most available space.
+ // Note that START grows towards the exterior END and vice versa.
+ adjustedPosition = (exteriorSpaceEnd >= exteriorSpaceStart) ?
+ CalloutPosition.START : CalloutPosition.END;
+ }
+
+ // Return null to revert the adjusted position
+ // Otherwise, return the incoming position
+ if (revert)
+ return (adjustedPosition) ? null : actualPosition;
+
+ // Adjusted position or null if the callout already fits
+ return adjustedPosition;
+ }
+
+ /**
+ * @private
+ *
+ * Nudge the callout position to fit on screen. Prefer top/left positions
+ * and allow overflow to get clipped on the bottom/right.
+ */
+ mx_internal function nudgeToFit(calloutStart:Number, calloutEnd:Number,
+ screenStart:Number, screenEnd:Number,
+ scaleFactor:Number):Number
+ {
+ var position:Number = 0;
+
+ if (calloutStart < screenStart)
+ position += (screenStart - calloutStart) / scaleFactor;
+ else if (calloutEnd > screenEnd)
+ position -= (calloutEnd - screenEnd) / scaleFactor;
+
+ return position;
+ }
+
+ /**
+ * @private
+ *
+ * Basically the same as PopUpAnchor, but with more position options
+ * including exterior, interior and corner positions.
+ *
+ * Nudging to fit the screen accounts for <code>margin</code> so that
+ * the Callout is not positioned in the margin.
+ *
+ * <code>arrowDirection</code> will change if required for the callout
+ * to fit.
+ *
+ * @see #margin
+ */
+ mx_internal function calculatePopUpPosition():Point
+ {
+ // This implementation doesn't handle rotation
+ var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
+ var matrix:Matrix = MatrixUtil.getConcatenatedMatrix(owner, sandboxRoot);
+
+ var regPoint:Point = new Point();
+
+ if (!matrix)
+ return regPoint;
+
+ var adjustedHorizontalPosition:String;
+ var adjustedVerticalPosition:String;
+ var calloutBounds:Rectangle = determinePosition(actualHorizontalPosition,
+ actualVerticalPosition, matrix, regPoint);
+ var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
+
+ // Position the callout in the opposite direction if it
+ // does not fit on the screen.
+ if (screen)
+ {
+ adjustedHorizontalPosition = adjustCalloutPosition(
+ actualHorizontalPosition, horizontalPosition,
+ calloutBounds.left, calloutBounds.right,
+ screen.left, screen.right,
+ ownerBounds.left, ownerBounds.right);
+
+ adjustedVerticalPosition = adjustCalloutPosition(
+ actualVerticalPosition, verticalPosition,
+ calloutBounds.top, calloutBounds.bottom,
+ screen.top, screen.bottom,
+ ownerBounds.top, ownerBounds.bottom);
+ }
+
+ var oldArrowDirection:String = arrowDirection;
+ var actualArrowDirection:String = null;
+
+ // Reset arrowDirectionAdjusted
+ arrowDirectionAdjusted = false;
+
+ // Get the new registration point based on the adjusted position
+ if ((adjustedHorizontalPosition != null) || (adjustedVerticalPosition != null))
+ {
+ var adjustedRegPoint:Point = new Point();
+ var tempHorizontalPosition:String = (adjustedHorizontalPosition)
+ ? adjustedHorizontalPosition : actualHorizontalPosition;
+ var tempVerticalPosition:String = (adjustedVerticalPosition)
+ ? adjustedVerticalPosition : actualVerticalPosition;
+
+ // Adjust arrow direction after adjusting position
+ actualArrowDirection = determineArrowPosition(tempHorizontalPosition,
+ tempVerticalPosition);
+
+ // All position flips gaurantee an arrowDirection change
+ setArrowDirection(actualArrowDirection);
+ arrowDirectionAdjusted = true;
+
+ if (arrow)
+ arrow.visible = (arrowDirection != ArrowDirection.NONE);
+
+ // Reposition the arrow
+ updateSkinDisplayList();
+
+ var adjustedBounds:Rectangle = determinePosition(tempHorizontalPosition,
+ tempVerticalPosition, matrix, adjustedRegPoint);
+
+ if (screen)
+ {
+ // If we adjusted the position but the callout still doesn't fit,
+ // then revert to the original position.
+ adjustedHorizontalPosition = adjustCalloutPosition(
+ adjustedHorizontalPosition, horizontalPosition,
+ adjustedBounds.left, adjustedBounds.right,
+ screen.left, screen.right,
+ ownerBounds.left, ownerBounds.right,
+ true);
+
+ adjustedVerticalPosition = adjustCalloutPosition(
+ adjustedVerticalPosition, verticalPosition,
+ adjustedBounds.top, adjustedBounds.bottom,
+ screen.top, screen.bottom,
+ ownerBounds.top, ownerBounds.bottom,
+ true);
+ }
+
+ if ((adjustedHorizontalPosition != null) || (adjustedVerticalPosition != null))
+ {
+ regPoint = adjustedRegPoint;
+ calloutBounds = adjustedBounds;
+
+ // Temporarily set actual positions to reposition the arrow
+ if (adjustedHorizontalPosition)
+ actualHorizontalPosition = adjustedHorizontalPosition;
+
+ if (adjustedVerticalPosition)
+ actualVerticalPosition = adjustedVerticalPosition;
+
+ // Reposition the arrow with the new actual position
+ updateSkinDisplayList();
+ }
+ else
+ {
+ // Restore previous arrow direction *before* reversing the
+ // adjusted positions
+ setArrowDirection(oldArrowDirection);
+ arrowDirectionAdjusted = false;
+
+ // Reposition the arrow to the original position
+ updateSkinDisplayList();
+ }
+ }
+
+ MatrixUtil.decomposeMatrix(decomposition, matrix, 0, 0);
+ var concatScaleX:Number = decomposition[3];
+ var concatScaleY:Number = decomposition[4];
+
+ // If the callout still doesn't fit, then nudge it
+ // so it is completely on the screen. Make sure to include scale.
+ var screenTop:Number = screen.top;
+ var screenBottom:Number = screen.bottom;
+ var screenLeft:Number = screen.left;
+ var screenRight:Number = screen.right;
+
+ // Allow zero margin on the the side with the arrow
+ switch (arrowDirection)
+ {
+ case ArrowDirection.UP:
+ {
+ screenBottom -= margin;
+ screenLeft += margin;
+ screenRight -= margin
+ break;
+ }
+ case ArrowDirection.DOWN:
+ {
+ screenTop += margin;
+ screenLeft += margin;
+ screenRight -= margin
+ break;
+ }
+ case ArrowDirection.LEFT:
+ {
+ screenTop += margin;
+ screenBottom -= margin;
+ screenRight -= margin
+ break;
+ }
+ case ArrowDirection.RIGHT:
+ {
+ screenTop += margin;
+ screenBottom -= margin;
+ screenLeft += margin;
+ break;
+ }
+ default:
+ {
+ screenTop += margin;
+ screenBottom -= margin;
+ screenLeft += margin;
+ screenRight -= margin
+ break;
+ }
+ }
+
+ regPoint.y += nudgeToFit(calloutBounds.top, calloutBounds.bottom,
+ screenTop, screenBottom, concatScaleY);
+
+ regPoint.x += nudgeToFit(calloutBounds.left, calloutBounds.right,
+ screenLeft, screenRight, concatScaleX);
+
+ // Compute the stage coordinates of the upper,left corner of the PopUp, taking
+ // the postTransformOffsets - which include mirroring - into account.
+ // If we're mirroring, then the implicit assumption that x=left will fail,
+ // so we compensate here.
+
+ if (layoutDirection == LayoutDirection.RTL)
+ regPoint.x += calloutBounds.width;
+ return MatrixUtil.getConcatenatedComputedMatrix(owner, sandboxRoot).transformPoint(regPoint);
+ }
+
+ /**
+ * @private
+ * Computes <code>actualHorizontalPosition</code> and/or
+ * <code>actualVerticalPosition</code> values when using
+ * <code>CalloutPosition.AUTO</code>. When implementing subclasses of
+ * Callout, use <code>actualHorizontalPosition</code> and
+ * <code>actualVerticalPosition</code> to compute
+ * <code>arrowDirection</code> and positioning in
+ * <code>updatePopUpPosition()</code> and <code>updateSkinDisplayList()</code>.
+ *
+ * <p>The default implementation chooses "outer" positions for the callout
+ * such that the owner is not obscured. Horizontal/Vertical orientation
+ * relative to the owner choosen based on the aspect ratio.</p>
+ *
+ * <p>When the aspect ratio is landscape, and the callout can fit to the
+ * left or right of the owner, <code>actualHorizontalPosition</code> is
+ * set to <code>CalloutPosition.BEFORE</code> or
+ * <code>CalloutPosition.AFTER</code> as appropriate.
+ * <code>actualVerticalPosition</code> is set to
+ * <code>CalloutPosition.MIDDLE</code> to have the vertical center of the
+ * callout align to the vertical center of the owner.</p>
+ *
+ * <p>When the aspect ratio is portrait, and the callout can fit
+ * above or below the owner, <code>actualVerticalPosition</code> is
+ * set to <code>CalloutPosition.BEFORE</code> or
+ * <code>CalloutPosition.AFTER</code> as appropriate.
+ * <code>actualHorizontalPosition</code> is set to
+ * <code>CalloutPosition.MIDDLE</code> to have the horizontal center of the
+ * callout align to the horizontal center of the owner.</p>
+ *
+ * <p>Subclasses may override to modify automatic positioning behavior.</p>
+ */
+ mx_internal function commitAutoPosition():void
+ {
+ if (!screen || ((horizontalPosition != CalloutPosition.AUTO) &&
+ (verticalPosition != CalloutPosition.AUTO)))
+ {
+ // Use explicit positions instead of AUTO
+ actualHorizontalPosition = null;
+ actualVerticalPosition = null;
+
+ return;
+ }
+
+ var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
+
+ // Use aspect ratio to determine vertical/horizontal preference
+ var isLandscape:Boolean = (screen.width > screen.height);
+
+ // Exterior space
+ var exteriorSpaceLeft:Number = Math.max(0, ownerBounds.left);
+ var exteriorSpaceRight:Number = Math.max(0, screen.width - ownerBounds.right);
+ var exteriorSpaceTop:Number = Math.max(0, ownerBounds.top);
+ var exteriorSpaceBottom:Number = Math.max(0, screen.height - ownerBounds.bottom);
+
+ if (verticalPosition != CalloutPosition.AUTO)
+ {
+ // Horizontal auto only
+ switch (verticalPosition)
+ {
+ case CalloutPosition.START:
+ case CalloutPosition.MIDDLE:
+ case CalloutPosition.END:
+ {
+ actualHorizontalPosition = (exteriorSpaceRight > exteriorSpaceLeft) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
+ break;
+ }
+ default:
+ {
+ actualHorizontalPosition = CalloutPosition.MIDDLE;
+ break;
+ }
+ }
+
+ actualVerticalPosition = null;
+ }
+ else if (horizontalPosition != CalloutPosition.AUTO)
+ {
+ // Vertical auto only
+ switch (horizontalPosition)
+ {
+ case CalloutPosition.START:
+ case CalloutPosition.MIDDLE:
+ case CalloutPosition.END:
+ {
+ actualVerticalPosition = (exteriorSpaceBottom > exteriorSpaceTop) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
+ break;
+ }
+ default:
+ {
+ actualVerticalPosition = CalloutPosition.MIDDLE;
+ break;
+ }
+ }
+
+ actualHorizontalPosition = null;
+ }
+ else // if ((verticalPosition == CalloutPosition.AUTO) && (horizontalPosition == CalloutPosition.AUTO))
+ {
+ if (!isLandscape)
+ {
+ // Arrow will be vertical when in portrait
+ actualHorizontalPosition = CalloutPosition.MIDDLE;
+ actualVerticalPosition = (exteriorSpaceBottom > exteriorSpaceTop) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
+ }
+ else
+ {
+ // Arrow will be horizontal when in landscape
+ actualHorizontalPosition = (exteriorSpaceRight > exteriorSpaceLeft) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
+ actualVerticalPosition = CalloutPosition.MIDDLE;
+ }
+ }
+ }
+
+ /**
+ * @private
+ * Return true if user-specified max size if set
+ */
+ mx_internal function get isMaxSizeSet():Boolean
+ {
+ var explicitMaxW:Number = super.explicitMaxWidth;
+ var explicitMaxH:Number = super.explicitMaxHeight;
+
+ return (!isNaN(explicitMaxW) && !isNaN(explicitMaxH));
+ }
+
+ /**
+ * @private
+ * Return the original height if the soft keyboard is active. This height
+ * is used to stabilize AUTO positioning so that the position is based
+ * on the original height of the Callout instead of a possibly shorter
+ * height due to soft keyboard effects.
+ */
+ mx_internal function get calloutHeight():Number
+ {
+ return (isSoftKeyboardEffectActive) ? softKeyboardEffectCachedHeight : getLayoutBoundsHeight();
+ }
+
+ /**
+ * @private
+ * Compute max width and max height. Uses the the owner and screen bounds
+ * as well as preferred positions to determine max width and max height
+ * for all possible exterior and interior positions.
+ */
+ mx_internal function commitMaxSize():void
+ {
+ var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
+ var ownerLeft:Number = ownerBounds.left;
+ var ownerRight:Number = ownerBounds.right;
+ var ownerTop:Number = ownerBounds.top;
+ var ownerBottom:Number = ownerBounds.bottom;
+ var maxW:Number;
+ var maxH:Number;
+
+ switch (actualHorizontalPosition)
+ {
+ case CalloutPosition.MIDDLE:
+ {
+ // Callout matches screen width
+ maxW = screen.width - (margin * 2);
+ break;
+ }
+ case CalloutPosition.START:
+ case CalloutPosition.END:
+ {
+ // Flip left and right when using inner positions
+ ownerLeft = ownerBounds.right;
+ ownerRight = ownerBounds.left;
+
+ // Fall through
+ }
+ default:
+ {
+ // Maximum is the larger of the actual position or flipped position
+ maxW = Math.max(ownerLeft, screen.right - ownerRight) - margin;
+ break;
+ }
+ }
+
+ // If preferred position was AUTO, then allow maxWidth to grow to
+ // fit the interior position if the owner is wide
+ if ((horizontalPosition == CalloutPosition.AUTO) &&
+ (ownerBounds.width > maxW))
+ maxW += ownerBounds.width;
+
+ switch (actualVerticalPosition)
+ {
+ case CalloutPosition.MIDDLE:
+ {
+ // Callout matches screen height
+ maxH = screen.height - (margin * 2);
+ break;
+ }
+ case CalloutPosition.START:
+ case CalloutPosition.END:
+ {
+ // Flip top and bottom when using inner positions
+ ownerTop = ownerBounds.bottom;
+ ownerBottom = ownerBounds.top;
+
+ // Fall through
+ }
+ default:
+ {
+ // Maximum is the larger of the actual position or flipped position
+ maxH = Math.max(ownerTop, screen.bottom - ownerBottom) - margin;
+ break;
+ }
+ }
+
+ // If preferred position was AUTO, then allow maxHeight to grow to
+ // fit the interior position if the owner is tall
+ if ((verticalPosition == CalloutPosition.AUTO) &&
+ (ownerBounds.height > maxH))
+ maxH += ownerBounds.height;
+
+ calloutMaxWidth = maxW;
+ calloutMaxHeight = maxH;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function determineArrowPosition(horizontalPos:String, verticalPos:String):String
+ {
+ // Determine arrow direction, outer positions get priority.
+ // Corner positions and center show no arrow
+ var direction:String = ArrowDirection.NONE;
+
+ if (horizontalPos == CalloutPosition.BEFORE)
+ {
+ if ((verticalPos != CalloutPosition.BEFORE)
+ && (verticalPos != CalloutPosition.AFTER))
+ {
+ direction = ArrowDirection.RIGHT;
+ }
+ }
+ else if (horizontalPos == CalloutPosition.AFTER)
+ {
+ if ((verticalPos != CalloutPosition.BEFORE)
+ && (verticalPos != CalloutPosition.AFTER))
+ {
+ direction = ArrowDirection.LEFT;
+ }
+ }
+ else if (verticalPos == CalloutPosition.BEFORE)
+ {
+ direction = ArrowDirection.DOWN;
+ }
+ else if (verticalPos == CalloutPosition.AFTER)
+ {
+ direction = ArrowDirection.UP;
+ }
+ else if (horizontalPos == CalloutPosition.START)
+ {
+ direction = ArrowDirection.LEFT;
+ }
+ else if (horizontalPos == CalloutPosition.END)
+ {
+ direction = ArrowDirection.RIGHT;
+ }
+ else if (verticalPos == CalloutPosition.START)
+ {
+ direction = ArrowDirection.UP;
+ }
+ else if (verticalPos == CalloutPosition.END)
+ {
+ direction = ArrowDirection.DOWN;
+ }
+
+ return direction
+ }
+
+ /**
+ * @private
+ *
+ * Uses horizontalPosition and verticalPosition to determine the bounds of
+ * the callout.
+ */
+ mx_internal function determinePosition(horizontalPos:String, verticalPos:String,
+ matrix:Matrix, registrationPoint:Point):Rectangle
+ {
+ var ownerVisualElement:ILayoutElement = owner as ILayoutElement;
+ var ownerWidth:Number = (ownerVisualElement) ? ownerVisualElement.getLayoutBoundsWidth() : owner.width;
+ var ownerHeight:Number = (ownerVisualElement) ? ownerVisualElement.getLayoutBoundsHeight() : owner.height;
+ var calloutWidth:Number = getLayoutBoundsWidth();
+ var calloutHeight:Number = this.calloutHeight;
+
+ switch (horizontalPos)
+ {
+ case CalloutPosition.BEFORE:
+ {
+ // The full width of the callout is before the owner
+ // All arrow directions are ArrowDirection.RIGHT x=(width - arrow.width)
+ registrationPoint.x = -calloutWidth;
+ break;
+ }
+ case CalloutPosition.START:
+ {
+ // ArrowDirection.LEFT is at x=0
+ registrationPoint.x = 0;
+ break;
+ }
+ case CalloutPosition.END:
+ {
+ // The ends of the owner and callout are aligned
+ registrationPoint.x = (ownerWidth - calloutWidth);
+ break;
+ }
+ case CalloutPosition.AFTER:
+ {
+ // The full width of the callout is after the owner
+ // All arrow directions are ArrowDirection.LEFT (x=0)
+ registrationPoint.x = ownerWidth;
+ break;
+ }
+ default: // case CalloutPosition.MIDDLE:
+ {
+ registrationPoint.x = Math.floor((ownerWidth - calloutWidth) / 2);
+ break;
+ }
+ }
+
+ switch (verticalPos)
+ {
+ case CalloutPosition.BEFORE:
+ {
+ // The full height of the callout is before the owner
+ // All arrow directions are ArrowDirection.DOWN y=(height - arrow.height)
+ registrationPoint.y = -calloutHeight;
+ break;
+ }
+ case CalloutPosition.START:
+ {
+ // ArrowDirection.UP is at y=0
+ registrationPoint.y = 0;
+ break;
+ }
+ case CalloutPosition.MIDDLE:
+ {
+ registrationPoint.y = Math.floor((ownerHeight - calloutHeight) / 2);
+ break;
+ }
+ case CalloutPosition.END:
+ {
+ // The ends of the owner and callout are aligned
+ registrationPoint.y = (ownerHeight - calloutHeight);
+ break;
+ }
+ default: //case CalloutPosition.AFTER:
+ {
+ // The full height of the callout is after the owner
+ // All arrow directions are ArrowDirection.UP (y=0)
+ registrationPoint.y = ownerHeight;
+ break;
+ }
+ }
+
+ var topLeft:Point = registrationPoint.clone();
+ var size:Point = MatrixUtil.transformBounds(calloutWidth, calloutHeight, matrix, topLeft);
+ var bounds:Rectangle = new Rectangle();
+
+ bounds.left = topLeft.x;
+ bounds.top = topLeft.y;
+ bounds.width = size.x;
+ bounds.height = size.y;
+
+ return bounds;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function get isArrowVertical():Boolean
+ {
+ return (arrowDirection == ArrowDirection.UP ||
+ arrowDirection == ArrowDirection.DOWN);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Event handlers
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private function arrow_resizeHandler(event:Event):void
+ {
+ updateSkinDisplayList();
+ }
+
+ /**
+ * @private
+ */
+ private function systemManager_resizeHandler(event:Event):void
+ {
+ // Remove explicit settings if due to Resize effect
+ softKeyboardEffectResetExplicitSize();
+
+ // Screen resize might require a new arrow direction and callout position
+ invalidatePosition();
+
+ if (!isSoftKeyboardEffectActive)
+ {
+ // Force validation and use new screen size only if the keyboard
+ // effect is not active. The stage dimensions may be invalid while
+ // the soft keyboard is active. See SDK-31860.
+ validateNow();
+ }
+ }
+}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/components/Callout.png
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/Callout.png b/frameworks/projects/spark/src/spark/components/Callout.png
new file mode 100644
index 0000000..36bc882
Binary files /dev/null and b/frameworks/projects/spark/src/spark/components/Callout.png differ
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/components/CalloutButton.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/CalloutButton.as b/frameworks/projects/spark/src/spark/components/CalloutButton.as
new file mode 100644
index 0000000..7eec462
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/components/CalloutButton.as
@@ -0,0 +1,807 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.components
+{
+import flash.events.Event;
+
+import mx.core.ClassFactory;
+import mx.core.IFactory;
+import mx.core.mx_internal;
+import mx.utils.BitFlagUtil;
+
+import spark.components.supportClasses.DropDownController;
+import spark.core.ContainerDestructionPolicy;
+import spark.events.DropDownEvent;
+import spark.events.PopUpEvent;
+import spark.layouts.supportClasses.LayoutBase;
+
+use namespace mx_internal;
+
+//--------------------------------------
+// Styles
+//--------------------------------------
+
+[Exclude(name="repeatDelay", kind="style")]
+[Exclude(name="repeatInterval", kind="style")]
+
+//--------------------------------------
+// Events
+//--------------------------------------
+
+/**
+ * Dispatched when the callout closes for any reason, such when:
+ * <ul>
+ * <li>The callout is programmatically closed.</li>
+ * <li>The user clicks outside of the callout.</li>
+ * <li>The user clicks the open button while the callout is
+ * displayed.</li>
+ * </ul>
+ *
+ * @eventType spark.events.DropDownEvent.CLOSE
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+[Event(name="close", type="spark.events.DropDownEvent")]
+
+/**
+ * Dispatched when the user clicks the open button
+ * to display the callout.
+ *
+ * @eventType spark.events.DropDownEvent.OPEN
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+[Event(name="open", type="spark.events.DropDownEvent")]
+
+//--------------------------------------
+// Other metadata
+//--------------------------------------
+
+[IconFile("Callout.png")]
+
+[DefaultProperty("calloutContent")]
+
+/**
+ * The CalloutButton control is a drop down component that defines a button to
+ * open and close a Callout container.
+ * The CalloutButton specifies the layout and child components
+ * of the Callout container.
+ *
+ * <p>The following image shows a Callout container under the CalloutButton
+ * labeled 'Open callout':</p>
+ *
+ * <p>
+ * <img src="../../images/ca_calloutButton_ca.png" alt="Callout button" />
+ * </p>
+ *
+ * <p>The CalloutButton control uses the spark.components.supportClasses.DropDownController
+ * class to manage the Callout container.
+ * You can access the DropDownController by using the protected
+ * <code>CalloutButton.dropDownController</code> property.</p>
+ *
+ * <p>When the callout is open:</p>
+ * <ul>
+ * <li>Clicking the button closes the callout</li>
+ * <li>Clicking outside of the callout closes the callout.</li>
+ * </ul>
+ *
+ * <p>The CalloutButton component has the following default characteristics:</p>
+ * <table class="innertable">
+ * <tr>
+ * <th>Characteristic</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>Default size</td>
+ * <td>Wide enough to display the text label of the control</td>
+ * </tr>
+ * <tr>
+ * <td>Minimum size</td>
+ * <td>32 pixels wide and 43 pixels high</td>
+ * </tr>
+ * <tr>
+ * <td>Maximum size</td>
+ * <td>10000 pixels wide and 10000 pixels high</td>
+ * </tr>
+ * <tr>
+ * <td>Default skin class</td>
+ * <td>spark.skins.mobile.CalloutButtonSkin</td>
+ * </tr>
+ * </table>
+ *
+ * @mxml
+ *
+ * <p>The <code><s:CalloutButton></code> tag inherits all of the tag
+ * attributes of its superclass and adds the following tag attributes:</p>
+ *
+ * <pre>
+ * <s:CalloutButton
+ * <strong>Properties</strong>
+ * calloutDestructionPolicy="auto"
+ * calloutLayout="BasicLayout"
+ * horizontalPosition="auto"
+ * verticalPosition="auto
+ *
+ * <strong>Events</strong>
+ * open="<i>No default</i>"
+ * close="<i>No default</i>"
+ * ...
+ * <i>child tags</i>
+ * ...
+ * </s:CalloutButton>
+ * </pre>
+ *
+ * @see spark.components.Callout
+ * @see spark.components.Button
+ * @see spark.components.supportClasses.DropDownController
+ *
+ * @includeExample examples/CalloutButtonExample.mxml -noswf
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public class CalloutButton extends Button
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ mx_internal static const CALLOUT_CONTENT_PROPERTY_FLAG:uint = 1 << 0;
+
+ /**
+ * @private
+ */
+ mx_internal static const CALLOUT_LAYOUT_PROPERTY_FLAG:uint = 1 << 1;
+
+ /**
+ * @private
+ */
+ mx_internal static const HORIZONTAL_POSITION_PROPERTY_FLAG:uint = 1 << 2;
+
+ /**
+ * @private
+ */
+ mx_internal static const VERTICAL_POSITION_PROPERTY_FLAG:uint = 1 << 3;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function CalloutButton()
+ {
+ super();
+
+ dropDownController = new DropDownController();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Skin parts
+ //
+ //--------------------------------------------------------------------------
+
+ [SkinPart(required="false")]
+
+ /**
+ * A skin part that defines the drop-down factory which creates the Callout
+ * instance.
+ *
+ * If <code>dropDown</code> is not defined on the skin, a
+ * <code>ClassFactory</code> is created to generate a default Callout
+ * instance.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public var dropDown:IFactory;
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Several properties are proxied to callout. However, when callout
+ * is not around, we need to store values set on CalloutButton. This object
+ * stores those values. If callout is around, the values are stored
+ * on the callout directly. However, we need to know what values
+ * have been set by the developer on the CalloutButton (versus set on
+ * the callout or defaults of the callout) as those are values
+ * we want to carry around if the callout changes (via a new skin).
+ * In order to store this info effeciently, calloutProperties becomes
+ * a uint to store a series of BitFlags. These bits represent whether a
+ * property has been explicitely set on this CalloutButton. When the
+ * callout is not around, calloutProperties is a typeless
+ * object to store these proxied properties. When callout is around,
+ * calloutProperties stores booleans as to whether these properties
+ * have been explicitely set or not.
+ */
+ mx_internal var calloutProperties:Object = {};
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties proxied to callout
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // calloutContent
+ //----------------------------------
+
+ [ArrayElementType("mx.core.IVisualElement")]
+
+ /**
+ * The set of components to include in the Callout's content.
+ *
+ * @default null
+ *
+ * @see spark.components.Callout
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get calloutContent():Array
+ {
+ if (callout && callout.contentGroup)
+ return callout.contentGroup.getMXMLContent();
+ else
+ return calloutProperties.calloutContent;
+ }
+
+ /**
+ * @private
+ */
+ public function set calloutContent(value:Array):void
+ {
+ if (callout)
+ {
+ callout.mxmlContent = value;
+ calloutProperties = BitFlagUtil.update(calloutProperties as uint,
+ CALLOUT_CONTENT_PROPERTY_FLAG, value != null);
+ }
+ else
+ calloutProperties.calloutContent = value;
+ }
+
+ //----------------------------------
+ // calloutLayout
+ //----------------------------------
+
+ /**
+ * Defines the layout of the Callout container.
+ *
+ * @default BasicLayout
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get calloutLayout():LayoutBase
+ {
+ return (callout) ? callout.layout : calloutProperties.calloutLayout;
+ }
+
+ /**
+ * @private
+ */
+ public function set calloutLayout(value:LayoutBase):void
+ {
+ if (callout)
+ {
+ callout.layout = value;
+ calloutProperties = BitFlagUtil.update(calloutProperties as uint,
+ CALLOUT_LAYOUT_PROPERTY_FLAG, true);
+ }
+ else
+ calloutProperties.calloutLayout = value;
+ }
+
+ //----------------------------------
+ // horizontalPosition
+ //----------------------------------
+
+ [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
+
+ /**
+ * @copy spark.components.Callout#horizontalPosition
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get horizontalPosition():String
+ {
+ if (callout)
+ return callout.horizontalPosition;
+
+ return calloutProperties.horizontalPosition;
+ }
+
+ /**
+ * @private
+ */
+ public function set horizontalPosition(value:String):void
+ {
+ if (callout)
+ {
+ callout.horizontalPosition = value;
+ calloutProperties = BitFlagUtil.update(calloutProperties as uint,
+ HORIZONTAL_POSITION_PROPERTY_FLAG, value != null);
+ }
+ else
+ calloutProperties.horizontalPosition = value;
+ }
+
+ //----------------------------------
+ // verticalPosition
+ //----------------------------------
+
+ [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
+
+ /**
+ * @copy spark.components.Callout#verticalPosition
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get verticalPosition():String
+ {
+ if (callout)
+ return callout.verticalPosition;
+
+ return calloutProperties.verticalPosition;
+ }
+
+ /**
+ * @private
+ */
+ public function set verticalPosition(value:String):void
+ {
+ if (callout)
+ {
+ callout.verticalPosition = value;
+ calloutProperties = BitFlagUtil.update(calloutProperties as uint,
+ VERTICAL_POSITION_PROPERTY_FLAG, value != null);
+ }
+ else
+ calloutProperties.verticalPosition = value;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // callout
+ //----------------------------------
+
+ /**
+ * @private
+ */
+ private var _callout:Callout;
+
+ [Bindable("calloutChanged")]
+
+ /**
+ * The Callout instance created after the <code>DropDownEvent.OPEN</code>
+ * is fired. The instance is created using the <code>dropDown</code>
+ * <code>IFactory</code> skin part.
+ *
+ * @see #calloutDestructionPolicy
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get callout():Callout
+ {
+ return _callout;
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function setCallout(value:Callout):void
+ {
+ if (_callout == value)
+ return;
+
+ _callout = value;
+
+ if (hasEventListener("calloutChanged"))
+ dispatchEvent(new Event("calloutChanged"));
+ }
+
+ //----------------------------------
+ // dropDownController
+ //----------------------------------
+
+ /**
+ * @private
+ */
+ private var _dropDownController:DropDownController;
+
+ /**
+ * Instance of the DropDownController class that handles all of the mouse, keyboard
+ * and focus user interactions.
+ *
+ * Flex calls the <code>initializeDropDownController()</code> method after
+ * the DropDownController instance is created in the constructor.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ protected function get dropDownController():DropDownController
+ {
+ return _dropDownController;
+ }
+
+ /**
+ * @private
+ */
+ protected function set dropDownController(value:DropDownController):void
+ {
+ if (_dropDownController == value)
+ return;
+
+ _dropDownController = value;
+
+ _dropDownController.closeOnResize = false;
+ _dropDownController.addEventListener(DropDownEvent.OPEN, dropDownController_openHandler);
+ _dropDownController.addEventListener(DropDownEvent.CLOSE, dropDownController_closeHandler);
+
+ _dropDownController.openButton = this;
+
+ if (callout)
+ _dropDownController.dropDown = callout;
+ }
+
+ //----------------------------------
+ // isDropDownOpen
+ //----------------------------------
+
+ /**
+ * @copy spark.components.supportClasses.DropDownController#isOpen
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get isDropDownOpen():Boolean
+ {
+ if (dropDownController)
+ return dropDownController.isOpen;
+ else
+ return false;
+ }
+
+ //----------------------------------
+ // calloutDestructionPolicy
+ //----------------------------------
+
+ private var _calloutDestructionPolicy:String = ContainerDestructionPolicy.AUTO;
+
+ [Inspectable(category="General", enumeration="auto,never", defaultValue="auto")]
+
+ /**
+ * Defines the destruction policy the callout button uses
+ * when the callout is closed.
+ * If set to <code>"auto"</code>, the button
+ * destroys the Callout instance when it is closed.
+ * If set to <code>"never"</code>, the Callout container
+ * is cached in memory.
+ *
+ * @default auto
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function get calloutDestructionPolicy():String
+ {
+ return _calloutDestructionPolicy;
+ }
+
+ /**
+ * @private
+ */
+ public function set calloutDestructionPolicy(value:String):void
+ {
+ if (_calloutDestructionPolicy == value)
+ return;
+
+ _calloutDestructionPolicy = value;
+
+ // destroy the callout immediately if currently closed
+ if (!isDropDownOpen &&
+ (calloutDestructionPolicy == ContainerDestructionPolicy.AUTO))
+ {
+ destroyCallout();
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ override protected function attachSkin():void
+ {
+ super.attachSkin();
+
+ // create dropDown if it was not found in the skin
+ if (!dropDown && !("dropDown" in skin))
+ dropDown = new ClassFactory(Callout);
+ }
+
+ /**
+ * @private
+ */
+ override protected function partAdded(partName:String, instance:Object):void
+ {
+ super.partAdded(partName, instance);
+
+ if (partName == "dropDown")
+ {
+ // copy proxied values from calloutProperties (if set) to callout
+ var newCalloutProperties:uint = 0;
+ var calloutInstance:Callout = instance as Callout;
+
+ if (calloutInstance && dropDownController)
+ {
+ calloutInstance.id = "callout";
+ dropDownController.dropDown = calloutInstance;
+
+ calloutInstance.addEventListener(PopUpEvent.OPEN, callout_openHandler);
+ calloutInstance.addEventListener(PopUpEvent.CLOSE, callout_closeHandler);
+
+ if (calloutProperties.calloutContent !== undefined)
+ {
+ calloutInstance.mxmlContent = calloutProperties.calloutContent;
+ newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
+ CALLOUT_CONTENT_PROPERTY_FLAG, true);
+ }
+
+ if (calloutProperties.calloutLayout !== undefined)
+ {
+ calloutInstance.layout = calloutProperties.calloutLayout;
+ newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
+ CALLOUT_LAYOUT_PROPERTY_FLAG, true);
+ }
+
+ if (calloutProperties.horizontalPosition !== undefined)
+ {
+ calloutInstance.horizontalPosition = calloutProperties.horizontalPosition;
+ newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
+ HORIZONTAL_POSITION_PROPERTY_FLAG, true);
+ }
+
+ if (calloutProperties.verticalPosition !== undefined)
+ {
+ calloutInstance.verticalPosition = calloutProperties.verticalPosition;
+ newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
+ VERTICAL_POSITION_PROPERTY_FLAG, true);
+ }
+
+ calloutProperties = newCalloutProperties;
+ }
+ }
+ }
+
+ /**
+ * @private
+ */
+ override protected function partRemoved(partName:String, instance:Object):void
+ {
+ if (dropDownController && (instance == callout))
+ {
+ dropDownController.dropDown = null;
+ }
+
+ if (partName == "dropDown")
+ {
+ callout.removeEventListener(PopUpEvent.OPEN, callout_openHandler);
+ callout.removeEventListener(PopUpEvent.CLOSE, callout_closeHandler);
+
+ // copy proxied values from callout (if explicitely set) to calloutProperties
+ var newCalloutProperties:Object = {};
+
+ if (BitFlagUtil.isSet(calloutProperties as uint, CALLOUT_CONTENT_PROPERTY_FLAG) &&
+ (callout.contentGroup))
+ {
+ newCalloutProperties.calloutContent = callout.contentGroup.getMXMLContent();
+ callout.contentGroup.mxmlContent = null;
+ }
+
+ if (BitFlagUtil.isSet(calloutProperties as uint, CALLOUT_LAYOUT_PROPERTY_FLAG))
+ {
+ newCalloutProperties.calloutLayout = callout.layout;
+ callout.layout = null;
+ }
+
+ if (BitFlagUtil.isSet(calloutProperties as uint, HORIZONTAL_POSITION_PROPERTY_FLAG))
+ newCalloutProperties.horizontalPosition = callout.horizontalPosition;
+
+ if (BitFlagUtil.isSet(calloutProperties as uint, VERTICAL_POSITION_PROPERTY_FLAG))
+ newCalloutProperties.verticalPosition = callout.verticalPosition;
+
+ calloutProperties = newCalloutProperties;
+ }
+
+ super.partRemoved(partName, instance);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Initializes the dropDown and changes the skin state to open.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function openDropDown():void
+ {
+ dropDownController.openDropDown();
+ }
+
+ /**
+ * Changes the skin state to normal.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public function closeDropDown():void
+ {
+ dropDownController.closeDropDown(false);
+ }
+
+ /**
+ * @private
+ * Destroys the callout
+ */
+ private function destroyCallout():void
+ {
+ removeDynamicPartInstance("dropDown", callout);
+ setCallout(null);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Event handlers
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Event handler for the <code>dropDownController</code>
+ * <code>DropDownEvent.OPEN</code> event. Creates and opens the Callout.
+ */
+ mx_internal function dropDownController_openHandler(event:DropDownEvent):void
+ {
+ if (!callout)
+ setCallout(createDynamicPartInstance("dropDown") as Callout);
+
+ if (callout)
+ {
+ // close the callout if the CalloutButton is removed
+ addEventListener(Event.REMOVED_FROM_STAGE, button_removedFromStage);
+
+ callout.open(this, false);
+ }
+ }
+
+ /**
+ * @private
+ * Event handler for the <code>dropDownController</code>
+ * <code>DropDownEvent.CLOSE</code> event. Closes the Callout.
+ */
+ mx_internal function dropDownController_closeHandler(event:DropDownEvent):void
+ {
+ // If the callout was closed directly, then callout could already be
+ // destroyed by calloutDestructionPolicy
+ if (callout)
+ {
+ removeEventListener(Event.REMOVED_FROM_STAGE, button_removedFromStage);
+
+ // Dispatch the close event after the callout's PopUpEvent.CLOSE fires
+ callout.close();
+ }
+ }
+
+ /**
+ * @private
+ */
+ private function callout_openHandler(event:PopUpEvent):void
+ {
+ dispatchEvent(new DropDownEvent(DropDownEvent.OPEN));
+ }
+
+ /**
+ * @private
+ */
+ private function callout_closeHandler(event:PopUpEvent):void
+ {
+ // Sanity check. Was callout closed without calling closeDropDown()?
+ // If so, call closeDropDown directly to remove event listeners. This
+ // callout_closeHandler will only be called once since the 2nd call
+ // to close() in dropDownController_closeHandler() will not dispatch
+ // another PopUpEvent.CLOSE.
+ if (dropDownController.isOpen)
+ closeDropDown();
+
+ if (calloutDestructionPolicy == ContainerDestructionPolicy.AUTO)
+ destroyCallout();
+
+ dispatchEvent(new DropDownEvent(DropDownEvent.CLOSE));
+ }
+
+ /**
+ * @private
+ */
+ private function button_removedFromStage(event:Event):void
+ {
+ if (!isDropDownOpen)
+ return;
+
+ // Hide the callout immediately instead of waiting for the skin
+ // state to transition to "closed"
+ callout.visible = false;
+
+ closeDropDown();
+ }
+}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/components/CalloutPosition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/CalloutPosition.as b/frameworks/projects/spark/src/spark/components/CalloutPosition.as
new file mode 100644
index 0000000..a0b6e7d
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/components/CalloutPosition.as
@@ -0,0 +1,96 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.components
+{
+
+/**
+ * The CalloutPosition calss defines the enumeration of
+ * horizontal and vertical positions of the Callout component
+ * relative to the owner.
+ *
+ * @see spark.components.Callout
+ * @see spark.components.Callout#horizontalPosition
+ * @see spark.components.Callout#verticalPosition
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public final class CalloutPosition
+{
+
+ /**
+ * Position the trailing edge of the callout before the leading edge of the owner.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const BEFORE:String = "before";
+
+ /**
+ * Position the leading edge of the callout at the leading edge of the owner.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const START:String = "start";
+
+ /**
+ * Position the horizontalCenter of the callout to the horizontalCenter of the owner.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const MIDDLE:String = "middle";
+
+ /**
+ * Position the trailing edge of the callout at the trailing edge of the owner.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const END:String = "end";
+
+ /**
+ * Position the leading edge of the callout after the trailing edge of the owner.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const AFTER:String = "after";
+
+ /**
+ * Position the callout on the exterior of the owner where the callout
+ * requires the least amount of resizing to fit.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const AUTO:String = "auto";
+
+}
+
+}
\ No newline at end of file
[7/8] git commit: [flex-sdk] [refs/heads/callout] - FIXED
https://issues.apache.org/jira/browse/FLEX-33350 - mobile Callout moved to
spark - Added borderColor and borderThickness styles to Callout - Desktop &
Mobile Callout uses same s:Callout - MobileSk
Posted by ma...@apache.org.
FIXED https://issues.apache.org/jira/browse/FLEX-33350
- mobile Callout moved to spark
- Added borderColor and borderThickness styles to Callout
- Desktop & Mobile Callout uses same s:Callout
- MobileSkin refactored
- new ActionScriptSkinBase class takes 99% of MobileSkin, and belongs to spark
- MobileSkin inherts from ActionScriptSkinBase with few overriddes
- New skin for desktop Callout = spark.skins.spark.CalloutSkin
- inherits from ActionScriptSkinBase
- duplicated from mobile skin (pure AS skin)
- with different css settings: lighter frame, and dark gray 1px border
- Limitation: CalloutSkin not a SparkSkin (chromeColor has no effect)
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/074354ca
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/074354ca
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/074354ca
Branch: refs/heads/callout
Commit: 074354ca2b78db404009bf3cf23dadb8045d7615
Parents: 3e23c76
Author: mamsellem <ma...@systar.com>
Authored: Tue Oct 8 02:23:46 2013 +0200
Committer: mamsellem <ma...@systar.com>
Committed: Tue Oct 8 02:23:46 2013 +0200
----------------------------------------------------------------------
.../src/spark/skins/mobile/CalloutSkin.as | 4 +
.../skins/mobile/supportClasses/CalloutArrow.as | 19 +-
.../skins/mobile/supportClasses/MobileSkin.as | 756 +---------------
frameworks/projects/spark/defaults.css | 10 +
frameworks/projects/spark/src/SparkClasses.as | 2 +
.../spark/src/spark/components/Callout.as | 25 +
.../src/spark/skins/ActionScriptSkinBase.as | 853 +++++++++++++++++++
.../spark/src/spark/skins/spark/CalloutSkin.as | 743 ++++++++++++++++
.../spark/assets/CalloutContentBackground.fxg | 51 ++
.../skins/spark/supportClasses/CalloutArrow.as | 423 +++++++++
10 files changed, 2121 insertions(+), 765 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
index b76696c..364327d 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/CalloutSkin.as
@@ -407,6 +407,10 @@ public class CalloutSkin extends MobileSkin
contentGroup.id = "contentGroup";
addChild(contentGroup);
}
+
+ borderThickness = getStyle("borderThickness");
+ borderColor = getStyle("borderColor");
+
}
/**
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
index 35f8757..453068c 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
@@ -36,7 +36,6 @@ import mx.utils.ColorUtil;
import spark.components.Application;
import spark.components.ArrowDirection;
import spark.components.Callout;
-import spark.core.SpriteVisualElement;
import spark.skins.mobile.CalloutSkin;
use namespace mx_internal;
@@ -148,16 +147,7 @@ public class CalloutArrow extends UIComponent
*/
protected var useBackgroundGradient:Boolean;
- /**
- * @copy spark.skins.mobile.CalloutSkin#borderColor
- */
- protected var borderColor:Number;
-
- /**
- * @copy spark.skins.mobile.CalloutSkin#borderThickness
- */
- protected var borderThickness:Number = NaN;
-
+
/**
* @private
* A sibling of the arrow used to erase the drop shadow in CalloutSkin
@@ -208,8 +198,9 @@ public class CalloutArrow extends UIComponent
var arrowTipY:Number = 0;
var arrowEndX:Number = 0;
var arrowEndY:Number = 0;
-
- var showBorder:Boolean = !isNaN(borderThickness);
+
+ var borderThickness:Number = getStyle("borderThickness");
+ var showBorder:Boolean = !isNaN(borderThickness) && borderThickness > 0;
var borderWeight:Number = showBorder ? borderThickness : 0;
var borderHalf:Number = borderWeight / 2;
var isHorizontal:Boolean = false;
@@ -358,7 +349,7 @@ public class CalloutArrow extends UIComponent
// draw arrow path
if (showBorder)
- arrowGraphics.lineStyle(borderThickness, borderColor, 1, true);
+ arrowGraphics.lineStyle(borderThickness, getStyle("borderColor"), 1, true);
arrowGraphics.drawPath(commands, coords);
arrowGraphics.endFill();
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
index e0abe24..bbaeaf5 100644
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as
@@ -19,24 +19,12 @@
package spark.skins.mobile.supportClasses
{
-import flash.display.DisplayObject;
-import flash.display.GradientType;
-import flash.display.Graphics;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
-import mx.core.FlexGlobals;
-import mx.core.IFlexDisplayObject;
-import mx.core.ILayoutElement;
-import mx.core.UIComponent;
import mx.core.mx_internal;
-import mx.utils.ColorUtil;
-import spark.components.supportClasses.SkinnableComponent;
-import spark.components.supportClasses.StyleableTextField;
-import spark.core.DisplayObjectSharingMode;
-import spark.core.IGraphicElement;
-import spark.skins.IHighlightBitmapCaptureClient;
+import spark.skins.ActionScriptSkinBase;
use namespace mx_internal;
@@ -50,7 +38,7 @@ use namespace mx_internal;
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
-public class MobileSkin extends UIComponent implements IHighlightBitmapCaptureClient
+public class MobileSkin extends ActionScriptSkinBase
{
//--------------------------------------------------------------------------
//
@@ -94,60 +82,10 @@ public class MobileSkin extends UIComponent implements IHighlightBitmapCaptureCl
*/
public function MobileSkin()
{
+ useMinimumHitArea = true;
}
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * Specifies whether or not this skin should be affected by the <code>symbolColor</code> style.
- *
- * @default false
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected var useSymbolColor:Boolean = false;
-
- /**
- * @private
- * Toggles transparent, centered hit-area if the unscaled size is less
- * than one-quarter inch square. Physical size is based on applicationDPI.
- */
- mx_internal var useMinimumHitArea:Boolean = true;
-
- /**
- * Specifies a default width. <code>measuredWidth</code> returns this value
- * when the computed <code>measuredWidth</code> is less than
- * <code>measuredDefaultWidth</code>.
- *
- * @default 0
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected var measuredDefaultWidth:Number = 0;
-
- /**
- * Specifies a default height. <code>measuredHeight</code> returns this value
- * when the computed <code>measuredHeight</code> is less than
- * <code>measuredDefaultHeight</code>.
- *
- * @default 0
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected var measuredDefaultHeight:Number = 0;
+
//----------------------------------
// colorMatrix
@@ -183,691 +121,7 @@ public class MobileSkin extends UIComponent implements IHighlightBitmapCaptureCl
return _colorTransform;
}
- //----------------------------------
- // applicationDPI
- //----------------------------------
- /**
- * Returns the DPI of the application. This property can only be set in MXML on the root application.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function get applicationDPI():Number
- {
- return FlexGlobals.topLevelApplication.applicationDPI;
- }
-
- //----------------------------------
- // symbolItems
- //----------------------------------
-
- /**
- * Names of items that should have their <code>color</code> property defined by
- * the <code>symbolColor</code> style.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 1.5
- * @productversion Flex 4
- */
- protected function get symbolItems():Array
- {
- return null;
- }
-
- //----------------------------------
- // currentState
- //----------------------------------
-
- private var _currentState:String;
-
- /**
- * @private
- */
- override public function get currentState():String
- {
- return _currentState;
- }
-
- /**
- * @private
- */
- override public function set currentState(value:String):void
- {
- if (value != _currentState)
- {
- _currentState = value;
- commitCurrentState();
- }
- }
-
- /**
- * Called whenever the currentState changes. Skins should override
- * this function if they make any appearance changes during
- * a state change.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function commitCurrentState():void
- {
- }
-
- /**
- * MobileSkin does not use states. Skins should override this function
- * to return false for states that are not implemented.
- *
- * @param stateName The state name.
- *
- * @return false for states that are not implemented.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- override public function hasState(stateName:String):Boolean
- {
- return true;
- }
-
- /**
- * @private
- */
- override public function setCurrentState(stateName:String,
- playTransition:Boolean = true):void
- {
- currentState = stateName;
- }
-
- /**
- * @private
- */
- override public function get measuredWidth():Number
- {
- return Math.max(super.measuredWidth, measuredDefaultWidth);
- }
-
- /**
- * @private
- */
- override public function get measuredHeight():Number
- {
- return Math.max(super.measuredHeight, measuredDefaultHeight);
- }
-
- /**
- * @private
- */
- override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
- {
- graphics.clear();
-
- super.updateDisplayList(unscaledWidth, unscaledHeight);
-
- layoutContents(unscaledWidth, unscaledHeight);
-
- if (useSymbolColor)
- applySymbolColor();
-
- if (useMinimumHitArea)
- drawMinimumHitArea(unscaledWidth, unscaledHeight);
-
- drawBackground(unscaledWidth, unscaledHeight);
- }
-
- /**
- * @private
- * Make the component's explicitMinWidth property override its skin's.
- * This is useful for cases where the skin's minWidth constrains
- * the skin's measured size. In those cases the user could set
- * explicit limits on the component itself thus relaxing the
- * hard-coded limits in the skin. See SDK-24741.
- */
- override public function get explicitMinWidth():Number
- {
- if (parent is SkinnableComponent)
- {
- var parentExplicitMinWidth:Number = SkinnableComponent(parent).explicitMinWidth;
- if (!isNaN(parentExplicitMinWidth))
- return parentExplicitMinWidth;
- }
- return super.explicitMinWidth;
- }
-
- /**
- * @private
- * Make the component's explicitMinWidth property override its skin's.
- * This is useful for cases where the skin's minWidth constrains
- * the skin's measured size. In those cases the user could set
- * explicit limits on the component itself thus relaxing the
- * hard-coded limits in the skin. See SDK-24741.
- */
- override public function get explicitMinHeight():Number
- {
- if (parent is SkinnableComponent)
- {
- var parentExplicitMinHeight:Number = SkinnableComponent(parent).explicitMinHeight;
- if (!isNaN(parentExplicitMinHeight))
- return parentExplicitMinHeight;
- }
- return super.explicitMinHeight;
- }
-
- /**
- * @private
- * Make the component's explicitMinWidth property override its skin's.
- * This is useful for cases where the skin's minWidth constrains
- * the skin's measured size. In those cases the user could set
- * explicit limits on the component itself thus relaxing the
- * hard-coded limits in the skin. See SDK-24741.
- */
- override public function get explicitMaxWidth():Number
- {
- if (parent is SkinnableComponent)
- {
- var parentExplicitMaxWidth:Number = SkinnableComponent(parent).explicitMaxWidth;
- if (!isNaN(parentExplicitMaxWidth))
- return parentExplicitMaxWidth;
- }
- return super.explicitMaxWidth;
- }
-
- /**
- * @private
- * Make the component's explicitMinWidth property override its skin's.
- * This is useful for cases where the skin's minWidth constrains
- * the skin's measured size. In those cases the user could set
- * explicit limits on the component itself thus relaxing the
- * hard-coded limits in the skin. See SDK-24741.
- */
- override public function get explicitMaxHeight():Number
- {
- if (parent is SkinnableComponent)
- {
- var parentExplicitMaxHeight:Number = SkinnableComponent(parent).explicitMaxHeight;
- if (!isNaN(parentExplicitMaxHeight))
- return parentExplicitMaxHeight;
- }
- return super.explicitMaxHeight;
- }
-
- //--------------------------------------------------------------------------
- //
- // Class methods
- //
- //--------------------------------------------------------------------------
-
- mx_internal function drawMinimumHitArea(unscaledWidth:Number, unscaledHeight:Number):void
- {
- // minimum hit area is 0.25 inches square
- var minSize:Number = applicationDPI / 4;
-
- // skip if skin size is larger than minimum
- if ((unscaledWidth > minSize) && (unscaledHeight > minSize))
- return;
-
- // center a transparent hit area larger than the skin
- var hitAreaWidth:Number = Math.max(minSize, unscaledWidth);
- var hitAreaHeight:Number = Math.max(minSize, unscaledHeight);
- var hitAreaX:Number = (unscaledWidth - hitAreaWidth) / 2;
- var hitAreaY:Number = (unscaledHeight - hitAreaHeight) / 2;
-
- graphics.beginFill(0, 0);
- graphics.drawRect(hitAreaX, hitAreaY, hitAreaWidth, hitAreaHeight);
- graphics.endFill();
- }
-
- /**
- * Positions the children for this skin.
- *
- * <p>This method, along with <code>colorizeContents()</code>, is called
- * by the <code>updateDisplayList()</code> method.</p>
- *
- * <p>This method positions skin parts and graphic children of the skin.
- * Subclasses should override this to position their children.</p>
- *
- * @param unscaledWidth Specifies the width of the component, in pixels,
- * in the component's coordinates, regardless of the value of the
- * <code>scaleX</code> property of the component.
- *
- * @param unscaledHeight Specifies the height of the component, in pixels,
- * in the component's coordinates, regardless of the value of the
- * <code>scaleY</code> property of the component.
- *
- * @langversion 3.0
- * @playerversion Flash 10.1
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
- {
-
- }
-
- /**
- * A helper method to set a color transform on a DisplayObject.
- *
- * @param displayObject The display object to transform
- * @param originalColor The original color
- * @param tintColor The desired color
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function applyColorTransform(displayObject:DisplayObject, originalColor:uint, tintColor:uint):void
- {
- colorTransform.redOffset = ((tintColor & (0xFF << 16)) >> 16) - ((originalColor & (0xFF << 16)) >> 16);
- colorTransform.greenOffset = ((tintColor & (0xFF << 8)) >> 8) - ((originalColor & (0xFF << 8)) >> 8);
- colorTransform.blueOffset = (tintColor & 0xFF) - (originalColor & 0xFF);
- colorTransform.alphaMultiplier = alpha;
-
- displayObject.transform.colorTransform = colorTransform;
- }
-
- /**
- * Renders a background for the skin.
- *
- * <p>This method, along with <code>layoutContents()</code>, is called
- * by the <code>updateDisplayList()</code>.</p>
- *
- * <p>This method draws the background chromeColor.
- * Override this method to change the appearance of the chromeColor.</p>
- *
- * @param unscaledWidth Specifies the width of the component, in pixels,
- * in the component's coordinates, regardless of the value of the
- * <code>scaleX</code> property of the component.
- *
- * @param unscaledHeight Specifies the height of the component, in pixels,
- * in the component's coordinates, regardless of the value of the
- * <code>scaleY</code> property of the component.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
- {
-
- }
-
- /**
- * @private
- */
- mx_internal function applySymbolColor():void
- {
- var symbols:Array = symbolItems;
- var len:uint = (symbols) ? symbols.length : 0;
-
- if (len > 0)
- {
- var symbolColor:uint = getStyle("symbolColor");
- var symbolObj:Object;
- var transformInitialized:Boolean = false;
-
- for (var i:uint = 0; i < len; i++)
- {
- symbolObj = this[symbols[i]];
-
- // SparkSkin assumed symbols were IFill objects
- // with a color property. MobileSkin instead assumes symbols
- // are DisplayObjects.
- if (symbolObj is DisplayObject)
- {
- if (!transformInitialized)
- {
- colorTransform.redOffset = ((symbolColor & (0xFF << 16)) >> 16) - DEFAULT_SYMBOL_COLOR_VALUE;
- colorTransform.greenOffset = ((symbolColor & (0xFF << 8)) >> 8) - DEFAULT_SYMBOL_COLOR_VALUE;
- colorTransform.blueOffset = (symbolColor & 0xFF) - DEFAULT_SYMBOL_COLOR_VALUE;
- colorTransform.alphaMultiplier = alpha;
-
- transformInitialized = true;
- }
-
- DisplayObject(symbolObj).transform.colorTransform = colorTransform;
- }
- }
- }
- }
-
- /**
- * A helper method to position children elements of this component.
- *
- * <p>This method is the recommended way to position children elements. You can
- * use this method instead of checking for and using
- * various interfaces/classes such as ILayoutElement, IFlexDisplayObject,
- * or StyleableTextField.</p>
- *
- * <p>Call this method after calling <code>setElementSize()</code></p>
- *
- * @param element The child element to position. The element could be an
- * ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
- * DisplayObject.
- *
- * @param x The x-coordinate of the child.
- *
- * @param y The y-coordinate of the child.
- *
- * @see #setElementSize
- *
- * @langversion 3.0
- * @playerversion Flash 10.1
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function setElementPosition(element:Object, x:Number, y:Number):void
- {
- if (element is ILayoutElement)
- {
- ILayoutElement(element).setLayoutBoundsPosition(x, y, false);
- }
- else if (element is IFlexDisplayObject)
- {
- IFlexDisplayObject(element).move(x, y);
- }
- else
- {
- element.x = x;
- element.y = y;
- }
- }
-
- /**
- * A helper method to size children elements of this component.
- *
- * <p>This method is the recommended way to size children elements. You can
- * use this method instead of checking for and using
- * interfaces/classes such as ILayoutElement, IFlexDisplayObject,
- * or StyleableTextField.</p>
- *
- * <p>Call this method before calling the <code>setElementPosition()</code> method.</p>
- *
- * @param element The child element to size. The element could be an
- * ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
- * DisplayObject.
- *
- * @param width The width of the child.
- *
- * @param height The height of the child.
- *
- * @see #setElementPosition
- *
- * @langversion 3.0
- * @playerversion Flash 10.1
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function setElementSize(element:Object, width:Number, height:Number):void
- {
- if (element is ILayoutElement)
- {
- ILayoutElement(element).setLayoutBoundsSize(width, height, false);
- }
- else if (element is IFlexDisplayObject)
- {
- IFlexDisplayObject(element).setActualSize(width, height);
- }
- else
- {
- element.width = width;
- element.height = height;
- }
- }
-
- /**
- * A helper method to retrieve the preferred width of a child element.
- *
- * <p>This method is the recommended way to get a child element's preferred
- * width. You can use this method instead of checking for and using
- * various interfaces/classes such as ILayoutElement, IFlexDisplayObject,
- * or StyleableTextField.</p>
- *
- * @param element The child element to retrieve the width for. The element could
- * be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
- * DisplayObject.
- *
- * @return The child element's preferred width.
- *
- * @see #sizeElement
- * @see #getElementPreferredHeight
- *
- * @langversion 3.0
- * @playerversion Flash 10.1
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function getElementPreferredWidth(element:Object):Number
- {
- if (element is ILayoutElement)
- {
- return ILayoutElement(element).getPreferredBoundsWidth();
- }
- else if (element is IFlexDisplayObject)
- {
- return IFlexDisplayObject(element).measuredWidth;
- }
- else
- {
- return element.width;
- }
- }
-
- /**
- * A helper method to retrieve the preferred height of a child element.
- *
- * <p>This method is the recommended way to get a child element's preferred
- * height. You can use this method instead of checking for and using
- * various interfaces/classes such as ILayoutElement, IFlexDisplayObject,
- * or StyleableTextField.</p>
- *
- * @param element The child element to retrieve the height for. The element could
- * be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
- * DisplayObject.
- *
- * @return The child element's preferred height.
- *
- * @see #sizeElement
- * @see #getElementPreferredWidth
- *
- * @langversion 3.0
- * @playerversion Flash 10.1
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function getElementPreferredHeight(element:Object):Number
- {
- if (element is ILayoutElement)
- {
- return ILayoutElement(element).getPreferredBoundsHeight();
- }
- else if (element is IFlexDisplayObject)
- {
- return IFlexDisplayObject(element).measuredHeight;
- }
- else
- {
- return element.height;
- }
- }
-
- /**
- * List of IDs of items that should be excluded when rendering the focus ring.
- * Only items of type DisplayObject or GraphicElement should be excluded. Items
- * of other types are ignored.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- protected function get focusSkinExclusions():Array
- {
- return null;
- }
-
- private static var exclusionAlphaValues:Array;
-
- private static var oldContentBackgroundAlpha:Number;
-
- private static var contentBackgroundAlphaSetLocally:Boolean;
-
- /**
- * Called before a bitmap capture is made for this skin. The default implementation
- * excludes items in the focusSkinExclusions array.
- *
- * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- public function beginHighlightBitmapCapture():Boolean
- {
- var exclusions:Array = focusSkinExclusions;
- if (!exclusions)
- {
- if (("hostComponent" in this) && this["hostComponent"] is SkinnableComponent)
- exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
- }
- var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
-
- /* we'll store off the previous alpha of the exclusions so we
- can restore them when we're done
- */
- exclusionAlphaValues = [];
- var needRedraw:Boolean = false;
-
- for (var i:int = 0; i < exclusionCount; i++)
- {
- // skip if the part isn't there
- if (!(exclusions[i] in this))
- continue;
-
- var ex:Object = this[exclusions[i]];
- /* we're going to go under the covers here to try and modify alpha with the least
- amount of disruption to the component. For UIComponents, we go to Sprite's alpha property;
- */
- if (ex is UIComponent)
- {
- exclusionAlphaValues[i] = (ex as UIComponent).$alpha;
- (ex as UIComponent).$alpha = 0;
- }
- else if (ex is DisplayObject)
- {
- exclusionAlphaValues[i] = (ex as DisplayObject).alpha;
- (ex as DisplayObject).alpha = 0;
- }
- else if (ex is IGraphicElement)
- {
- /* if we're lucky, the IGE has its own DisplayObject, and we can just trip its alpha.
- If not, we're going to have to set it to 0, and force a redraw of the whole component */
- var ge:IGraphicElement = ex as IGraphicElement;
- if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
- {
- exclusionAlphaValues[i] = ge.displayObject.alpha;
- ge.displayObject.alpha = 0;
- }
- else
- {
- exclusionAlphaValues[i] = ge.alpha;
- ge.alpha = 0;
- needRedraw = true;
- }
- }
- }
-
- // If we have a mostly-transparent content background, temporarily bump
- // up the contentBackgroundAlpha so the captured bitmap includes an opaque
- // snapshot of the background.
- if (getStyle("contentBackgroundAlpha") < 0.5)
- {
- if (styleDeclaration && styleDeclaration.getStyle("contentBackgroundAlpha") !== null)
- contentBackgroundAlphaSetLocally = true;
- else
- contentBackgroundAlphaSetLocally = false;
- oldContentBackgroundAlpha = getStyle("contentBackgroundAlpha");
- setStyle("contentBackgroundAlpha", 0.5);
- needRedraw = true;
- }
-
- /* if we excluded an IGE without its own DO, we need to update the component before grabbing the bitmap */
- return needRedraw;
- }
-
- /**
- * Called after a bitmap capture is made for this skin. The default implementation
- * restores the items in the focusSkinExclusions array.
- *
- * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
- *
- * @langversion 3.0
- * @playerversion Flash 10
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- public function endHighlightBitmapCapture():Boolean
- {
- var exclusions:Array = focusSkinExclusions;
- if (!exclusions)
- {
- if (this["hostComponent"] is SkinnableComponent)
- exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
- }
- var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
- var needRedraw:Boolean = false;
-
- for (var i:int=0; i < exclusionCount; i++)
- {
- // skip if the part isn't there
- if (!(exclusions[i] in this))
- continue;
-
- var ex:Object = this[exclusions[i]];
- if (ex is UIComponent)
- {
- (ex as UIComponent).$alpha = exclusionAlphaValues[i];
- }
- else if (ex is DisplayObject)
- {
- (ex as DisplayObject).alpha = exclusionAlphaValues[i];
- }
- else if (ex is IGraphicElement)
- {
- var ge:IGraphicElement = ex as IGraphicElement;
- if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
- {
- ge.displayObject.alpha = exclusionAlphaValues[i];
- }
- else
- {
- ge.alpha = exclusionAlphaValues[i];
- needRedraw = true;
- }
- }
- }
-
- exclusionAlphaValues = null;
-
- if (!isNaN(oldContentBackgroundAlpha))
- {
- if (contentBackgroundAlphaSetLocally)
- setStyle("contentBackgroundAlpha", oldContentBackgroundAlpha);
- else
- clearStyle("contentBackgroundAlpha");
- needRedraw = true;
- oldContentBackgroundAlpha = NaN;
- }
-
- return needRedraw;
- }
+
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/defaults.css
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/defaults.css b/frameworks/projects/spark/defaults.css
index 754c860..0b6ba5c 100644
--- a/frameworks/projects/spark/defaults.css
+++ b/frameworks/projects/spark/defaults.css
@@ -50,6 +50,16 @@ ButtonBar
skinClass: ClassReference("spark.skins.spark.ButtonBarSkin");
}
+Callout
+{
+ backgroundColor: #ffffff;
+ contentBackgroundAppearance: flat;
+ contentBackgroundColor: #FFFFFF;
+ skinClass: ClassReference("spark.skins.spark.CalloutSkin");
+ borderColor: #3d3d3d;
+ borderThickness: 1;
+}
+
CheckBox
{
skinClass: ClassReference("spark.skins.spark.CheckBoxSkin");
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/SparkClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/SparkClasses.as b/frameworks/projects/spark/src/SparkClasses.as
index 0800608..0aa207f 100644
--- a/frameworks/projects/spark/src/SparkClasses.as
+++ b/frameworks/projects/spark/src/SparkClasses.as
@@ -121,6 +121,8 @@ import spark.skins.spark.VSliderTrackSkin; VSliderTrackSkin;
import spark.utils.TextFlowUtil; TextFlowUtil;
import spark.components.ContentBackgroundAppearance;ContentBackgroundAppearance;
+import spark.skins.ActionScriptSkinBase; ActionScriptSkinBase ;
+import spark.skins.spark.CalloutSkin; CalloutSkin;
}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/components/Callout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/Callout.as b/frameworks/projects/spark/src/spark/components/Callout.as
index 8d81b4a..85593dd 100644
--- a/frameworks/projects/spark/src/spark/components/Callout.as
+++ b/frameworks/projects/spark/src/spark/components/Callout.as
@@ -64,6 +64,31 @@ use namespace mx_internal;
*/
[Style(name="contentBackgroundAppearance", type="String", enumeration="inset,flat,none", inherit="no")]
+/**
+ * Color of the frame border and arrow outline of the Callout control.
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+
+[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="spark, mobile")]
+
+/**
+ * Thickness of the border stroke around the <code>backgroundColor</code> Callout "frame" and arrow.
+ * Set to NaN or 0 to hide the border ;
+ *
+ * @default NaN
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 3.8
+ * @productversion Flex 4.11
+ */
+[Style(name="borderThickness", type="Number", format="Length", inherit="no", theme="spark,mobile")]
+
//--------------------------------------
// Other metadata
//--------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/074354ca/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as b/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as
new file mode 100644
index 0000000..93a49ba
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/skins/ActionScriptSkinBase.as
@@ -0,0 +1,853 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.skins
+{
+import flash.display.DisplayObject;
+import flash.geom.ColorTransform;
+import flash.geom.Matrix;
+
+import mx.core.FlexGlobals;
+import mx.core.IFlexDisplayObject;
+import mx.core.ILayoutElement;
+import mx.core.UIComponent;
+import mx.core.mx_internal;
+
+import spark.components.supportClasses.SkinnableComponent;
+import spark.core.DisplayObjectSharingMode;
+import spark.core.IGraphicElement;
+
+use namespace mx_internal;
+
+/**
+ * ActionScript-based skin for both mobile and desktop applications.
+ * This skin is the base class for MobileSkin.
+ * As an optimization, it removes state transition support.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+public class ActionScriptSkinBase extends UIComponent implements IHighlightBitmapCaptureClient
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Default symbol color for <code>symbolColor</code> style.
+ */
+ mx_internal static const DEFAULT_SYMBOL_COLOR_VALUE:uint = 0x00;
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ *
+ */
+ public function ActionScriptSkinBase()
+ {
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Specifies whether or not this skin should be affected by the <code>symbolColor</code> style.
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected var useSymbolColor:Boolean = false;
+
+ /**
+ * @private
+ * Toggles transparent, centered hit-area if the unscaled size is less
+ * than one-quarter inch square. Physical size is based on applicationDPI.
+ */
+ mx_internal var useMinimumHitArea:Boolean = false;
+
+ /**
+ * Specifies a default width. <code>measuredWidth</code> returns this value
+ * when the computed <code>measuredWidth</code> is less than
+ * <code>measuredDefaultWidth</code>.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected var measuredDefaultWidth:Number = 0;
+
+ /**
+ * Specifies a default height. <code>measuredHeight</code> returns this value
+ * when the computed <code>measuredHeight</code> is less than
+ * <code>measuredDefaultHeight</code>.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected var measuredDefaultHeight:Number = 0;
+
+ //----------------------------------
+ // colorMatrix
+ //----------------------------------
+
+ private static var _colorMatrix:Matrix = new Matrix();
+
+ /**
+ * @private
+ */
+ mx_internal static function get colorMatrix():Matrix
+ {
+ if (!_colorMatrix)
+ _colorMatrix = new Matrix();
+
+ return _colorMatrix;
+ }
+
+ //----------------------------------
+ // colorTransform
+ //----------------------------------
+
+ private static var _colorTransform:ColorTransform;
+
+ /**
+ * @private
+ */
+ mx_internal static function get colorTransform():ColorTransform
+ {
+ if (!_colorTransform)
+ _colorTransform = new ColorTransform();
+
+ return _colorTransform;
+ }
+
+ //----------------------------------
+ // applicationDPI
+ //----------------------------------
+
+ /**
+ * Returns the DPI of the application. This property can only be set in MXML on the root application.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function get applicationDPI():Number
+ {
+ return FlexGlobals.topLevelApplication.applicationDPI;
+ }
+
+ //----------------------------------
+ // symbolItems
+ //----------------------------------
+
+ /**
+ * Names of items that should have their <code>color</code> property defined by
+ * the <code>symbolColor</code> style.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Flex 4
+ */
+ protected function get symbolItems():Array
+ {
+ return null;
+ }
+
+ //----------------------------------
+ // currentState
+ //----------------------------------
+
+ private var _currentState:String;
+
+ /**
+ * @private
+ */
+ override public function get currentState():String
+ {
+ return _currentState;
+ }
+
+ /**
+ * @private
+ */
+ override public function set currentState(value:String):void
+ {
+ if (value != _currentState)
+ {
+ _currentState = value;
+ commitCurrentState();
+ }
+ }
+
+ /**
+ * Called whenever the currentState changes. Skins should override
+ * this function if they make any appearance changes during
+ * a state change.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function commitCurrentState():void
+ {
+ }
+
+ /**
+ * MobileSkin does not use states. Skins should override this function
+ * to return false for states that are not implemented.
+ *
+ * @param stateName The state name.
+ *
+ * @return false for states that are not implemented.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ override public function hasState(stateName:String):Boolean
+ {
+ return true;
+ }
+
+ /**
+ * @private
+ */
+ override public function setCurrentState(stateName:String,
+ playTransition:Boolean = true):void
+ {
+ currentState = stateName;
+ }
+
+ /**
+ * @private
+ */
+ override public function get measuredWidth():Number
+ {
+ return Math.max(super.measuredWidth, measuredDefaultWidth);
+ }
+
+ /**
+ * @private
+ */
+ override public function get measuredHeight():Number
+ {
+ return Math.max(super.measuredHeight, measuredDefaultHeight);
+ }
+
+ /**
+ * @private
+ */
+ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ graphics.clear();
+
+ super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+ layoutContents(unscaledWidth, unscaledHeight);
+
+ if (useSymbolColor)
+ applySymbolColor();
+
+ if (useMinimumHitArea)
+ drawMinimumHitArea(unscaledWidth, unscaledHeight);
+
+ drawBackground(unscaledWidth, unscaledHeight);
+ }
+
+ /**
+ * @private
+ * Make the component's explicitMinWidth property override its skin's.
+ * This is useful for cases where the skin's minWidth constrains
+ * the skin's measured size. In those cases the user could set
+ * explicit limits on the component itself thus relaxing the
+ * hard-coded limits in the skin. See SDK-24741.
+ */
+ override public function get explicitMinWidth():Number
+ {
+ if (parent is SkinnableComponent)
+ {
+ var parentExplicitMinWidth:Number = SkinnableComponent(parent).explicitMinWidth;
+ if (!isNaN(parentExplicitMinWidth))
+ return parentExplicitMinWidth;
+ }
+ return super.explicitMinWidth;
+ }
+
+ /**
+ * @private
+ * Make the component's explicitMinWidth property override its skin's.
+ * This is useful for cases where the skin's minWidth constrains
+ * the skin's measured size. In those cases the user could set
+ * explicit limits on the component itself thus relaxing the
+ * hard-coded limits in the skin. See SDK-24741.
+ */
+ override public function get explicitMinHeight():Number
+ {
+ if (parent is SkinnableComponent)
+ {
+ var parentExplicitMinHeight:Number = SkinnableComponent(parent).explicitMinHeight;
+ if (!isNaN(parentExplicitMinHeight))
+ return parentExplicitMinHeight;
+ }
+ return super.explicitMinHeight;
+ }
+
+ /**
+ * @private
+ * Make the component's explicitMinWidth property override its skin's.
+ * This is useful for cases where the skin's minWidth constrains
+ * the skin's measured size. In those cases the user could set
+ * explicit limits on the component itself thus relaxing the
+ * hard-coded limits in the skin. See SDK-24741.
+ */
+ override public function get explicitMaxWidth():Number
+ {
+ if (parent is SkinnableComponent)
+ {
+ var parentExplicitMaxWidth:Number = SkinnableComponent(parent).explicitMaxWidth;
+ if (!isNaN(parentExplicitMaxWidth))
+ return parentExplicitMaxWidth;
+ }
+ return super.explicitMaxWidth;
+ }
+
+ /**
+ * @private
+ * Make the component's explicitMinWidth property override its skin's.
+ * This is useful for cases where the skin's minWidth constrains
+ * the skin's measured size. In those cases the user could set
+ * explicit limits on the component itself thus relaxing the
+ * hard-coded limits in the skin. See SDK-24741.
+ */
+ override public function get explicitMaxHeight():Number
+ {
+ if (parent is SkinnableComponent)
+ {
+ var parentExplicitMaxHeight:Number = SkinnableComponent(parent).explicitMaxHeight;
+ if (!isNaN(parentExplicitMaxHeight))
+ return parentExplicitMaxHeight;
+ }
+ return super.explicitMaxHeight;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ mx_internal function drawMinimumHitArea(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ // minimum hit area is 0.25 inches square
+ var minSize:Number = applicationDPI / 4;
+
+ // skip if skin size is larger than minimum
+ if ((unscaledWidth > minSize) && (unscaledHeight > minSize))
+ return;
+
+ // center a transparent hit area larger than the skin
+ var hitAreaWidth:Number = Math.max(minSize, unscaledWidth);
+ var hitAreaHeight:Number = Math.max(minSize, unscaledHeight);
+ var hitAreaX:Number = (unscaledWidth - hitAreaWidth) / 2;
+ var hitAreaY:Number = (unscaledHeight - hitAreaHeight) / 2;
+
+ graphics.beginFill(0, 0);
+ graphics.drawRect(hitAreaX, hitAreaY, hitAreaWidth, hitAreaHeight);
+ graphics.endFill();
+ }
+
+ /**
+ * Positions the children for this skin.
+ *
+ * <p>This method, along with <code>colorizeContents()</code>, is called
+ * by the <code>updateDisplayList()</code> method.</p>
+ *
+ * <p>This method positions skin parts and graphic children of the skin.
+ * Subclasses should override this to position their children.</p>
+ *
+ * @param unscaledWidth Specifies the width of the component, in pixels,
+ * in the component's coordinates, regardless of the value of the
+ * <code>scaleX</code> property of the component.
+ *
+ * @param unscaledHeight Specifies the height of the component, in pixels,
+ * in the component's coordinates, regardless of the value of the
+ * <code>scaleY</code> property of the component.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.1
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+
+ }
+
+ /**
+ * A helper method to set a color transform on a DisplayObject.
+ *
+ * @param displayObject The display object to transform
+ * @param originalColor The original color
+ * @param tintColor The desired color
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function applyColorTransform(displayObject:DisplayObject, originalColor:uint, tintColor:uint):void
+ {
+ colorTransform.redOffset = ((tintColor & (0xFF << 16)) >> 16) - ((originalColor & (0xFF << 16)) >> 16);
+ colorTransform.greenOffset = ((tintColor & (0xFF << 8)) >> 8) - ((originalColor & (0xFF << 8)) >> 8);
+ colorTransform.blueOffset = (tintColor & 0xFF) - (originalColor & 0xFF);
+ colorTransform.alphaMultiplier = alpha;
+
+ displayObject.transform.colorTransform = colorTransform;
+ }
+
+ /**
+ * Renders a background for the skin.
+ *
+ * <p>This method, along with <code>layoutContents()</code>, is called
+ * by the <code>updateDisplayList()</code>.</p>
+ *
+ * <p>This method draws the background chromeColor.
+ * Override this method to change the appearance of the chromeColor.</p>
+ *
+ * @param unscaledWidth Specifies the width of the component, in pixels,
+ * in the component's coordinates, regardless of the value of the
+ * <code>scaleX</code> property of the component.
+ *
+ * @param unscaledHeight Specifies the height of the component, in pixels,
+ * in the component's coordinates, regardless of the value of the
+ * <code>scaleY</code> property of the component.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+
+ }
+
+ /**
+ * @private
+ */
+ mx_internal function applySymbolColor():void
+ {
+ var symbols:Array = symbolItems;
+ var len:uint = (symbols) ? symbols.length : 0;
+
+ if (len > 0)
+ {
+ var symbolColor:uint = getStyle("symbolColor");
+ var symbolObj:Object;
+ var transformInitialized:Boolean = false;
+
+ for (var i:uint = 0; i < len; i++)
+ {
+ symbolObj = this[symbols[i]];
+
+ // SparkSkin assumed symbols were IFill objects
+ // with a color property. MobileSkin instead assumes symbols
+ // are DisplayObjects.
+ if (symbolObj is DisplayObject)
+ {
+ if (!transformInitialized)
+ {
+ colorTransform.redOffset = ((symbolColor & (0xFF << 16)) >> 16) - DEFAULT_SYMBOL_COLOR_VALUE;
+ colorTransform.greenOffset = ((symbolColor & (0xFF << 8)) >> 8) - DEFAULT_SYMBOL_COLOR_VALUE;
+ colorTransform.blueOffset = (symbolColor & 0xFF) - DEFAULT_SYMBOL_COLOR_VALUE;
+ colorTransform.alphaMultiplier = alpha;
+
+ transformInitialized = true;
+ }
+
+ DisplayObject(symbolObj).transform.colorTransform = colorTransform;
+ }
+ }
+ }
+ }
+
+ /**
+ * A helper method to position children elements of this component.
+ *
+ * <p>This method is the recommended way to position children elements. You can
+ * use this method instead of checking for and using
+ * various interfaces/classes such as ILayoutElement, IFlexDisplayObject,
+ * or StyleableTextField.</p>
+ *
+ * <p>Call this method after calling <code>setElementSize()</code></p>
+ *
+ * @param element The child element to position. The element could be an
+ * ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
+ * DisplayObject.
+ *
+ * @param x The x-coordinate of the child.
+ *
+ * @param y The y-coordinate of the child.
+ *
+ * @see #setElementSize
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.1
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function setElementPosition(element:Object, x:Number, y:Number):void
+ {
+ if (element is ILayoutElement)
+ {
+ ILayoutElement(element).setLayoutBoundsPosition(x, y, false);
+ }
+ else if (element is IFlexDisplayObject)
+ {
+ IFlexDisplayObject(element).move(x, y);
+ }
+ else
+ {
+ element.x = x;
+ element.y = y;
+ }
+ }
+
+ /**
+ * A helper method to size children elements of this component.
+ *
+ * <p>This method is the recommended way to size children elements. You can
+ * use this method instead of checking for and using
+ * interfaces/classes such as ILayoutElement, IFlexDisplayObject,
+ * or StyleableTextField.</p>
+ *
+ * <p>Call this method before calling the <code>setElementPosition()</code> method.</p>
+ *
+ * @param element The child element to size. The element could be an
+ * ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
+ * DisplayObject.
+ *
+ * @param width The width of the child.
+ *
+ * @param height The height of the child.
+ *
+ * @see #setElementPosition
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.1
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function setElementSize(element:Object, width:Number, height:Number):void
+ {
+ if (element is ILayoutElement)
+ {
+ ILayoutElement(element).setLayoutBoundsSize(width, height, false);
+ }
+ else if (element is IFlexDisplayObject)
+ {
+ IFlexDisplayObject(element).setActualSize(width, height);
+ }
+ else
+ {
+ element.width = width;
+ element.height = height;
+ }
+ }
+
+ /**
+ * A helper method to retrieve the preferred width of a child element.
+ *
+ * <p>This method is the recommended way to get a child element's preferred
+ * width. You can use this method instead of checking for and using
+ * various interfaces/classes such as ILayoutElement, IFlexDisplayObject,
+ * or StyleableTextField.</p>
+ *
+ * @param element The child element to retrieve the width for. The element could
+ * be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
+ * DisplayObject.
+ *
+ * @return The child element's preferred width.
+ *
+ * @see #sizeElement
+ * @see #getElementPreferredHeight
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.1
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function getElementPreferredWidth(element:Object):Number
+ {
+ if (element is ILayoutElement)
+ {
+ return ILayoutElement(element).getPreferredBoundsWidth();
+ }
+ else if (element is IFlexDisplayObject)
+ {
+ return IFlexDisplayObject(element).measuredWidth;
+ }
+ else
+ {
+ return element.width;
+ }
+ }
+
+ /**
+ * A helper method to retrieve the preferred height of a child element.
+ *
+ * <p>This method is the recommended way to get a child element's preferred
+ * height. You can use this method instead of checking for and using
+ * various interfaces/classes such as ILayoutElement, IFlexDisplayObject,
+ * or StyleableTextField.</p>
+ *
+ * @param element The child element to retrieve the height for. The element could
+ * be an ILayoutElement, IFlexDisplayObject, StyleableTextField, or a generic
+ * DisplayObject.
+ *
+ * @return The child element's preferred height.
+ *
+ * @see #sizeElement
+ * @see #getElementPreferredWidth
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.1
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function getElementPreferredHeight(element:Object):Number
+ {
+ if (element is ILayoutElement)
+ {
+ return ILayoutElement(element).getPreferredBoundsHeight();
+ }
+ else if (element is IFlexDisplayObject)
+ {
+ return IFlexDisplayObject(element).measuredHeight;
+ }
+ else
+ {
+ return element.height;
+ }
+ }
+
+ /**
+ * List of IDs of items that should be excluded when rendering the focus ring.
+ * Only items of type DisplayObject or GraphicElement should be excluded. Items
+ * of other types are ignored.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ protected function get focusSkinExclusions():Array
+ {
+ return null;
+ }
+
+ private static var exclusionAlphaValues:Array;
+
+ private static var oldContentBackgroundAlpha:Number;
+
+ private static var contentBackgroundAlphaSetLocally:Boolean;
+
+ /**
+ * Called before a bitmap capture is made for this skin. The default implementation
+ * excludes items in the focusSkinExclusions array.
+ *
+ * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function beginHighlightBitmapCapture():Boolean
+ {
+ var exclusions:Array = focusSkinExclusions;
+ if (!exclusions)
+ {
+ if (("hostComponent" in this) && this["hostComponent"] is SkinnableComponent)
+ exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
+ }
+ var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
+
+ /* we'll store off the previous alpha of the exclusions so we
+ can restore them when we're done
+ */
+ exclusionAlphaValues = [];
+ var needRedraw:Boolean = false;
+
+ for (var i:int = 0; i < exclusionCount; i++)
+ {
+ // skip if the part isn't there
+ if (!(exclusions[i] in this))
+ continue;
+
+ var ex:Object = this[exclusions[i]];
+ /* we're going to go under the covers here to try and modify alpha with the least
+ amount of disruption to the component. For UIComponents, we go to Sprite's alpha property;
+ */
+ if (ex is UIComponent)
+ {
+ exclusionAlphaValues[i] = (ex as UIComponent).$alpha;
+ (ex as UIComponent).$alpha = 0;
+ }
+ else if (ex is DisplayObject)
+ {
+ exclusionAlphaValues[i] = (ex as DisplayObject).alpha;
+ (ex as DisplayObject).alpha = 0;
+ }
+ else if (ex is IGraphicElement)
+ {
+ /* if we're lucky, the IGE has its own DisplayObject, and we can just trip its alpha.
+ If not, we're going to have to set it to 0, and force a redraw of the whole component */
+ var ge:IGraphicElement = ex as IGraphicElement;
+ if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
+ {
+ exclusionAlphaValues[i] = ge.displayObject.alpha;
+ ge.displayObject.alpha = 0;
+ }
+ else
+ {
+ exclusionAlphaValues[i] = ge.alpha;
+ ge.alpha = 0;
+ needRedraw = true;
+ }
+ }
+ }
+
+ // If we have a mostly-transparent content background, temporarily bump
+ // up the contentBackgroundAlpha so the captured bitmap includes an opaque
+ // snapshot of the background.
+ if (getStyle("contentBackgroundAlpha") < 0.5)
+ {
+ if (styleDeclaration && styleDeclaration.getStyle("contentBackgroundAlpha") !== null)
+ contentBackgroundAlphaSetLocally = true;
+ else
+ contentBackgroundAlphaSetLocally = false;
+ oldContentBackgroundAlpha = getStyle("contentBackgroundAlpha");
+ setStyle("contentBackgroundAlpha", 0.5);
+ needRedraw = true;
+ }
+
+ /* if we excluded an IGE without its own DO, we need to update the component before grabbing the bitmap */
+ return needRedraw;
+ }
+
+ /**
+ * Called after a bitmap capture is made for this skin. The default implementation
+ * restores the items in the focusSkinExclusions array.
+ *
+ * @return <code>true</code> if the component needs to be redrawn; otherwise <code>false</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function endHighlightBitmapCapture():Boolean
+ {
+ var exclusions:Array = focusSkinExclusions;
+ if (!exclusions)
+ {
+ if (this["hostComponent"] is SkinnableComponent)
+ exclusions = SkinnableComponent(this["hostComponent"]).suggestedFocusSkinExclusions;
+ }
+ var exclusionCount:Number = (exclusions == null) ? 0 : exclusions.length;
+ var needRedraw:Boolean = false;
+
+ for (var i:int=0; i < exclusionCount; i++)
+ {
+ // skip if the part isn't there
+ if (!(exclusions[i] in this))
+ continue;
+
+ var ex:Object = this[exclusions[i]];
+ if (ex is UIComponent)
+ {
+ (ex as UIComponent).$alpha = exclusionAlphaValues[i];
+ }
+ else if (ex is DisplayObject)
+ {
+ (ex as DisplayObject).alpha = exclusionAlphaValues[i];
+ }
+ else if (ex is IGraphicElement)
+ {
+ var ge:IGraphicElement = ex as IGraphicElement;
+ if (ge.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT)
+ {
+ ge.displayObject.alpha = exclusionAlphaValues[i];
+ }
+ else
+ {
+ ge.alpha = exclusionAlphaValues[i];
+ needRedraw = true;
+ }
+ }
+ }
+
+ exclusionAlphaValues = null;
+
+ if (!isNaN(oldContentBackgroundAlpha))
+ {
+ if (contentBackgroundAlphaSetLocally)
+ setStyle("contentBackgroundAlpha", oldContentBackgroundAlpha);
+ else
+ clearStyle("contentBackgroundAlpha");
+ needRedraw = true;
+ oldContentBackgroundAlpha = NaN;
+ }
+
+ return needRedraw;
+ }
+}
+}
\ No newline at end of file
[3/8] temp commit move experimental callout to spark
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/components/CalloutButton.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/CalloutButton.as b/frameworks/projects/mobilecomponents/src/spark/components/CalloutButton.as
deleted file mode 100644
index 7eec462..0000000
--- a/frameworks/projects/mobilecomponents/src/spark/components/CalloutButton.as
+++ /dev/null
@@ -1,807 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 spark.components
-{
-import flash.events.Event;
-
-import mx.core.ClassFactory;
-import mx.core.IFactory;
-import mx.core.mx_internal;
-import mx.utils.BitFlagUtil;
-
-import spark.components.supportClasses.DropDownController;
-import spark.core.ContainerDestructionPolicy;
-import spark.events.DropDownEvent;
-import spark.events.PopUpEvent;
-import spark.layouts.supportClasses.LayoutBase;
-
-use namespace mx_internal;
-
-//--------------------------------------
-// Styles
-//--------------------------------------
-
-[Exclude(name="repeatDelay", kind="style")]
-[Exclude(name="repeatInterval", kind="style")]
-
-//--------------------------------------
-// Events
-//--------------------------------------
-
-/**
- * Dispatched when the callout closes for any reason, such when:
- * <ul>
- * <li>The callout is programmatically closed.</li>
- * <li>The user clicks outside of the callout.</li>
- * <li>The user clicks the open button while the callout is
- * displayed.</li>
- * </ul>
- *
- * @eventType spark.events.DropDownEvent.CLOSE
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-[Event(name="close", type="spark.events.DropDownEvent")]
-
-/**
- * Dispatched when the user clicks the open button
- * to display the callout.
- *
- * @eventType spark.events.DropDownEvent.OPEN
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-[Event(name="open", type="spark.events.DropDownEvent")]
-
-//--------------------------------------
-// Other metadata
-//--------------------------------------
-
-[IconFile("Callout.png")]
-
-[DefaultProperty("calloutContent")]
-
-/**
- * The CalloutButton control is a drop down component that defines a button to
- * open and close a Callout container.
- * The CalloutButton specifies the layout and child components
- * of the Callout container.
- *
- * <p>The following image shows a Callout container under the CalloutButton
- * labeled 'Open callout':</p>
- *
- * <p>
- * <img src="../../images/ca_calloutButton_ca.png" alt="Callout button" />
- * </p>
- *
- * <p>The CalloutButton control uses the spark.components.supportClasses.DropDownController
- * class to manage the Callout container.
- * You can access the DropDownController by using the protected
- * <code>CalloutButton.dropDownController</code> property.</p>
- *
- * <p>When the callout is open:</p>
- * <ul>
- * <li>Clicking the button closes the callout</li>
- * <li>Clicking outside of the callout closes the callout.</li>
- * </ul>
- *
- * <p>The CalloutButton component has the following default characteristics:</p>
- * <table class="innertable">
- * <tr>
- * <th>Characteristic</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td>Default size</td>
- * <td>Wide enough to display the text label of the control</td>
- * </tr>
- * <tr>
- * <td>Minimum size</td>
- * <td>32 pixels wide and 43 pixels high</td>
- * </tr>
- * <tr>
- * <td>Maximum size</td>
- * <td>10000 pixels wide and 10000 pixels high</td>
- * </tr>
- * <tr>
- * <td>Default skin class</td>
- * <td>spark.skins.mobile.CalloutButtonSkin</td>
- * </tr>
- * </table>
- *
- * @mxml
- *
- * <p>The <code><s:CalloutButton></code> tag inherits all of the tag
- * attributes of its superclass and adds the following tag attributes:</p>
- *
- * <pre>
- * <s:CalloutButton
- * <strong>Properties</strong>
- * calloutDestructionPolicy="auto"
- * calloutLayout="BasicLayout"
- * horizontalPosition="auto"
- * verticalPosition="auto
- *
- * <strong>Events</strong>
- * open="<i>No default</i>"
- * close="<i>No default</i>"
- * ...
- * <i>child tags</i>
- * ...
- * </s:CalloutButton>
- * </pre>
- *
- * @see spark.components.Callout
- * @see spark.components.Button
- * @see spark.components.supportClasses.DropDownController
- *
- * @includeExample examples/CalloutButtonExample.mxml -noswf
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-public class CalloutButton extends Button
-{
- //--------------------------------------------------------------------------
- //
- // Class constants
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- */
- mx_internal static const CALLOUT_CONTENT_PROPERTY_FLAG:uint = 1 << 0;
-
- /**
- * @private
- */
- mx_internal static const CALLOUT_LAYOUT_PROPERTY_FLAG:uint = 1 << 1;
-
- /**
- * @private
- */
- mx_internal static const HORIZONTAL_POSITION_PROPERTY_FLAG:uint = 1 << 2;
-
- /**
- * @private
- */
- mx_internal static const VERTICAL_POSITION_PROPERTY_FLAG:uint = 1 << 3;
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructor.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function CalloutButton()
- {
- super();
-
- dropDownController = new DropDownController();
- }
-
- //--------------------------------------------------------------------------
- //
- // Skin parts
- //
- //--------------------------------------------------------------------------
-
- [SkinPart(required="false")]
-
- /**
- * A skin part that defines the drop-down factory which creates the Callout
- * instance.
- *
- * If <code>dropDown</code> is not defined on the skin, a
- * <code>ClassFactory</code> is created to generate a default Callout
- * instance.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public var dropDown:IFactory;
-
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- * Several properties are proxied to callout. However, when callout
- * is not around, we need to store values set on CalloutButton. This object
- * stores those values. If callout is around, the values are stored
- * on the callout directly. However, we need to know what values
- * have been set by the developer on the CalloutButton (versus set on
- * the callout or defaults of the callout) as those are values
- * we want to carry around if the callout changes (via a new skin).
- * In order to store this info effeciently, calloutProperties becomes
- * a uint to store a series of BitFlags. These bits represent whether a
- * property has been explicitely set on this CalloutButton. When the
- * callout is not around, calloutProperties is a typeless
- * object to store these proxied properties. When callout is around,
- * calloutProperties stores booleans as to whether these properties
- * have been explicitely set or not.
- */
- mx_internal var calloutProperties:Object = {};
-
- //--------------------------------------------------------------------------
- //
- // Properties proxied to callout
- //
- //--------------------------------------------------------------------------
-
- //----------------------------------
- // calloutContent
- //----------------------------------
-
- [ArrayElementType("mx.core.IVisualElement")]
-
- /**
- * The set of components to include in the Callout's content.
- *
- * @default null
- *
- * @see spark.components.Callout
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get calloutContent():Array
- {
- if (callout && callout.contentGroup)
- return callout.contentGroup.getMXMLContent();
- else
- return calloutProperties.calloutContent;
- }
-
- /**
- * @private
- */
- public function set calloutContent(value:Array):void
- {
- if (callout)
- {
- callout.mxmlContent = value;
- calloutProperties = BitFlagUtil.update(calloutProperties as uint,
- CALLOUT_CONTENT_PROPERTY_FLAG, value != null);
- }
- else
- calloutProperties.calloutContent = value;
- }
-
- //----------------------------------
- // calloutLayout
- //----------------------------------
-
- /**
- * Defines the layout of the Callout container.
- *
- * @default BasicLayout
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get calloutLayout():LayoutBase
- {
- return (callout) ? callout.layout : calloutProperties.calloutLayout;
- }
-
- /**
- * @private
- */
- public function set calloutLayout(value:LayoutBase):void
- {
- if (callout)
- {
- callout.layout = value;
- calloutProperties = BitFlagUtil.update(calloutProperties as uint,
- CALLOUT_LAYOUT_PROPERTY_FLAG, true);
- }
- else
- calloutProperties.calloutLayout = value;
- }
-
- //----------------------------------
- // horizontalPosition
- //----------------------------------
-
- [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
-
- /**
- * @copy spark.components.Callout#horizontalPosition
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get horizontalPosition():String
- {
- if (callout)
- return callout.horizontalPosition;
-
- return calloutProperties.horizontalPosition;
- }
-
- /**
- * @private
- */
- public function set horizontalPosition(value:String):void
- {
- if (callout)
- {
- callout.horizontalPosition = value;
- calloutProperties = BitFlagUtil.update(calloutProperties as uint,
- HORIZONTAL_POSITION_PROPERTY_FLAG, value != null);
- }
- else
- calloutProperties.horizontalPosition = value;
- }
-
- //----------------------------------
- // verticalPosition
- //----------------------------------
-
- [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
-
- /**
- * @copy spark.components.Callout#verticalPosition
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get verticalPosition():String
- {
- if (callout)
- return callout.verticalPosition;
-
- return calloutProperties.verticalPosition;
- }
-
- /**
- * @private
- */
- public function set verticalPosition(value:String):void
- {
- if (callout)
- {
- callout.verticalPosition = value;
- calloutProperties = BitFlagUtil.update(calloutProperties as uint,
- VERTICAL_POSITION_PROPERTY_FLAG, value != null);
- }
- else
- calloutProperties.verticalPosition = value;
- }
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- //----------------------------------
- // callout
- //----------------------------------
-
- /**
- * @private
- */
- private var _callout:Callout;
-
- [Bindable("calloutChanged")]
-
- /**
- * The Callout instance created after the <code>DropDownEvent.OPEN</code>
- * is fired. The instance is created using the <code>dropDown</code>
- * <code>IFactory</code> skin part.
- *
- * @see #calloutDestructionPolicy
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get callout():Callout
- {
- return _callout;
- }
-
- /**
- * @private
- */
- mx_internal function setCallout(value:Callout):void
- {
- if (_callout == value)
- return;
-
- _callout = value;
-
- if (hasEventListener("calloutChanged"))
- dispatchEvent(new Event("calloutChanged"));
- }
-
- //----------------------------------
- // dropDownController
- //----------------------------------
-
- /**
- * @private
- */
- private var _dropDownController:DropDownController;
-
- /**
- * Instance of the DropDownController class that handles all of the mouse, keyboard
- * and focus user interactions.
- *
- * Flex calls the <code>initializeDropDownController()</code> method after
- * the DropDownController instance is created in the constructor.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- protected function get dropDownController():DropDownController
- {
- return _dropDownController;
- }
-
- /**
- * @private
- */
- protected function set dropDownController(value:DropDownController):void
- {
- if (_dropDownController == value)
- return;
-
- _dropDownController = value;
-
- _dropDownController.closeOnResize = false;
- _dropDownController.addEventListener(DropDownEvent.OPEN, dropDownController_openHandler);
- _dropDownController.addEventListener(DropDownEvent.CLOSE, dropDownController_closeHandler);
-
- _dropDownController.openButton = this;
-
- if (callout)
- _dropDownController.dropDown = callout;
- }
-
- //----------------------------------
- // isDropDownOpen
- //----------------------------------
-
- /**
- * @copy spark.components.supportClasses.DropDownController#isOpen
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get isDropDownOpen():Boolean
- {
- if (dropDownController)
- return dropDownController.isOpen;
- else
- return false;
- }
-
- //----------------------------------
- // calloutDestructionPolicy
- //----------------------------------
-
- private var _calloutDestructionPolicy:String = ContainerDestructionPolicy.AUTO;
-
- [Inspectable(category="General", enumeration="auto,never", defaultValue="auto")]
-
- /**
- * Defines the destruction policy the callout button uses
- * when the callout is closed.
- * If set to <code>"auto"</code>, the button
- * destroys the Callout instance when it is closed.
- * If set to <code>"never"</code>, the Callout container
- * is cached in memory.
- *
- * @default auto
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get calloutDestructionPolicy():String
- {
- return _calloutDestructionPolicy;
- }
-
- /**
- * @private
- */
- public function set calloutDestructionPolicy(value:String):void
- {
- if (_calloutDestructionPolicy == value)
- return;
-
- _calloutDestructionPolicy = value;
-
- // destroy the callout immediately if currently closed
- if (!isDropDownOpen &&
- (calloutDestructionPolicy == ContainerDestructionPolicy.AUTO))
- {
- destroyCallout();
- }
- }
-
- //--------------------------------------------------------------------------
- //
- // Overridden methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- */
- override protected function attachSkin():void
- {
- super.attachSkin();
-
- // create dropDown if it was not found in the skin
- if (!dropDown && !("dropDown" in skin))
- dropDown = new ClassFactory(Callout);
- }
-
- /**
- * @private
- */
- override protected function partAdded(partName:String, instance:Object):void
- {
- super.partAdded(partName, instance);
-
- if (partName == "dropDown")
- {
- // copy proxied values from calloutProperties (if set) to callout
- var newCalloutProperties:uint = 0;
- var calloutInstance:Callout = instance as Callout;
-
- if (calloutInstance && dropDownController)
- {
- calloutInstance.id = "callout";
- dropDownController.dropDown = calloutInstance;
-
- calloutInstance.addEventListener(PopUpEvent.OPEN, callout_openHandler);
- calloutInstance.addEventListener(PopUpEvent.CLOSE, callout_closeHandler);
-
- if (calloutProperties.calloutContent !== undefined)
- {
- calloutInstance.mxmlContent = calloutProperties.calloutContent;
- newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
- CALLOUT_CONTENT_PROPERTY_FLAG, true);
- }
-
- if (calloutProperties.calloutLayout !== undefined)
- {
- calloutInstance.layout = calloutProperties.calloutLayout;
- newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
- CALLOUT_LAYOUT_PROPERTY_FLAG, true);
- }
-
- if (calloutProperties.horizontalPosition !== undefined)
- {
- calloutInstance.horizontalPosition = calloutProperties.horizontalPosition;
- newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
- HORIZONTAL_POSITION_PROPERTY_FLAG, true);
- }
-
- if (calloutProperties.verticalPosition !== undefined)
- {
- calloutInstance.verticalPosition = calloutProperties.verticalPosition;
- newCalloutProperties = BitFlagUtil.update(newCalloutProperties,
- VERTICAL_POSITION_PROPERTY_FLAG, true);
- }
-
- calloutProperties = newCalloutProperties;
- }
- }
- }
-
- /**
- * @private
- */
- override protected function partRemoved(partName:String, instance:Object):void
- {
- if (dropDownController && (instance == callout))
- {
- dropDownController.dropDown = null;
- }
-
- if (partName == "dropDown")
- {
- callout.removeEventListener(PopUpEvent.OPEN, callout_openHandler);
- callout.removeEventListener(PopUpEvent.CLOSE, callout_closeHandler);
-
- // copy proxied values from callout (if explicitely set) to calloutProperties
- var newCalloutProperties:Object = {};
-
- if (BitFlagUtil.isSet(calloutProperties as uint, CALLOUT_CONTENT_PROPERTY_FLAG) &&
- (callout.contentGroup))
- {
- newCalloutProperties.calloutContent = callout.contentGroup.getMXMLContent();
- callout.contentGroup.mxmlContent = null;
- }
-
- if (BitFlagUtil.isSet(calloutProperties as uint, CALLOUT_LAYOUT_PROPERTY_FLAG))
- {
- newCalloutProperties.calloutLayout = callout.layout;
- callout.layout = null;
- }
-
- if (BitFlagUtil.isSet(calloutProperties as uint, HORIZONTAL_POSITION_PROPERTY_FLAG))
- newCalloutProperties.horizontalPosition = callout.horizontalPosition;
-
- if (BitFlagUtil.isSet(calloutProperties as uint, VERTICAL_POSITION_PROPERTY_FLAG))
- newCalloutProperties.verticalPosition = callout.verticalPosition;
-
- calloutProperties = newCalloutProperties;
- }
-
- super.partRemoved(partName, instance);
- }
-
- //--------------------------------------------------------------------------
- //
- // Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * Initializes the dropDown and changes the skin state to open.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function openDropDown():void
- {
- dropDownController.openDropDown();
- }
-
- /**
- * Changes the skin state to normal.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function closeDropDown():void
- {
- dropDownController.closeDropDown(false);
- }
-
- /**
- * @private
- * Destroys the callout
- */
- private function destroyCallout():void
- {
- removeDynamicPartInstance("dropDown", callout);
- setCallout(null);
- }
-
- //--------------------------------------------------------------------------
- //
- // Event handlers
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- * Event handler for the <code>dropDownController</code>
- * <code>DropDownEvent.OPEN</code> event. Creates and opens the Callout.
- */
- mx_internal function dropDownController_openHandler(event:DropDownEvent):void
- {
- if (!callout)
- setCallout(createDynamicPartInstance("dropDown") as Callout);
-
- if (callout)
- {
- // close the callout if the CalloutButton is removed
- addEventListener(Event.REMOVED_FROM_STAGE, button_removedFromStage);
-
- callout.open(this, false);
- }
- }
-
- /**
- * @private
- * Event handler for the <code>dropDownController</code>
- * <code>DropDownEvent.CLOSE</code> event. Closes the Callout.
- */
- mx_internal function dropDownController_closeHandler(event:DropDownEvent):void
- {
- // If the callout was closed directly, then callout could already be
- // destroyed by calloutDestructionPolicy
- if (callout)
- {
- removeEventListener(Event.REMOVED_FROM_STAGE, button_removedFromStage);
-
- // Dispatch the close event after the callout's PopUpEvent.CLOSE fires
- callout.close();
- }
- }
-
- /**
- * @private
- */
- private function callout_openHandler(event:PopUpEvent):void
- {
- dispatchEvent(new DropDownEvent(DropDownEvent.OPEN));
- }
-
- /**
- * @private
- */
- private function callout_closeHandler(event:PopUpEvent):void
- {
- // Sanity check. Was callout closed without calling closeDropDown()?
- // If so, call closeDropDown directly to remove event listeners. This
- // callout_closeHandler will only be called once since the 2nd call
- // to close() in dropDownController_closeHandler() will not dispatch
- // another PopUpEvent.CLOSE.
- if (dropDownController.isOpen)
- closeDropDown();
-
- if (calloutDestructionPolicy == ContainerDestructionPolicy.AUTO)
- destroyCallout();
-
- dispatchEvent(new DropDownEvent(DropDownEvent.CLOSE));
- }
-
- /**
- * @private
- */
- private function button_removedFromStage(event:Event):void
- {
- if (!isDropDownOpen)
- return;
-
- // Hide the callout immediately instead of waiting for the skin
- // state to transition to "closed"
- callout.visible = false;
-
- closeDropDown();
- }
-}
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/components/CalloutPosition.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/CalloutPosition.as b/frameworks/projects/mobilecomponents/src/spark/components/CalloutPosition.as
deleted file mode 100644
index a0b6e7d..0000000
--- a/frameworks/projects/mobilecomponents/src/spark/components/CalloutPosition.as
+++ /dev/null
@@ -1,96 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 spark.components
-{
-
-/**
- * The CalloutPosition calss defines the enumeration of
- * horizontal and vertical positions of the Callout component
- * relative to the owner.
- *
- * @see spark.components.Callout
- * @see spark.components.Callout#horizontalPosition
- * @see spark.components.Callout#verticalPosition
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-public final class CalloutPosition
-{
-
- /**
- * Position the trailing edge of the callout before the leading edge of the owner.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const BEFORE:String = "before";
-
- /**
- * Position the leading edge of the callout at the leading edge of the owner.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const START:String = "start";
-
- /**
- * Position the horizontalCenter of the callout to the horizontalCenter of the owner.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const MIDDLE:String = "middle";
-
- /**
- * Position the trailing edge of the callout at the trailing edge of the owner.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const END:String = "end";
-
- /**
- * Position the leading edge of the callout after the trailing edge of the owner.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const AFTER:String = "after";
-
- /**
- * Position the callout on the exterior of the owner where the callout
- * requires the least amount of resizing to fit.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const AUTO:String = "auto";
-
-}
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/components/ContentBackgroundAppearance.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/ContentBackgroundAppearance.as b/frameworks/projects/mobilecomponents/src/spark/components/ContentBackgroundAppearance.as
deleted file mode 100644
index 13f0f0a..0000000
--- a/frameworks/projects/mobilecomponents/src/spark/components/ContentBackgroundAppearance.as
+++ /dev/null
@@ -1,72 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 spark.components
-{
-
-/**
- * The ContentBackgroundAppearance class defines the constants for the
- * allowed values of the <code>contentBackgroundAppearance</code> style of
- * Callout.
- *
- * @see spark.components.Callout#style:contentBackgroundAppearance
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-public final class ContentBackgroundAppearance
-{
- //--------------------------------------------------------------------------
- //
- // Class constants
- //
- //--------------------------------------------------------------------------
-
- /**
- * Applies a shadow and mask to the contentGroup.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const INSET:String = "inset";
-
- /**
- * Applies mask to the contentGroup.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const FLAT:String = "flat";
-
- /**
- * Disables both the <code>contentBackgroundColor</code> style and
- * contentGroup masking. Use this value when Callout's contents should
- * appear directly on top of the <code>backgroundColor</code> or when
- * contents provide their own masking.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const NONE:String = "none";
-}
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/core/ContainerDestructionPolicy.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/core/ContainerDestructionPolicy.as b/frameworks/projects/mobilecomponents/src/spark/core/ContainerDestructionPolicy.as
deleted file mode 100644
index 2ae91f1..0000000
--- a/frameworks/projects/mobilecomponents/src/spark/core/ContainerDestructionPolicy.as
+++ /dev/null
@@ -1,62 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 spark.core
-{
-/**
- * The ContainerCreationPolicy class defines the constant values
- * for the <code>destructionPolicy</code> property of spark view
- * classes.
- *
- * @see spark.components.supportClasses.ViewNavigatorBase#destructionPolicy
- * @see spark.components.View#destructionPolicy
- *
- * @langversion 3.0
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
-public final class ContainerDestructionPolicy
-{
- //--------------------------------------------------------------------------
- //
- // Class constants
- //
- //--------------------------------------------------------------------------
-
- /**
- * The lifespan of the container's children is automatically
- * managed by the container based on the container's own
- * heuristic.
- *
- * @langversion 3.0
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- public static const AUTO:String = "auto";
-
- /**
- * The container never destroys its children.
- *
- * @langversion 3.0
- * @playerversion AIR 2.5
- * @productversion Flex 4.5
- */
- public static const NEVER:String = "never";
-}
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/SparkClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/SparkClasses.as b/frameworks/projects/spark/src/SparkClasses.as
index cf36f06..0800608 100644
--- a/frameworks/projects/spark/src/SparkClasses.as
+++ b/frameworks/projects/spark/src/SparkClasses.as
@@ -119,6 +119,8 @@ import spark.skins.spark.VSliderSkin; VSliderSkin;
import spark.skins.spark.VSliderThumbSkin; VSliderThumbSkin;
import spark.skins.spark.VSliderTrackSkin; VSliderTrackSkin;
import spark.utils.TextFlowUtil; TextFlowUtil;
+
+import spark.components.ContentBackgroundAppearance;ContentBackgroundAppearance;
}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/spark/src/spark/components/ArrowDirection.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/ArrowDirection.as b/frameworks/projects/spark/src/spark/components/ArrowDirection.as
new file mode 100644
index 0000000..2ef7c4c
--- /dev/null
+++ b/frameworks/projects/spark/src/spark/components/ArrowDirection.as
@@ -0,0 +1,84 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 spark.components
+{
+/**
+ * Enumeration of arrow directions for use in visual components.
+ *
+ * @see spark.components.Callout#arrowDirection
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+public class ArrowDirection
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Arrow points right.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const RIGHT:String = "right";
+
+ /**
+ * Arrow points up.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const UP:String = "up";
+
+ /**
+ * Arrow points left.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const LEFT:String = "left";
+
+ /**
+ * Arrow points down.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const DOWN:String = "down";
+
+ /**
+ * No arrow direciton.
+ *
+ * @langversion 3.0
+ * @playerversion AIR 3
+ * @productversion Flex 4.6
+ */
+ public static const NONE:String = "none";
+}
+}
[5/8] git commit: [flex-sdk] [refs/heads/callout] - Merge branch
'develop' into callout
Posted by ma...@apache.org.
Merge branch 'develop' into callout
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/3e23c769
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/3e23c769
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/3e23c769
Branch: refs/heads/callout
Commit: 3e23c769a3a2bcead78fb6db82ca629b9331d95e
Parents: 0d6e7b3 6e0cb6c
Author: mamsellem <ma...@systar.com>
Authored: Mon Oct 7 21:41:26 2013 +0200
Committer: mamsellem <ma...@systar.com>
Committed: Mon Oct 7 21:41:26 2013 +0200
----------------------------------------------------------------------
RELEASE_NOTES | 12 ++-
build/check_sigs.sh | 77 ++++++++++++++++++
build/deploy_release_candidate.sh | 82 ++++++++++++++++++++
build/make_release_branch.sh | 49 ++++++++++++
build/tag_release_candidate.sh | 47 +++++++++++
frameworks/downloads.xml | 26 ++-----
.../itemRenderers/MenuBarItemRenderer.mxml | 41 +++++-----
.../itemRenderers/MenuCoreItemRenderer.as | 2 +
.../itemRenderers/MenuItemRenderer.mxml | 41 +++++-----
.../experimental/src/spark/skins/AlertSkin.mxml | 41 +++++-----
.../src/spark/skins/ColorPickerButtonSkin.mxml | 41 +++++-----
.../src/spark/skins/ColorPickerSkin.mxml | 42 +++++-----
.../src/spark/skins/MenuBarSkin.mxml | 41 +++++-----
.../experimental/src/spark/skins/MenuSkin.mxml | 41 +++++-----
.../src/spark/skins/ProgressBarSkin.mxml | 41 +++++-----
15 files changed, 434 insertions(+), 190 deletions(-)
----------------------------------------------------------------------
[4/8] git commit: [flex-sdk] [refs/heads/callout] - temp commit move
experimental callout to spark
Posted by ma...@apache.org.
temp commit move experimental callout to spark
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/0d6e7b32
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/0d6e7b32
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/0d6e7b32
Branch: refs/heads/callout
Commit: 0d6e7b32f9f708bc871160a60b9cdc2e9a7bb7a6
Parents: 05ae41d
Author: mamsellem <ma...@systar.com>
Authored: Mon Oct 7 21:36:00 2013 +0200
Committer: mamsellem <ma...@systar.com>
Committed: Mon Oct 7 21:36:00 2013 +0200
----------------------------------------------------------------------
.../projects/mobilecomponents/manifest.xml | 2 -
.../src/MobileComponentsClasses.as | 2 +-
.../src/MobileComponentsClassesAIR2.as | 1 -
.../src/spark/components/ArrowDirection.as | 84 -
.../src/spark/components/Callout.as | 1669 ------------------
.../src/spark/components/Callout.png | Bin 410 -> 0 bytes
.../src/spark/components/CalloutButton.as | 807 ---------
.../src/spark/components/CalloutPosition.as | 96 -
.../components/ContentBackgroundAppearance.as | 72 -
.../spark/core/ContainerDestructionPolicy.as | 62 -
frameworks/projects/spark/src/SparkClasses.as | 2 +
.../src/spark/components/ArrowDirection.as | 84 +
.../spark/src/spark/components/Callout.as | 1669 ++++++++++++++++++
.../spark/src/spark/components/Callout.png | Bin 0 -> 410 bytes
.../spark/src/spark/components/CalloutButton.as | 807 +++++++++
.../src/spark/components/CalloutPosition.as | 96 +
.../components/ContentBackgroundAppearance.as | 72 +
.../spark/core/ContainerDestructionPolicy.as | 62 +
frameworks/spark-manifest.xml | 2 +
19 files changed, 2795 insertions(+), 2794 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/manifest.xml
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/manifest.xml b/frameworks/projects/mobilecomponents/manifest.xml
index 06cc74b..810bfea 100644
--- a/frameworks/projects/mobilecomponents/manifest.xml
+++ b/frameworks/projects/mobilecomponents/manifest.xml
@@ -25,8 +25,6 @@
-->
<componentPackage>
<component id="ActionBar" class="spark.components.ActionBar"/>
- <component id="Callout" class="spark.components.Callout"/>
- <component id="CalloutButton" class="spark.components.CalloutButton"/>
<component id="CrossFadeViewTransition" class="spark.transitions.CrossFadeViewTransition"/>
<component id="DateSpinner" class="spark.components.DateSpinner"/>
<component id="DateSpinnerItemRenderer" class="spark.components.calendarClasses.DateSpinnerItemRenderer"/>
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as b/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
index f213281..7da878a 100644
--- a/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
+++ b/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
@@ -35,6 +35,6 @@ internal class MobileComponentsClasses
import spark.components.supportClasses.StyleableStageText; StyleableStageText;
import spark.components.supportClasses.StyleableTextField; StyleableTextField;
import spark.components.ActionBarDefaultButtonAppearance; ActionBarDefaultButtonAppearance;
- import spark.components.ContentBackgroundAppearance; ContentBackgroundAppearance;
+
}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as b/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
index 17f8e56..d5468cd 100644
--- a/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
+++ b/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
@@ -34,6 +34,5 @@ internal class MobileComponentsClassesAIR2
import spark.preloaders.SplashScreen; SplashScreen;
import spark.components.supportClasses.StyleableTextField; StyleableTextField;
import spark.components.ActionBarDefaultButtonAppearance; ActionBarDefaultButtonAppearance;
- import spark.components.ContentBackgroundAppearance; ContentBackgroundAppearance;
}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/components/ArrowDirection.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/ArrowDirection.as b/frameworks/projects/mobilecomponents/src/spark/components/ArrowDirection.as
deleted file mode 100644
index 2ef7c4c..0000000
--- a/frameworks/projects/mobilecomponents/src/spark/components/ArrowDirection.as
+++ /dev/null
@@ -1,84 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 spark.components
-{
-/**
- * Enumeration of arrow directions for use in visual components.
- *
- * @see spark.components.Callout#arrowDirection
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-public class ArrowDirection
-{
- //--------------------------------------------------------------------------
- //
- // Class constants
- //
- //--------------------------------------------------------------------------
-
- /**
- * Arrow points right.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const RIGHT:String = "right";
-
- /**
- * Arrow points up.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const UP:String = "up";
-
- /**
- * Arrow points left.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const LEFT:String = "left";
-
- /**
- * Arrow points down.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const DOWN:String = "down";
-
- /**
- * No arrow direciton.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public static const NONE:String = "none";
-}
-}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/components/Callout.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/Callout.as b/frameworks/projects/mobilecomponents/src/spark/components/Callout.as
deleted file mode 100644
index 8615ab5..0000000
--- a/frameworks/projects/mobilecomponents/src/spark/components/Callout.as
+++ /dev/null
@@ -1,1669 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 spark.components
-{
-import flash.display.DisplayObject;
-import flash.display.DisplayObjectContainer;
-import flash.events.Event;
-import flash.geom.ColorTransform;
-import flash.geom.Matrix;
-import flash.geom.Point;
-import flash.geom.Rectangle;
-
-import mx.core.DPIClassification;
-import mx.core.FlexGlobals;
-import mx.core.ILayoutElement;
-import mx.core.IVisualElement;
-import mx.core.LayoutDirection;
-import mx.core.UIComponent;
-import mx.core.mx_internal;
-import mx.events.ResizeEvent;
-import mx.managers.SystemManager;
-import mx.utils.MatrixUtil;
-import mx.utils.PopUpUtil;
-
-use namespace mx_internal;
-
-//--------------------------------------
-// Styles
-//--------------------------------------
-
-/**
- * Appearance of the <code>contentGroup</code>.
- * Valid MXML values are <code>inset</code>,
- * <code>flat</code>, and <code>none</code>.
- *
- * <p>In ActionScript, you can use the following constants
- * to set this property:
- * <code>ContentBackgroundAppearance.INSET</code>,
- * <code>ContentBackgroundAppearance.FLAT</code> and
- * <code>ContentBackgroundAppearance.NONE</code>.</p>
- *
- * @default ContentBackgroundAppearance.INSET
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-[Style(name="contentBackgroundAppearance", type="String", enumeration="inset,flat,none", inherit="no")]
-
-//--------------------------------------
-// Other metadata
-//--------------------------------------
-
-[IconFile("Callout.png")]
-
-/**
- * The Callout container is a SkinnablePopUpContainer that functions as a pop-up
- * with additional owner-relative positioning options similar to PopUpAnchor.
- * Callout also adds an optional <code>arrow</code> skin part that visually
- * displays the direction toward the owner.
- *
- * <p>The following image shows a Callout container labeled 'Settings':</p>
- *
- * <p>
- * <img src="../../images/ca_calloutViewNav_ca.png" alt="Callout container" />
- * </p>
- *
- * <p>You can also use the CalloutButton control to open a callout container.
- * The CalloutButton control encapsulates in a single control the callout container
- * and all of the logic necessary to open and close the callout.
- * The CalloutButton control is then said to the be the owner, or host,
- * of the callout.</p>
- *
- * <p>Callout uses the <code>horizontalPosition</code> and
- * <code>verticalPosition</code> properties to determine the position of the
- * Callout relative to the owner that is specified by the <code>open()</code>
- * method.
- * Both properties can be set to <code>CalloutPosition.AUTO</code> which selects a
- * position based on the aspect ratio of the screen for the Callout to fit
- * with minimal overlap with the owner and and minimal adjustments at the
- * screen bounds.</p>
- *
- * <p>Once positioned, the Callout positions the arrow on the side adjacent
- * to the owner, centered as close as possible on the horizontal or vertical
- * center of the owner as appropriate. The arrow is hidden in cases where
- * the Callout position is not adjacent to any edge.</p>
- *
- * <p>You do not create a Callout container as part of the normal layout
- * of its parent container.
- * Instead, it appears as a pop-up container on top of its parent.
- * Therefore, you do not create it directly in the MXML code of your application.</p>
- *
- * <p>Instead, you create is as an MXML component, often in a separate MXML file.
- * To show the component create an instance of the MXML component, and
- * then call the <code>open()</code> method.
- * You can also set the size and position of the component when you open it.</p>
- *
- * <p>To close the component, call the <code>close()</code> method.
- * If the pop-up needs to return data to a handler, you can add an event listener for
- * the <code>PopUp.CLOSE</code> event, and specify the returned data in
- * the <code>close()</code> method.</p>
- *
- * <p>The Callout is initially in its <code>closed</code> skin state.
- * When it opens, it adds itself as a pop-up to the PopUpManager,
- * and transition to the <code>normal</code> skin state.
- * To define open and close animations, use a custom skin with transitions between
- * the <code>closed</code> and <code>normal</code> skin states.</p>
- *
- * <p>Callout changes the default inheritance behavior seen in Flex components
- * and instead, inherits styles from the top-level application. This prevents
- * Callout's contents from unintentionally inheriting styles from an owner
- * (i.e. Button or TextInput) where the default appearance was desired and
- * expected.</p>
- *
- * <p>The Callout container has the following default characteristics:</p>
- * <table class="innertable">
- * <tr><th>Characteristic</th><th>Description</th></tr>
- * <tr><td>Default size</td><td>Large enough to display its children</td></tr>
- * <tr><td>Minimum size</td><td>0 pixels</td></tr>
- * <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr>
- * <tr><td>Default skin class</td><td>spark.skins.mobile.CalloutSkin</td></tr>
- * </table>
- *
- * @mxml <p>The <code><s:Callout></code> tag inherits all of the tag
- * attributes of its superclass and adds the following tag attributes:</p>
- *
- * <pre>
- * <s:Callout
- * <strong>Properties</strong>
- * horizontalPosition="auto"
- * verticalPosition="auto"
- *
- * <strong>Styles</strong>
- * contentBackgroundAppearance="inset"
- * />
- * </pre>
- *
- * @see spark.components.CalloutButton
- * @see spark.skins.mobile.CalloutSkin
- * @see spark.components.ContentBackgroundAppearance
- * @see spark.components.CalloutPosition
- *
- * @includeExample examples/CalloutExample.mxml -noswf
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
-public class Callout extends SkinnablePopUpContainer
-{
-
- //--------------------------------------------------------------------------
- //
- // Class constants
- //
- //--------------------------------------------------------------------------
-
- private static var decomposition:Vector.<Number> = new <Number>[0,0,0,0,0];
-
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
-
- /**
- * Constructor.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function Callout()
- {
- super();
- }
-
- //--------------------------------------------------------------------------
- //
- // Skin parts
- //
- //--------------------------------------------------------------------------
-
- [Bindable]
- [SkinPart(required="false")]
-
- /**
- * An optional skin part that visually connects the owner to the
- * contentGroup.
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public var arrow:UIComponent;
-
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
-
- private var invalidatePositionFlag:Boolean = false;
-
- //--------------------------------------------------------------------------
- //
- // Properties
- //
- //--------------------------------------------------------------------------
-
- //----------------------------------
- // horizontalPosition
- //----------------------------------
-
- private var _horizontalPosition:String = CalloutPosition.AUTO;
-
- [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
-
- /**
- * Horizontal position of the callout relative to the owner.
- *
- * <p>Possible values are <code>"before"</code>, <code>"start"</code>,
- * <code>"middle"</code>, <code>"end"</code>, <code>"after"</code>,
- * and <code>"auto"</code> (default).</p>
- *
- * @default CalloutPosition.AUTO
- * @see spark.components.CalloutPosition
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get horizontalPosition():String
- {
- return _horizontalPosition;
- }
-
- /**
- * @private
- */
- public function set horizontalPosition(value:String):void
- {
- if (value == _horizontalPosition)
- return;
-
- _horizontalPosition = value;
-
- invalidatePosition();
- }
-
- //----------------------------------
- // actualHorizontalPosition
- //----------------------------------
-
- private var _actualHorizontalPosition:String;
-
- /**
- * Fully resolved horizontal position after evaluating CalloutPosition.AUTO.
- *
- * <p>Update this property in <code>commitProperties()</code> when the
- * explicit <code>horizontalPosition</code> is CalloutPosition.AUTO.
- * This property must be updated in <code>updatePopUpPosition()</code>
- * when attempting to reposition the Callout.</p>
- *
- * <p>Subclasses should read this property when computing the <code>arrowDirection</code>,
- * the arrow position in <code>updateSkinDisplayList()</code>.</p>
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- protected function get actualHorizontalPosition():String
- {
- if (_actualHorizontalPosition)
- return _actualHorizontalPosition;
-
- return horizontalPosition;
- }
-
- /**
- * @private
- */
- protected function set actualHorizontalPosition(value:String):void
- {
- _actualHorizontalPosition = value;
- }
-
- //----------------------------------
- // verticalPosition
- //----------------------------------
-
- private var _verticalPosition:String = CalloutPosition.AUTO;
-
- [Inspectable(category="General", enumeration="before,start,middle,end,after,auto", defaultValue="auto")]
-
- /**
- * Vertical position of the callout relative to the owner.
- *
- * <p>Possible values are <code>"before"</code>, <code>"start"</code>,
- * <code>"middle"</code>, <code>"end"</code>, <code>"after"</code>,
- * and <code>"auto"</code> (default).</p>
- *
- * @default CalloutPosition.AUTO
- * @see spark.components.CalloutPosition
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get verticalPosition():String
- {
- return _verticalPosition;
- }
-
- /**
- * @private
- */
- public function set verticalPosition(value:String):void
- {
- if (value == _verticalPosition)
- return;
-
- _verticalPosition = value;
-
- invalidatePosition();
- }
-
- //----------------------------------
- // actualVerticalPosition
- //----------------------------------
-
- private var _actualVerticalPosition:String;
-
- /**
- * Fully resolved vertical position after evaluating CalloutPosition.AUTO.
- *
- * <p>Update this property in <code>commitProperties()</code> when the
- * explicit <code>verticalPosition</code> is CalloutPosition.AUTO.
- * This property must be updated in <code>updatePopUpPosition()</code>
- * when attempting to reposition the Callout.</p>
- *
- * <p>Subclasses should read this property when computing the <code>arrowDirection</code>,
- * the arrow position in <code>updateSkinDisplayList()</code>.</p>
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- protected function get actualVerticalPosition():String
- {
- if (_actualVerticalPosition)
- return _actualVerticalPosition;
-
- return verticalPosition;
- }
-
- /**
- * @private
- */
- protected function set actualVerticalPosition(value:String):void
- {
- _actualVerticalPosition = value;
- }
-
- //----------------------------------
- // arrowDirection
- //----------------------------------
-
- private var _arrowDirection:String = ArrowDirection.NONE;
-
- /**
- * @private
- * Indicates if arrow direction was flipped automatically.
- */
- private var arrowDirectionAdjusted:Boolean = false;
-
- /**
- * A read-only property that indicates the direction from the callout
- * towards the owner.
- *
- * <p>This value is computed based on the callout position given by
- * <code>horizontalPosition</code> and <code>verticalPosition</code>.
- * Exterior and interior positions will point from the callout towards
- * the edge of the owner. Corner and absolute center positions are not
- * supported and will return a value of <code>"none".</code></p>
- *
- * @default none
- *
- * @see spark.components.ArrowDirection
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- public function get arrowDirection():String
- {
- return _arrowDirection;
- }
-
- /**
- * @private
- * Invalidate skin when the arrowDirection changes. Dispatches an
- * "arrowDirectionChanged" event when the property is set.
- */
- mx_internal function setArrowDirection(value:String):void
- {
- if (_arrowDirection == value)
- return;
-
- _arrowDirection = value;
-
- // Instead of using skin states for each arrowDirection, the
- // skin must override commitProperties() and account for
- // arrowDirection on it's own.
- skin.invalidateProperties();
-
- // adjust margins based on arrow direction
- switch (arrowDirection)
- {
- case ArrowDirection.DOWN:
- {
- // Set the marginBottom to zero to place the arrow adjacent to the keyboard
- softKeyboardEffectMarginBottom = 0;
- softKeyboardEffectMarginTop = margin;
- break;
- }
- case ArrowDirection.UP:
- {
- // Arrow should already be adjacent to the owner or the top of
- // the screen.
- softKeyboardEffectMarginTop = 0;
- softKeyboardEffectMarginBottom = margin;
- break;
- }
- default:
- {
- softKeyboardEffectMarginBottom = margin;
- softKeyboardEffectMarginTop = margin;
- break;
- }
- }
-
- if (hasEventListener("arrowDirectionChanged"))
- dispatchEvent(new Event("arrowDirectionChanged"));
- }
-
- //----------------------------------
- // margin
- //----------------------------------
-
- private var _margin:Number = NaN;
-
- /**
- * @private
- * Defines a margin around the Callout to nudge it's position away from the
- * edge of the screen.
- */
- mx_internal function get margin():Number
- {
- if (isNaN(_margin))
- {
- var dpi:Number = FlexGlobals.topLevelApplication["applicationDPI"];
-
- if (dpi)
- {
- switch (dpi)
- {
- case DPIClassification.DPI_640:
- {
- _margin = 32;
- break;
- }
- case DPIClassification.DPI_480:
- {
- _margin = 24;
- break;
- }
- case DPIClassification.DPI_320:
- {
- _margin = 16;
- break;
- }
- case DPIClassification.DPI_240:
- {
- _margin = 12;
- break;
- }
- case DPIClassification.DPI_120:
- {
- _margin = 6;
- break;
- }
- default:
- {
- // default DPI_160
- _margin = 8;
- break;
- }
- }
- }
- else
- {
- _margin = 8;
- }
- }
-
- return _margin;
- }
-
- private var _explicitMoveForSoftKeyboard:Boolean = false;
-
- /**
- * @private
- */
- override public function get moveForSoftKeyboard():Boolean
- {
- // If no explicit setting, then automatically disable move when
- // pointing up towards the owner.
- if (!_explicitMoveForSoftKeyboard &&
- (arrowDirection == ArrowDirection.UP))
- {
- return false;
- }
-
- return super.moveForSoftKeyboard;
- }
-
- /**
- * @private
- */
- override public function set moveForSoftKeyboard(value:Boolean):void
- {
- super.moveForSoftKeyboard = value;
-
- _explicitMoveForSoftKeyboard = true;
- }
-
- //----------------------------------
- // calloutMaxWidth
- //----------------------------------
-
- private var _calloutMaxWidth:Number = NaN;
-
- /**
- * @private
- */
- mx_internal function get calloutMaxWidth():Number
- {
- return _calloutMaxWidth;
- }
-
- /**
- * @private
- */
- mx_internal function set calloutMaxWidth(value:Number):void
- {
- if (_calloutMaxWidth == value)
- return;
-
- _calloutMaxWidth = value;
-
- invalidateMaxSize();
- }
-
-
- //----------------------------------
- // calloutMaxHeight
- //----------------------------------
-
- private var _calloutMaxHeight:Number = NaN;
-
- /**
- * @private
- */
- mx_internal function get calloutMaxHeight():Number
- {
- return _calloutMaxHeight;
- }
-
- /**
- * @private
- */
- mx_internal function set calloutMaxHeight(value:Number):void
- {
- if (_calloutMaxHeight == value)
- return;
-
- _calloutMaxHeight = value;
-
- invalidateMaxSize();
- }
-
-
- //--------------------------------------------------------------------------
- //
- // Overridden methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- */
- override public function get explicitMaxWidth():Number
- {
- if (!isNaN(super.explicitMaxWidth))
- return super.explicitMaxWidth;
-
- return calloutMaxWidth;
- }
-
- /**
- * @private
- */
- override public function get explicitMaxHeight():Number
- {
- if (!isNaN(super.explicitMaxHeight))
- return super.explicitMaxHeight;
-
- return calloutMaxHeight;
- }
-
- /**
- * @private
- */
- override protected function commitProperties():void
- {
- super.commitProperties();
-
- // Do not commit position changes if closed (no owner) or owner was
- // removed from the display list.
- if (!owner || !owner.parent)
- return;
-
- // Compute actual positions when using AUTO
- commitAutoPosition();
-
- // Compute max size based on actual positions
- commitMaxSize();
-
- if (arrow)
- {
- // arrowDirection can be set in 2 ways: (1) horizontalPostion/verticalPosition
- // changes and (2) flipping the axis to fit on screen.
- if (!arrowDirectionAdjusted)
- {
- // Invalidate only when the arrow direction changes
- var direction:String = determineArrowPosition(actualHorizontalPosition,
- actualVerticalPosition);
-
- if (arrowDirection != direction)
- {
- setArrowDirection(direction);
-
- if (arrow)
- arrow.visible = (arrowDirection != ArrowDirection.NONE);
- }
- }
-
- // Always reset the arrow position
- invalidateDisplayList();
- }
- }
-
- /**
- * @private
- * Re-position the pop-up using actualHorizontalPosition and
- * actualVerticalPosition.
- */
- override public function updatePopUpPosition():void
- {
- if (!owner || !systemManager)
- return;
-
- var popUpPoint:Point = calculatePopUpPosition();
- var ownerComponent:UIComponent = owner as UIComponent;
- var concatenatedColorTransform:ColorTransform =
- (ownerComponent) ? ownerComponent.$transform.concatenatedColorTransform : null;
-
- PopUpUtil.applyPopUpTransform(owner, concatenatedColorTransform,
- systemManager, this, popUpPoint);
- }
-
- /**
- * @private
- *
- * Cooperative layout
- * @see spark.components.supportClasses.TrackBase#partAdded
- */
- override protected function partAdded(partName:String, instance:Object):void
- {
- super.partAdded(partName, instance);
-
- if (instance == arrow)
- arrow.addEventListener(ResizeEvent.RESIZE, arrow_resizeHandler);
- }
-
- /**
- * @private
- */
- override protected function partRemoved(partName:String, instance:Object):void
- {
- super.partRemoved(partName, instance);
-
- if (instance == arrow)
- arrow.removeEventListener(ResizeEvent.RESIZE, arrow_resizeHandler);
- }
-
- /**
- * @private
- */
- override public function open(owner:DisplayObjectContainer, modal:Boolean=false):void
- {
- if (isOpen)
- return;
-
- // reset state
- invalidatePositionFlag = false;
- arrowDirectionAdjusted = false;
-
- // Add to PopUpManager, calls updatePopUpPosition(), and change state
- super.open(owner, modal);
-
- // Reposition the callout when the screen changes
- var systemManagerParent:SystemManager = this.parent as SystemManager;
-
- if (systemManagerParent)
- systemManagerParent.addEventListener(Event.RESIZE, systemManager_resizeHandler);
- }
-
- /**
- * @private
- */
- override public function close(commit:Boolean=false, data:*=null):void
- {
- if (!isOpen)
- return;
-
- var systemManagerParent:SystemManager = this.parent as SystemManager;
-
- if (systemManagerParent)
- systemManagerParent.removeEventListener(Event.RESIZE, systemManager_resizeHandler);
-
- super.close(commit, data);
- }
-
- /**
- * @private
- */
- override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
- {
- super.updateDisplayList(unscaledWidth, unscaledHeight);
-
- // Callout can be respositioned while open via SystemManager resize or
- // explicit changes to horizontalPostion and verticalPosition.
- if (isOpen && invalidatePositionFlag)
- {
- updatePopUpPosition();
- invalidatePositionFlag = false;
- }
-
- // Position the arrow
- updateSkinDisplayList();
- }
-
- //--------------------------------------------------------------------------
- //
- // Methods
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- */
- private function invalidatePosition():void
- {
- arrowDirectionAdjusted = false;
-
- invalidateProperties();
-
- if (isOpen)
- invalidatePositionFlag = true;
- }
-
- /**
- * @private
- * Force a new measurement when callout should use it's screen-constrained
- * max size.
- */
- private function invalidateMaxSize():void
- {
- // calloutMaxWidth and calloutMaxHeight don't invalidate
- // explicitMaxWidth or explicitMaxHeight. If callout's max size changes
- // and explicit max sizes aren't set, then invalidate size here so that
- // callout's max size is applied.
- if (!canSkipMeasurement() && !isMaxSizeSet)
- skin.invalidateSize();
- }
-
- /**
- * Sets the bounds of <code>arrow</code>, whose geometry isn't fully
- * specified by the skin's layout.
- *
- * <p>Subclasses can override this method to update the arrow's size,
- * position, and visibility, based on the computed
- * <code>arrowDirection</code>.</p>
- *
- * <p>By default, this method aligns the arrow on the shorter of either
- * the <code>arrow</code> bounds or the <code>owner</code> bounds. This
- * implementation assumes that the <code>arrow</code> and the Callout skin
- * share the same coordinate space.</p>
- *
- * @langversion 3.0
- * @playerversion AIR 3
- * @productversion Flex 4.6
- */
- protected function updateSkinDisplayList():void
- {
- var ownerVisualElement:IVisualElement = owner as IVisualElement;
-
- // Sanity check to verify owner is still on the display list. If not,
- // leave the arrow in the current position.
- if (!arrow || !ownerVisualElement ||
- (arrowDirection == ArrowDirection.NONE) ||
- (!ownerVisualElement.parent))
- return;
-
- var isStartPosition:Boolean = false;
- var isMiddlePosition:Boolean = false;
- var isEndPosition:Boolean = false;
-
- var position:String = (isArrowVertical) ? actualHorizontalPosition : actualVerticalPosition;
-
- isStartPosition = (position == CalloutPosition.START);
- isMiddlePosition = (position == CalloutPosition.MIDDLE);
- isEndPosition = (position == CalloutPosition.END);
-
- var isEndOfCallout:Boolean = (arrowDirection == ArrowDirection.DOWN)
- || (arrowDirection == ArrowDirection.RIGHT);
-
- var calloutWidth:Number = getLayoutBoundsWidth();
- var calloutHeight:Number = getLayoutBoundsHeight();
- var arrowWidth:Number = arrow.getLayoutBoundsWidth();
- var arrowHeight:Number = arrow.getLayoutBoundsHeight();
-
- // arrow X/Y in pop-up coordinates
- var arrowX:Number = 0;
- var arrowY:Number = 0;
-
- // Max arrow positions
- var maxArrowX:Number = calloutWidth - arrowWidth;
- var maxArrowY:Number = calloutHeight - arrowHeight;
-
- // Find the registration point of the owner
- var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
- var regPoint:Point = owner.localToGlobal(new Point());
- regPoint = sandboxRoot.globalToLocal(regPoint);
-
- if (isArrowVertical)
- {
- // Vertical arrows need horizontal alignment
- var ownerX:Number = regPoint.x;
- var ownerVisibleWidth:Number = (ownerVisualElement)
- ? ownerVisualElement.getLayoutBoundsWidth() : owner.width;
-
- // Edge cases when start/end of owner is not visible
- if ((ownerX < 0) && (ownerVisibleWidth < screen.width))
- ownerVisibleWidth = Math.max(ownerVisibleWidth + ownerX, 0);
- else if ((ownerX >= 0) && ((ownerX + ownerVisibleWidth) >= screen.width))
- ownerVisibleWidth = Math.max(screen.width - ownerX, 0);
-
- ownerVisibleWidth = Math.min(ownerVisibleWidth, screen.width);
-
- if (calloutWidth <= ownerVisibleWidth)
- {
- arrowX = (calloutWidth - arrowWidth) / 2;
- }
- else // if (calloutWidth > ownerWidth)
- {
- // Center the arrow on the owner
- arrowX = (ownerVisibleWidth - arrowWidth) / 2;
-
- // Add owner offset
- if (ownerX > 0)
- arrowX += Math.abs(ownerX - getLayoutBoundsX());
-
- if (ownerX < margin)
- arrowX -= (margin - ownerX);
- }
-
- // arrow should not extend past the callout bounds
- arrowX = Math.max(Math.min(maxArrowX, arrowX), 0);
-
- // Move the arrow to the bottom of the callout
- if (isEndOfCallout)
- arrowY = calloutHeight - arrowHeight;
- }
- else
- {
- // Horizontal arrows need vertical alignment
- var ownerY:Number = regPoint.y;
- var ownerVisibleHeight:Number = (ownerVisualElement)
- ? ownerVisualElement.getLayoutBoundsHeight() : owner.height;
-
- // Edge cases when start/end of owner is not visible
- if ((ownerY < 0) && (ownerVisibleHeight < screen.height))
- ownerVisibleHeight = Math.max(ownerVisibleHeight + ownerY, 0);
- else if ((ownerY >= 0) && ((ownerY + ownerVisibleHeight) >= screen.height))
- ownerVisibleHeight = Math.max(screen.height - ownerY, 0);
-
- ownerVisibleHeight = Math.min(ownerVisibleHeight, screen.height);
-
- if (calloutHeight <= ownerVisibleHeight)
- {
- arrowY = (calloutHeight - arrowHeight) / 2;
- }
- else // if (calloutHeight > ownerHeight)
- {
- // Center the arrow on the owner
- arrowY = (ownerVisibleHeight - arrowHeight) / 2;
-
- // Add owner offset
- if (ownerY > 0)
- arrowY += Math.abs(ownerY - getLayoutBoundsY());
-
- if (ownerY < margin)
- ownerY -= (margin - ownerY);
- }
-
- // arrow should not extend past the callout bounds
- arrowY = Math.max(Math.min(maxArrowY, arrowY), 0);
-
- // Move the arrow to the end of the callout
- if (isEndOfCallout)
- arrowX = calloutWidth - arrowWidth;
- }
-
- arrow.setLayoutBoundsPosition(Math.floor(arrowX), Math.floor(arrowY));
- arrow.invalidateDisplayList();
- }
-
- /**
- * @private
- *
- * Flip or clear the adjusted position when the callout bounds are outside
- * the screen bounds.
- */
- mx_internal function adjustCalloutPosition(actualPosition:String, preferredPosition:String,
- calloutStart:Number, calloutEnd:Number,
- screenStart:Number, screenEnd:Number,
- ownerStart:Number, ownerEnd:Number,
- revert:Boolean=false):String
- {
- if (!actualPosition)
- return null;
-
- var adjustedPosition:String = null;
- var calloutSize:Number = calloutEnd - calloutStart;
-
- // Exterior space
- var exteriorSpaceStart:Number = Math.max(0, ownerStart - screenStart);
- var exteriorSpaceEnd:Number = Math.max(0, ownerEnd - screenEnd);
-
- // Fallback to interior positions if using AUTO and callout can not
- // fit in either exterior positions
- var useInterior:Boolean = (preferredPosition == CalloutPosition.AUTO) &&
- (exteriorSpaceStart < calloutSize) &&
- (exteriorSpaceEnd < calloutSize);
- var isExterior:Boolean = false;
-
- // Flip to opposite position
- switch (actualPosition)
- {
- case CalloutPosition.BEFORE:
- {
- isExterior = true;
-
- if (calloutStart < screenStart)
- adjustedPosition = CalloutPosition.AFTER;
-
- break;
- }
- case CalloutPosition.AFTER:
- {
- isExterior = true;
-
- if (calloutEnd > screenEnd)
- adjustedPosition = CalloutPosition.BEFORE;
-
- break;
- }
- case CalloutPosition.END:
- {
- if (calloutStart < screenStart)
- adjustedPosition = CalloutPosition.START;
- break;
- }
- case CalloutPosition.START:
- {
- if (calloutEnd > screenEnd)
- adjustedPosition = CalloutPosition.END;
- break;
- }
- // case CalloutPosition.MIDDLE:
- // Nudge instead of flipping
- }
-
- // Use interior position if exterior flipping was necessary
- if (useInterior && adjustedPosition && isExterior)
- {
- // Choose the exterior position with the most available space.
- // Note that START grows towards the exterior END and vice versa.
- adjustedPosition = (exteriorSpaceEnd >= exteriorSpaceStart) ?
- CalloutPosition.START : CalloutPosition.END;
- }
-
- // Return null to revert the adjusted position
- // Otherwise, return the incoming position
- if (revert)
- return (adjustedPosition) ? null : actualPosition;
-
- // Adjusted position or null if the callout already fits
- return adjustedPosition;
- }
-
- /**
- * @private
- *
- * Nudge the callout position to fit on screen. Prefer top/left positions
- * and allow overflow to get clipped on the bottom/right.
- */
- mx_internal function nudgeToFit(calloutStart:Number, calloutEnd:Number,
- screenStart:Number, screenEnd:Number,
- scaleFactor:Number):Number
- {
- var position:Number = 0;
-
- if (calloutStart < screenStart)
- position += (screenStart - calloutStart) / scaleFactor;
- else if (calloutEnd > screenEnd)
- position -= (calloutEnd - screenEnd) / scaleFactor;
-
- return position;
- }
-
- /**
- * @private
- *
- * Basically the same as PopUpAnchor, but with more position options
- * including exterior, interior and corner positions.
- *
- * Nudging to fit the screen accounts for <code>margin</code> so that
- * the Callout is not positioned in the margin.
- *
- * <code>arrowDirection</code> will change if required for the callout
- * to fit.
- *
- * @see #margin
- */
- mx_internal function calculatePopUpPosition():Point
- {
- // This implementation doesn't handle rotation
- var sandboxRoot:DisplayObject = systemManager.getSandboxRoot();
- var matrix:Matrix = MatrixUtil.getConcatenatedMatrix(owner, sandboxRoot);
-
- var regPoint:Point = new Point();
-
- if (!matrix)
- return regPoint;
-
- var adjustedHorizontalPosition:String;
- var adjustedVerticalPosition:String;
- var calloutBounds:Rectangle = determinePosition(actualHorizontalPosition,
- actualVerticalPosition, matrix, regPoint);
- var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
-
- // Position the callout in the opposite direction if it
- // does not fit on the screen.
- if (screen)
- {
- adjustedHorizontalPosition = adjustCalloutPosition(
- actualHorizontalPosition, horizontalPosition,
- calloutBounds.left, calloutBounds.right,
- screen.left, screen.right,
- ownerBounds.left, ownerBounds.right);
-
- adjustedVerticalPosition = adjustCalloutPosition(
- actualVerticalPosition, verticalPosition,
- calloutBounds.top, calloutBounds.bottom,
- screen.top, screen.bottom,
- ownerBounds.top, ownerBounds.bottom);
- }
-
- var oldArrowDirection:String = arrowDirection;
- var actualArrowDirection:String = null;
-
- // Reset arrowDirectionAdjusted
- arrowDirectionAdjusted = false;
-
- // Get the new registration point based on the adjusted position
- if ((adjustedHorizontalPosition != null) || (adjustedVerticalPosition != null))
- {
- var adjustedRegPoint:Point = new Point();
- var tempHorizontalPosition:String = (adjustedHorizontalPosition)
- ? adjustedHorizontalPosition : actualHorizontalPosition;
- var tempVerticalPosition:String = (adjustedVerticalPosition)
- ? adjustedVerticalPosition : actualVerticalPosition;
-
- // Adjust arrow direction after adjusting position
- actualArrowDirection = determineArrowPosition(tempHorizontalPosition,
- tempVerticalPosition);
-
- // All position flips gaurantee an arrowDirection change
- setArrowDirection(actualArrowDirection);
- arrowDirectionAdjusted = true;
-
- if (arrow)
- arrow.visible = (arrowDirection != ArrowDirection.NONE);
-
- // Reposition the arrow
- updateSkinDisplayList();
-
- var adjustedBounds:Rectangle = determinePosition(tempHorizontalPosition,
- tempVerticalPosition, matrix, adjustedRegPoint);
-
- if (screen)
- {
- // If we adjusted the position but the callout still doesn't fit,
- // then revert to the original position.
- adjustedHorizontalPosition = adjustCalloutPosition(
- adjustedHorizontalPosition, horizontalPosition,
- adjustedBounds.left, adjustedBounds.right,
- screen.left, screen.right,
- ownerBounds.left, ownerBounds.right,
- true);
-
- adjustedVerticalPosition = adjustCalloutPosition(
- adjustedVerticalPosition, verticalPosition,
- adjustedBounds.top, adjustedBounds.bottom,
- screen.top, screen.bottom,
- ownerBounds.top, ownerBounds.bottom,
- true);
- }
-
- if ((adjustedHorizontalPosition != null) || (adjustedVerticalPosition != null))
- {
- regPoint = adjustedRegPoint;
- calloutBounds = adjustedBounds;
-
- // Temporarily set actual positions to reposition the arrow
- if (adjustedHorizontalPosition)
- actualHorizontalPosition = adjustedHorizontalPosition;
-
- if (adjustedVerticalPosition)
- actualVerticalPosition = adjustedVerticalPosition;
-
- // Reposition the arrow with the new actual position
- updateSkinDisplayList();
- }
- else
- {
- // Restore previous arrow direction *before* reversing the
- // adjusted positions
- setArrowDirection(oldArrowDirection);
- arrowDirectionAdjusted = false;
-
- // Reposition the arrow to the original position
- updateSkinDisplayList();
- }
- }
-
- MatrixUtil.decomposeMatrix(decomposition, matrix, 0, 0);
- var concatScaleX:Number = decomposition[3];
- var concatScaleY:Number = decomposition[4];
-
- // If the callout still doesn't fit, then nudge it
- // so it is completely on the screen. Make sure to include scale.
- var screenTop:Number = screen.top;
- var screenBottom:Number = screen.bottom;
- var screenLeft:Number = screen.left;
- var screenRight:Number = screen.right;
-
- // Allow zero margin on the the side with the arrow
- switch (arrowDirection)
- {
- case ArrowDirection.UP:
- {
- screenBottom -= margin;
- screenLeft += margin;
- screenRight -= margin
- break;
- }
- case ArrowDirection.DOWN:
- {
- screenTop += margin;
- screenLeft += margin;
- screenRight -= margin
- break;
- }
- case ArrowDirection.LEFT:
- {
- screenTop += margin;
- screenBottom -= margin;
- screenRight -= margin
- break;
- }
- case ArrowDirection.RIGHT:
- {
- screenTop += margin;
- screenBottom -= margin;
- screenLeft += margin;
- break;
- }
- default:
- {
- screenTop += margin;
- screenBottom -= margin;
- screenLeft += margin;
- screenRight -= margin
- break;
- }
- }
-
- regPoint.y += nudgeToFit(calloutBounds.top, calloutBounds.bottom,
- screenTop, screenBottom, concatScaleY);
-
- regPoint.x += nudgeToFit(calloutBounds.left, calloutBounds.right,
- screenLeft, screenRight, concatScaleX);
-
- // Compute the stage coordinates of the upper,left corner of the PopUp, taking
- // the postTransformOffsets - which include mirroring - into account.
- // If we're mirroring, then the implicit assumption that x=left will fail,
- // so we compensate here.
-
- if (layoutDirection == LayoutDirection.RTL)
- regPoint.x += calloutBounds.width;
- return MatrixUtil.getConcatenatedComputedMatrix(owner, sandboxRoot).transformPoint(regPoint);
- }
-
- /**
- * @private
- * Computes <code>actualHorizontalPosition</code> and/or
- * <code>actualVerticalPosition</code> values when using
- * <code>CalloutPosition.AUTO</code>. When implementing subclasses of
- * Callout, use <code>actualHorizontalPosition</code> and
- * <code>actualVerticalPosition</code> to compute
- * <code>arrowDirection</code> and positioning in
- * <code>updatePopUpPosition()</code> and <code>updateSkinDisplayList()</code>.
- *
- * <p>The default implementation chooses "outer" positions for the callout
- * such that the owner is not obscured. Horizontal/Vertical orientation
- * relative to the owner choosen based on the aspect ratio.</p>
- *
- * <p>When the aspect ratio is landscape, and the callout can fit to the
- * left or right of the owner, <code>actualHorizontalPosition</code> is
- * set to <code>CalloutPosition.BEFORE</code> or
- * <code>CalloutPosition.AFTER</code> as appropriate.
- * <code>actualVerticalPosition</code> is set to
- * <code>CalloutPosition.MIDDLE</code> to have the vertical center of the
- * callout align to the vertical center of the owner.</p>
- *
- * <p>When the aspect ratio is portrait, and the callout can fit
- * above or below the owner, <code>actualVerticalPosition</code> is
- * set to <code>CalloutPosition.BEFORE</code> or
- * <code>CalloutPosition.AFTER</code> as appropriate.
- * <code>actualHorizontalPosition</code> is set to
- * <code>CalloutPosition.MIDDLE</code> to have the horizontal center of the
- * callout align to the horizontal center of the owner.</p>
- *
- * <p>Subclasses may override to modify automatic positioning behavior.</p>
- */
- mx_internal function commitAutoPosition():void
- {
- if (!screen || ((horizontalPosition != CalloutPosition.AUTO) &&
- (verticalPosition != CalloutPosition.AUTO)))
- {
- // Use explicit positions instead of AUTO
- actualHorizontalPosition = null;
- actualVerticalPosition = null;
-
- return;
- }
-
- var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
-
- // Use aspect ratio to determine vertical/horizontal preference
- var isLandscape:Boolean = (screen.width > screen.height);
-
- // Exterior space
- var exteriorSpaceLeft:Number = Math.max(0, ownerBounds.left);
- var exteriorSpaceRight:Number = Math.max(0, screen.width - ownerBounds.right);
- var exteriorSpaceTop:Number = Math.max(0, ownerBounds.top);
- var exteriorSpaceBottom:Number = Math.max(0, screen.height - ownerBounds.bottom);
-
- if (verticalPosition != CalloutPosition.AUTO)
- {
- // Horizontal auto only
- switch (verticalPosition)
- {
- case CalloutPosition.START:
- case CalloutPosition.MIDDLE:
- case CalloutPosition.END:
- {
- actualHorizontalPosition = (exteriorSpaceRight > exteriorSpaceLeft) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
- break;
- }
- default:
- {
- actualHorizontalPosition = CalloutPosition.MIDDLE;
- break;
- }
- }
-
- actualVerticalPosition = null;
- }
- else if (horizontalPosition != CalloutPosition.AUTO)
- {
- // Vertical auto only
- switch (horizontalPosition)
- {
- case CalloutPosition.START:
- case CalloutPosition.MIDDLE:
- case CalloutPosition.END:
- {
- actualVerticalPosition = (exteriorSpaceBottom > exteriorSpaceTop) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
- break;
- }
- default:
- {
- actualVerticalPosition = CalloutPosition.MIDDLE;
- break;
- }
- }
-
- actualHorizontalPosition = null;
- }
- else // if ((verticalPosition == CalloutPosition.AUTO) && (horizontalPosition == CalloutPosition.AUTO))
- {
- if (!isLandscape)
- {
- // Arrow will be vertical when in portrait
- actualHorizontalPosition = CalloutPosition.MIDDLE;
- actualVerticalPosition = (exteriorSpaceBottom > exteriorSpaceTop) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
- }
- else
- {
- // Arrow will be horizontal when in landscape
- actualHorizontalPosition = (exteriorSpaceRight > exteriorSpaceLeft) ? CalloutPosition.AFTER : CalloutPosition.BEFORE;
- actualVerticalPosition = CalloutPosition.MIDDLE;
- }
- }
- }
-
- /**
- * @private
- * Return true if user-specified max size if set
- */
- mx_internal function get isMaxSizeSet():Boolean
- {
- var explicitMaxW:Number = super.explicitMaxWidth;
- var explicitMaxH:Number = super.explicitMaxHeight;
-
- return (!isNaN(explicitMaxW) && !isNaN(explicitMaxH));
- }
-
- /**
- * @private
- * Return the original height if the soft keyboard is active. This height
- * is used to stabilize AUTO positioning so that the position is based
- * on the original height of the Callout instead of a possibly shorter
- * height due to soft keyboard effects.
- */
- mx_internal function get calloutHeight():Number
- {
- return (isSoftKeyboardEffectActive) ? softKeyboardEffectCachedHeight : getLayoutBoundsHeight();
- }
-
- /**
- * @private
- * Compute max width and max height. Uses the the owner and screen bounds
- * as well as preferred positions to determine max width and max height
- * for all possible exterior and interior positions.
- */
- mx_internal function commitMaxSize():void
- {
- var ownerBounds:Rectangle = owner.getBounds(systemManager.getSandboxRoot());
- var ownerLeft:Number = ownerBounds.left;
- var ownerRight:Number = ownerBounds.right;
- var ownerTop:Number = ownerBounds.top;
- var ownerBottom:Number = ownerBounds.bottom;
- var maxW:Number;
- var maxH:Number;
-
- switch (actualHorizontalPosition)
- {
- case CalloutPosition.MIDDLE:
- {
- // Callout matches screen width
- maxW = screen.width - (margin * 2);
- break;
- }
- case CalloutPosition.START:
- case CalloutPosition.END:
- {
- // Flip left and right when using inner positions
- ownerLeft = ownerBounds.right;
- ownerRight = ownerBounds.left;
-
- // Fall through
- }
- default:
- {
- // Maximum is the larger of the actual position or flipped position
- maxW = Math.max(ownerLeft, screen.right - ownerRight) - margin;
- break;
- }
- }
-
- // If preferred position was AUTO, then allow maxWidth to grow to
- // fit the interior position if the owner is wide
- if ((horizontalPosition == CalloutPosition.AUTO) &&
- (ownerBounds.width > maxW))
- maxW += ownerBounds.width;
-
- switch (actualVerticalPosition)
- {
- case CalloutPosition.MIDDLE:
- {
- // Callout matches screen height
- maxH = screen.height - (margin * 2);
- break;
- }
- case CalloutPosition.START:
- case CalloutPosition.END:
- {
- // Flip top and bottom when using inner positions
- ownerTop = ownerBounds.bottom;
- ownerBottom = ownerBounds.top;
-
- // Fall through
- }
- default:
- {
- // Maximum is the larger of the actual position or flipped position
- maxH = Math.max(ownerTop, screen.bottom - ownerBottom) - margin;
- break;
- }
- }
-
- // If preferred position was AUTO, then allow maxHeight to grow to
- // fit the interior position if the owner is tall
- if ((verticalPosition == CalloutPosition.AUTO) &&
- (ownerBounds.height > maxH))
- maxH += ownerBounds.height;
-
- calloutMaxWidth = maxW;
- calloutMaxHeight = maxH;
- }
-
- /**
- * @private
- */
- mx_internal function determineArrowPosition(horizontalPos:String, verticalPos:String):String
- {
- // Determine arrow direction, outer positions get priority.
- // Corner positions and center show no arrow
- var direction:String = ArrowDirection.NONE;
-
- if (horizontalPos == CalloutPosition.BEFORE)
- {
- if ((verticalPos != CalloutPosition.BEFORE)
- && (verticalPos != CalloutPosition.AFTER))
- {
- direction = ArrowDirection.RIGHT;
- }
- }
- else if (horizontalPos == CalloutPosition.AFTER)
- {
- if ((verticalPos != CalloutPosition.BEFORE)
- && (verticalPos != CalloutPosition.AFTER))
- {
- direction = ArrowDirection.LEFT;
- }
- }
- else if (verticalPos == CalloutPosition.BEFORE)
- {
- direction = ArrowDirection.DOWN;
- }
- else if (verticalPos == CalloutPosition.AFTER)
- {
- direction = ArrowDirection.UP;
- }
- else if (horizontalPos == CalloutPosition.START)
- {
- direction = ArrowDirection.LEFT;
- }
- else if (horizontalPos == CalloutPosition.END)
- {
- direction = ArrowDirection.RIGHT;
- }
- else if (verticalPos == CalloutPosition.START)
- {
- direction = ArrowDirection.UP;
- }
- else if (verticalPos == CalloutPosition.END)
- {
- direction = ArrowDirection.DOWN;
- }
-
- return direction
- }
-
- /**
- * @private
- *
- * Uses horizontalPosition and verticalPosition to determine the bounds of
- * the callout.
- */
- mx_internal function determinePosition(horizontalPos:String, verticalPos:String,
- matrix:Matrix, registrationPoint:Point):Rectangle
- {
- var ownerVisualElement:ILayoutElement = owner as ILayoutElement;
- var ownerWidth:Number = (ownerVisualElement) ? ownerVisualElement.getLayoutBoundsWidth() : owner.width;
- var ownerHeight:Number = (ownerVisualElement) ? ownerVisualElement.getLayoutBoundsHeight() : owner.height;
- var calloutWidth:Number = getLayoutBoundsWidth();
- var calloutHeight:Number = this.calloutHeight;
-
- switch (horizontalPos)
- {
- case CalloutPosition.BEFORE:
- {
- // The full width of the callout is before the owner
- // All arrow directions are ArrowDirection.RIGHT x=(width - arrow.width)
- registrationPoint.x = -calloutWidth;
- break;
- }
- case CalloutPosition.START:
- {
- // ArrowDirection.LEFT is at x=0
- registrationPoint.x = 0;
- break;
- }
- case CalloutPosition.END:
- {
- // The ends of the owner and callout are aligned
- registrationPoint.x = (ownerWidth - calloutWidth);
- break;
- }
- case CalloutPosition.AFTER:
- {
- // The full width of the callout is after the owner
- // All arrow directions are ArrowDirection.LEFT (x=0)
- registrationPoint.x = ownerWidth;
- break;
- }
- default: // case CalloutPosition.MIDDLE:
- {
- registrationPoint.x = Math.floor((ownerWidth - calloutWidth) / 2);
- break;
- }
- }
-
- switch (verticalPos)
- {
- case CalloutPosition.BEFORE:
- {
- // The full height of the callout is before the owner
- // All arrow directions are ArrowDirection.DOWN y=(height - arrow.height)
- registrationPoint.y = -calloutHeight;
- break;
- }
- case CalloutPosition.START:
- {
- // ArrowDirection.UP is at y=0
- registrationPoint.y = 0;
- break;
- }
- case CalloutPosition.MIDDLE:
- {
- registrationPoint.y = Math.floor((ownerHeight - calloutHeight) / 2);
- break;
- }
- case CalloutPosition.END:
- {
- // The ends of the owner and callout are aligned
- registrationPoint.y = (ownerHeight - calloutHeight);
- break;
- }
- default: //case CalloutPosition.AFTER:
- {
- // The full height of the callout is after the owner
- // All arrow directions are ArrowDirection.UP (y=0)
- registrationPoint.y = ownerHeight;
- break;
- }
- }
-
- var topLeft:Point = registrationPoint.clone();
- var size:Point = MatrixUtil.transformBounds(calloutWidth, calloutHeight, matrix, topLeft);
- var bounds:Rectangle = new Rectangle();
-
- bounds.left = topLeft.x;
- bounds.top = topLeft.y;
- bounds.width = size.x;
- bounds.height = size.y;
-
- return bounds;
- }
-
- /**
- * @private
- */
- mx_internal function get isArrowVertical():Boolean
- {
- return (arrowDirection == ArrowDirection.UP ||
- arrowDirection == ArrowDirection.DOWN);
- }
-
- //--------------------------------------------------------------------------
- //
- // Event handlers
- //
- //--------------------------------------------------------------------------
-
- /**
- * @private
- */
- private function arrow_resizeHandler(event:Event):void
- {
- updateSkinDisplayList();
- }
-
- /**
- * @private
- */
- private function systemManager_resizeHandler(event:Event):void
- {
- // Remove explicit settings if due to Resize effect
- softKeyboardEffectResetExplicitSize();
-
- // Screen resize might require a new arrow direction and callout position
- invalidatePosition();
-
- if (!isSoftKeyboardEffectActive)
- {
- // Force validation and use new screen size only if the keyboard
- // effect is not active. The stage dimensions may be invalid while
- // the soft keyboard is active. See SDK-31860.
- validateNow();
- }
- }
-}
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/0d6e7b32/frameworks/projects/mobilecomponents/src/spark/components/Callout.png
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/Callout.png b/frameworks/projects/mobilecomponents/src/spark/components/Callout.png
deleted file mode 100644
index 36bc882..0000000
Binary files a/frameworks/projects/mobilecomponents/src/spark/components/Callout.png and /dev/null differ
[8/8] git commit: [flex-sdk] [refs/heads/callout] - Merge branch
'develop' of https://git-wip-us.apache.org/repos/asf/flex-sdk into callout
FIXED https://issues.apache.org/jira/browse/FLEX-33350 - mobile Callout moved
to spark - Added borderColor and bor
Posted by ma...@apache.org.
Merge branch 'develop' of https://git-wip-us.apache.org/repos/asf/flex-sdk into callout
FIXED https://issues.apache.org/jira/browse/FLEX-33350
- mobile Callout moved to spark
- Added borderColor and borderThickness styles to Callout
- Desktop & Mobile Callout uses same s:Callout
- MobileSkin refactored
- new ActionScriptSkinBase class takes 99% of MobileSkin, and belongs to spark
- MobileSkin inherts from ActionScriptSkinBase with few overriddes
- New skin for desktop Callout = spark.skins.spark.CalloutSkin
- inherits from ActionScriptSkinBase
- duplicated from mobile skin (pure AS skin)
- with different css settings: lighter frame, and dark gray 1px border
- Limitation: CalloutSkin not a SparkSkin (chromeColor has no effect)
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/891df758
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/891df758
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/891df758
Branch: refs/heads/callout
Commit: 891df758147b14003eb02ff9199482e7a5a09fe5
Parents: 074354c 320dea3
Author: mamsellem <ma...@systar.com>
Authored: Tue Oct 8 02:24:38 2013 +0200
Committer: mamsellem <ma...@systar.com>
Committed: Tue Oct 8 02:26:29 2013 +0200
----------------------------------------------------------------------
frameworks/projects/experimental/compile-config.xml | 2 +-
frameworks/projects/experimental_mobile/compile-config.xml | 2 +-
.../src/spark/skins/mobile/supportClasses/CalloutArrow.as | 1 -
3 files changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/891df758/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
----------------------------------------------------------------------
diff --cc frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
index 453068c,35f8757..ac8823d
--- a/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
+++ b/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/CalloutArrow.as
@@@ -20,7 -20,7 +20,6 @@@
package spark.skins.mobile.supportClasses
{
import flash.display.BlendMode;
--import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.GraphicsPathCommand;