This is an automated email from the ASF dual-hosted git repository.

greg-dove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit d224f96cfb4cec35680a7cc42338a1b3681c002c
Author: greg-dove <[email protected]>
AuthorDate: Fri Apr 24 17:26:01 2026 +1200

    Tooltip updates with 2 TooltipBeads.
    A little trickier than I expected... required a bunch of skin updates, but 
I believe that is working now.
---
 .../Style/src/main/resources/style-manifest.xml    |   4 +
 .../main/royale/org/apache/royale/style/Tooltip.as |  42 ++-
 .../royale/style/beads/AdaptiveTooltipBead.as      |  62 ++++
 .../org/apache/royale/style/beads/TooltipBead.as   | 333 +++++++++++++++++++++
 .../org/apache/royale/style/skins/ITooltipSkin.as  |   3 +
 .../org/apache/royale/style/skins/TooltipSkin.as   | 143 ++++++---
 6 files changed, 533 insertions(+), 54 deletions(-)

diff --git a/frameworks/projects/Style/src/main/resources/style-manifest.xml 
b/frameworks/projects/Style/src/main/resources/style-manifest.xml
index 1ce74e9a98..f78e3be009 100644
--- a/frameworks/projects/Style/src/main/resources/style-manifest.xml
+++ b/frameworks/projects/Style/src/main/resources/style-manifest.xml
@@ -336,5 +336,9 @@
   <component id="ToastSkin" class="org.apache.royale.style.skins.ToastSkin"/>
   <component id="TooltipSkin" 
class="org.apache.royale.style.skins.TooltipSkin"/>
   <component id="ITooltipSkin" 
class="org.apache.royale.style.skins.ITooltipSkin"/>
+  
+  
+  <component id="TooltipBead" 
class="org.apache.royale.style.beads.TooltipBead"/>
+  <component id="AdaptiveTooltipBead" 
class="org.apache.royale.style.beads.AdaptiveTooltipBead"/>
 
 </componentPackage>
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Tooltip.as 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Tooltip.as
index ca3c5d4ac3..8a7db62e61 100644
--- 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Tooltip.as
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Tooltip.as
@@ -23,6 +23,7 @@ package org.apache.royale.style
   import org.apache.royale.style.elements.Div;
   import org.apache.royale.style.elements.Span;
   import org.apache.royale.style.skins.ITooltipSkin;
+  import org.apache.royale.geom.Rectangle;
   
   COMPILE::JS {
     import org.apache.royale.core.WrappedHTMLElement;
@@ -31,9 +32,22 @@ package org.apache.royale.style
   public class Tooltip extends StyleUIBase implements IHasLabel
   {
     
-    public function Tooltip()
+    public function Tooltip(forDisplayInPopup:Boolean = false)
     {
       super();
+      useWrapperStyle = true;
+      _forDisplayInPopup = forDisplayInPopup;
+      //set the default direction
+      toggleAttribute("data-direction-top", true);
+    }
+    
+    override public function getWrapperStyle():String{
+      return 'tool-tip';
+    }
+    
+    private var _forDisplayInPopup:Boolean;
+    public function get forDisplayInPopup():Boolean{
+        return _forDisplayInPopup
     }
   
     private var _contentNode:Div;
@@ -171,16 +185,16 @@ package org.apache.royale.style
     public function set direction(value:String):void
     {
       if (value == _direction) return;
-     /* if(_direction){
+      if(_direction){
         toggleAttribute("data-direction-" + _direction, false);
-      }*/
+      }
       if(value){
         switch(value){
           case "left":
           case "right":
           case "bottom":
           case "top":
-         //   toggleAttribute("data-direction-" + value, true);
+            toggleAttribute("data-direction-" + value, true);
             break;
           default:
             throw new Error("Invalid direction: " + value);
@@ -222,7 +236,7 @@ package org.apache.royale.style
       }
     }
 
-    private var _isOpen:Boolean;
+    private var _isOpen:Boolean = false;
 
     public function get isOpen():Boolean
     {
@@ -231,7 +245,7 @@ package org.apache.royale.style
 
     public function set isOpen(value:Boolean):void
     {
-      if(value != !!_isOpen){
+      if(value != _isOpen){
         toggleAttribute("is-open", value);
       }
       _isOpen = value;
@@ -261,5 +275,21 @@ package org.apache.royale.style
       updateFlavorIcon();
       positionTip();
     }
+    
+    public function getFullHeight():Number{
+      var h:Number = height;
+      if (skin) {
+        h += (skin as ITooltipSkin).getExtraHeight();
+      }
+      return h;
+    }
+    
+    public function getFullHWidth():Number{
+      var w:Number = width;
+      if (skin) {
+        w += (skin as ITooltipSkin).getExtraWidth();
+      }
+      return w;
+    }
   }
 }
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/beads/AdaptiveTooltipBead.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/beads/AdaptiveTooltipBead.as
new file mode 100644
index 0000000000..17e706de3f
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/beads/AdaptiveTooltipBead.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 org.apache.royale.style.beads
+{
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.style.Tooltip;
+       import org.apache.royale.core.IParentIUIBase;
+       import org.apache.royale.geom.Point;
+       /**
+        * Provides core functionality for managing display of Tooltips.
+        * AdaptiveTooltipBead supports avoidance of browser edges when the 
tooltip is displayed
+        *
+        * This file includes derived work from Spectrum Royale,
+        * also licensed under the Apache License, Version 2.0.
+        *
+        */
+       public class AdaptiveTooltipBead extends TooltipBead
+       {
+               override protected function determinePosition(comp:IUIBase, 
tooltip:Tooltip):Point
+               {
+                       var margin:int = 0;
+                       var pt:Point = super.determinePosition(comp, tooltip);
+                       var screenWidth:Number = (host.popUpParent as 
IParentIUIBase).width;
+                       var screenHeight:Number = (host.popUpParent as 
IParentIUIBase).height;
+                       if (direction == TooltipBead.LEFT && pt.x < margin)
+                       {
+                               direction = TooltipBead.RIGHT;
+                       } else if (direction == TooltipBead.TOP && pt.y < 
margin)
+                       {
+                               direction = TooltipBead.BOTTOM;
+                       } else if (direction == TooltipBead.RIGHT && (pt.x + 
tooltip.getFullHWidth() + margin) > screenWidth)
+                       {
+                               direction = TooltipBead.LEFT;
+                       } else if (direction == TooltipBead.BOTTOM && (pt.y + 
tooltip.getFullHeight() + margin) > screenHeight)
+                       {
+                               direction = TooltipBead.TOP;    
+                       } else
+                       {
+                               return pt;
+                       }
+                       return super.determinePosition(comp, tooltip);
+               }
+
+       }
+}
+
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/beads/TooltipBead.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/beads/TooltipBead.as
new file mode 100644
index 0000000000..7774f0342b
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/beads/TooltipBead.as
@@ -0,0 +1,333 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.style.beads
+{
+       import org.apache.royale.core.IBead;
+       import org.apache.royale.core.IPopUpHost;
+       import org.apache.royale.core.IStrand;
+       import org.apache.royale.core.IUIBase;
+       import org.apache.royale.events.IEventDispatcher;
+       import org.apache.royale.events.MouseEvent;
+       import org.apache.royale.geom.Point;
+       import org.apache.royale.utils.PointUtils;
+       import org.apache.royale.utils.UIUtils;
+       import org.apache.royale.style.Tooltip;
+       
+       COMPILE::SWF{
+               //for compilation support only
+               import flash.utils.setTimeout;
+               import flash.utils.clearTimeout;
+       }
+       
+       /**
+        * Provides core functionality for managing display of Tooltips. 
+        *
+        * This file includes derived work from Spectrum Royale,
+        * also licensed under the Apache License, Version 2.0.
+        * 
+        */
+       public class TooltipBead implements IBead
+       {
+               public function TooltipBead()
+               {
+               }
+               
+
+               public static const LEFT:String = "left";
+               public static const RIGHT:String = "right";
+               public static const BOTTOM:String = "bottom";
+               public static const TOP:String = "top";
+
+               private static var activeBead:TooltipBead;
+
+               public static function closeTips():void{
+                       if(activeBead){
+                               activeBead.closeTooltip();
+                       }
+               }
+
+               protected var tt:Tooltip;
+               protected var host:IPopUpHost;
+
+               private var _autoClose:Number = 2000;
+
+               /**
+                * Number of milliseconds to auto-close the tooltip
+                * 0 means it stays open
+                * Default is 2000
+                */
+               public function get autoClose():Number
+               {
+                       return _autoClose;
+               }
+
+               public function set autoClose(value:Number):void
+               {
+                       _autoClose = value;
+               }
+
+               private var _delay:Number = 0;
+               /**
+                * Delay (in ms) until tooltip shows
+                */
+               public function get delay():Number{
+                       return _delay;
+               }
+
+               public function set delay(value:Number):void{
+                       _delay = value;
+               }
+
+               private var _stayOpen:Number = 0;
+               /**
+                * How long  (in ms) for the tooltip to stay open after mouse 
leaves.
+                */
+               public function get stayOpen():Number
+               {
+                       return _stayOpen;
+               }
+
+               public function set stayOpen(value:Number):void
+               {
+                       _stayOpen = value;
+               }
+
+               private var _coolDown:Number = 0;
+               /**
+                * ms since last closed tooltip to ignore delay value
+                * See 
https://spectrum.adobe.com/page/tooltip/#Warmup-and-cooldown
+                */
+               public function get coolDown():Number{
+                       return _coolDown;
+               }
+
+               public function set coolDown(value:Number):void{
+                       _coolDown = value;
+               }
+
+               private var _toolTip:String;
+               public function get toolTip():String
+               {
+                       return _toolTip;
+               }
+               public function set toolTip(value:String):void
+               {
+                       _toolTip = value;
+                       if (tt) {
+                               if (value) {
+                                       tt.text = value;
+                               } else {
+                                       closeTooltip();
+                               }
+                       }
+               }
+
+               private var _direction:String = TOP;
+       [Inspectable(category="General", enumeration="left,right,bottom,top", 
defaultValue="top")]
+               public function set direction(value:String):void
+               {
+                       _direction = value;
+                       if (tt)
+                       {
+                               tt.direction = value;
+                       }
+               }
+
+               public function get direction():String
+               {
+                       return _direction;
+               }
+
+               private var _tipPosition:String;
+
+               /**
+                * The position of the tip within the tooltip
+                */
+               public function get tipPosition():String{
+                       return _tipPosition;
+               }
+
+               [Inspectable(category="General", 
enumeration="start,end,center",defaultValue="center")]
+               public function set tipPosition(value:String):void{
+                       _tipPosition = value;
+                       if (tt)
+                       {
+                               tt.tipPosition = value;
+                       }
+               }
+
+               private var _flavor:String;
+
+               /**
+                * The flavor of the Tooltip
+                * One of info, positive and negative, success and error.
+                * To set the Tooltip to the default, specify an empty string
+                */
+               public function get flavor():String
+               {
+                       return _flavor;
+               }
+
+               [Inspectable(category="General", 
enumeration="info,positive,negative,success,error")]
+               public function set flavor(value:String):void
+               {
+                       _flavor = value;
+                       if(tt){
+                               tt.flavor = value;
+                       }
+               }
+
+               protected var _strand:IStrand;
+
+               public function set strand(value:IStrand):void
+               {
+                       _strand = value;
+
+                       (_strand as 
IEventDispatcher).addEventListener("mouseenter", rollOverHandler, false);
+               }
+
+               protected function rollOverHandler(event:MouseEvent):void
+               {
+                       if (!toolTip || tt){
+                               return;
+                       }
+                       (_strand as 
IEventDispatcher).addEventListener("mouseleave", rollOutHandler, false);
+                       
+                       // Already open. Just make sure it stays open and 
closes when it should.
+                       if(activeBead == this && tt && tt.isOpen){
+                               clearTimeouts();
+                               if(_autoClose > 0){
+                                       closeTimeoutId = 
setTimeout(closeTooltip,_autoClose);
+                               }
+                       }
+                       else if(delay == 0 || new Date().getTime() - 
lastShownTS < coolDown){
+                               showTooltip();
+                       } else {
+                               showTimeoutId = setTimeout(showTooltip,delay);
+                       }
+
+               }
+               private var showTimeoutId:Number = 0;
+               private var closeTimeoutId:Number = 0;
+               private var stayOpenTimeoutId:Number = 0;
+               private function clearTimeouts():void{
+                       if(showTimeoutId > 0){
+                               clearTimeout(showTimeoutId);
+                               showTimeoutId = 0;
+                       }
+                       if(closeTimeoutId > 0){
+                               clearTimeout(closeTimeoutId);
+                               closeTimeoutId = 0;
+                       }
+                       if(stayOpenTimeoutId > 0){
+                               clearTimeout(stayOpenTimeoutId);
+                               stayOpenTimeoutId = 0;
+                       }
+
+               }
+
+               protected function createTooltip():void{
+                       if(activeBead && activeBead != this){
+                               activeBead.closeTooltip();
+                       }
+                       activeBead = this;
+
+
+                       var comp:IUIBase = _strand as IUIBase
+                       host = UIUtils.findPopUpHost(comp);
+                       removeTooltip();
+                       tt = new Tooltip(true);
+                       if(_flavor){
+                               tt.flavor = _flavor;
+                       }
+                       tt.direction = _direction;
+                       if(tipPosition){
+                               tt.tipPosition = tipPosition;
+                       }
+               
+                       tt.text = toolTip;
+                       if(_autoClose > 0){
+                               closeTimeoutId = 
setTimeout(closeTooltip,_autoClose);
+                       }
+               }
+
+               protected function showTooltip():void {
+                       createTooltip();
+                       host.popUpParent.addElement(tt, false); // don't 
trigger a layout
+                       var ttWidth:Number = tt.width;
+                       var pt:Point = determinePosition(_strand as IUIBase, 
tt);
+                       tt.x = pt.x;
+                       tt.y = pt.y;
+                       tt.isOpen = true;
+                       if(ttWidth != tt.width){
+                               pt = determinePosition(_strand as IUIBase, tt);
+                               tt.x = pt.x;
+                               tt.y = pt.y;
+                       }
+               }
+
+               protected function determinePosition(comp:IUIBase, 
tooltip:Tooltip):Point
+               {
+                       var pt:Point = new Point();
+                       if (_direction == LEFT) {
+                               pt.x = -tooltip.width;
+                               pt.y = (comp.height - tooltip.height) / 2;
+                       } else if (_direction == TOP) {
+                               pt.x = (comp.width - tooltip.width) / 2;
+                               pt.y = -tooltip.height;
+                       } else if (_direction == RIGHT) {
+                               pt.x = comp.width;
+                               pt.y = (comp.height - tooltip.height) / 2;
+                       } else
+                       {
+                               pt.x = (comp.width - tooltip.width) / 2;
+                               pt.y = comp.height;
+                       }
+
+                       pt = PointUtils.localToGlobal(pt, comp);
+                       return pt;
+               }
+
+               protected function rollOutHandler(event:MouseEvent):void{
+                       (_strand as 
IEventDispatcher).removeEventListener("mouseleave", rollOutHandler, false);
+                       clearTimeouts();
+                       if(stayOpen > 0){
+                               stayOpenTimeoutId = 
setTimeout(closeTooltip,stayOpen);
+                       } else {
+                               closeTooltip();
+                       }
+               }
+               protected function closeTooltip():void{
+                       clearTimeouts();
+                       activeBead = null;
+                       removeTooltip();
+                       closeTimeoutId = 0;
+                       showTimeoutId = 0;
+                       lastShownTS = new Date().getTime();
+               }
+               protected function removeTooltip():void{
+                       if(tt && tt.parent){
+                               tt.parent.removeElement(tt);
+                       }
+                       tt = null;
+               }
+               public static var lastShownTS:Number = 0;
+       }
+}
+
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ITooltipSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ITooltipSkin.as
index a540ba278d..3ad6f55155 100644
--- 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ITooltipSkin.as
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ITooltipSkin.as
@@ -26,5 +26,8 @@ package org.apache.royale.style.skins
                function get tooltipContentStyles():Array;
                function get tipStyles():Array;
                function getIcon(flavor:String):IStyleUIBase;
+               
+               function getExtraHeight():Number;
+               function getExtraWidth():Number;
        }
 }
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/TooltipSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/TooltipSkin.as
index 705ed47666..d481c4dbf0 100644
--- 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/TooltipSkin.as
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/TooltipSkin.as
@@ -33,6 +33,7 @@ package org.apache.royale.style.skins
        import org.apache.royale.style.stylebeads.flexgrid.AlignItems;
        import org.apache.royale.style.stylebeads.flexgrid.Flex;
        import org.apache.royale.style.stylebeads.flexgrid.Gap;
+       import org.apache.royale.style.stylebeads.interact.PointerEvents;
        import org.apache.royale.style.stylebeads.interact.UserSelect;
        import org.apache.royale.style.stylebeads.layout.Bottom;
        import org.apache.royale.style.stylebeads.layout.Display;
@@ -46,7 +47,9 @@ package org.apache.royale.style.skins
        import org.apache.royale.style.stylebeads.sizing.WidthStyle;
        import org.apache.royale.style.stylebeads.spacing.Margin;
        import org.apache.royale.style.stylebeads.spacing.Padding;
+       import org.apache.royale.style.stylebeads.states.GroupPseudo;
        import 
org.apache.royale.style.stylebeads.states.attribute.AttributeState;
+       import org.apache.royale.style.stylebeads.states.attribute.DataState;
        import org.apache.royale.style.stylebeads.transform.Transform;
        import org.apache.royale.style.stylebeads.typography.FontSize;
        import org.apache.royale.style.stylebeads.typography.FontWeight;
@@ -91,27 +94,46 @@ package org.apache.royale.style.skins
 
                private function applyStyles():void
                {
-                       //transform 130ms ease-in-out, opacity 130ms 
ease-in-out, visibility 0ms linear 130ms;
-                       
+
                        var transition:Transition = new Transition()
-                       transition.property = 'transform, opacity, visibility';
+                       transition.property = 'transform,opacity';
+                       transition.duration = '130ms';
+                       transition.timingFunction ='ease-in-out';
+                       const inPopup:Boolean = host.forDisplayInPopup;
                        
-                       transition.timingFunction 
='ease-in-out,ease-in-out,linear'
+                       var openStates:Array = [        
+                               new Visibility('visible'),
+                               new OpacityStyle(100)
+                       ]
+                       if (inPopup) {
+                               var tipMargin:String = computeSize(2 * 
border_radius * getMultiplier(),host.unit);
+                               var transformTop:Transform = new Transform();
+                               transformTop.translateY = '-' + tipMargin;
+                               var transformBottom:Transform = new Transform();
+                               transformBottom.translateY = tipMargin;
+                               var transformLeft:Transform = new Transform();
+                               transformLeft.translateX = '-' + tipMargin;
+                               var transformRight:Transform = new Transform();
+                               transformRight.translateX = tipMargin;
+                               openStates.push(new 
DataState('direction-top',[transformTop]));
+                               openStates.push(new 
DataState('direction-left',[transformLeft]));
+                               openStates.push(new 
DataState('direction-right',[transformRight]));
+                               openStates.push(new 
DataState('direction-bottom',[transformBottom]));
+                       }
                        
-                       //var multiplier:Number = getMultiplier();
+                       var positionStyle:String = inPopup ? 'absolute' : 
'relative';
                        var styles:Array = [
                                new Display('inline-flex'),
                                new AlignItems('center'),
-                               new Position('relative'),
+                               new Position(positionStyle),
                                new UserSelect('none'),
+                               new PointerEvents('none'),
                                transition,
                                new Visibility('hidden'),
                                new OpacityStyle(0),
-                               new AttributeState('is-open',[
-                                               new Visibility('visible'),
-                                               new OpacityStyle(100)
-                               ])
+                               new AttributeState('is-open',openStates)
                        ];
+                       
                        host.setStyles(styles, true);
                }
 
@@ -189,13 +211,7 @@ package org.apache.royale.style.skins
                        border.topColor = backgroundColor.colorSpecifier;
                        
                        //location related:
-                       var locationStyles:Array = []
-                       var tipDirection:String = host.direction;
                        var tipPosition:String = host.tipPosition;
-                       var margin:Margin = new Margin(null,unit);
-                       var transform:Transform = new Transform();
-                       locationStyles.push(margin);
-                       
                        var sideLocation:String;
                        if (tipPosition == 'center') {
                                sideLocation = '50%';
@@ -203,38 +219,50 @@ package org.apache.royale.style.skins
                                var cornerExclusionZone:String = 
computeSize(border_radius * 1.5 * multiplier,unit);
                                sideLocation = 'calc(' + (tipPosition == 
'start' ? '0% + ' : '100% - ') + cornerExclusionZone + ')';
                        }
-
-                       switch(tipDirection) {
-                               case 'bottom':
-                                       margin.left = '-'+tipWidth;
-                                       locationStyles.push(new Bottom('100%'));
-                                       transform.rotate = '180deg';
-                                       locationStyles.push(transform);
-                                       //side location
-                                       locationStyles.push(new 
Left(sideLocation));
-                                       break;
-                               case 'left':
-                                       margin.top = '-'+tipWidth;
-                                       locationStyles.push(new Right('100%'));
-                                       transform.rotate = '90deg';
-                                       locationStyles.push(transform);
-                                       //side location
-                                       locationStyles.push(new 
Top(sideLocation));
-                                       break;
-                               case 'right':
-                                       margin.top = '-'+tipWidth;
-                                       locationStyles.push(new Left('100%'));
-                                       transform.rotate = '-90deg';    
-                                       locationStyles.push(transform);
-                                       //side location
-                                       locationStyles.push(new 
Top(sideLocation));
-                                       break;
-                               default:
-                                       margin.left = '-'+tipWidth;
-                                       locationStyles.push(new Top('100%'));
-                                       //side location
-                                       locationStyles.push(new 
Left(sideLocation));
-                       }
+                       
+                       var verticalPlacementMarginTop:Margin = new 
Margin(null,unit);
+                       verticalPlacementMarginTop.left = '-'+tipWidth;
+                       var verticalPlacementMarginBottom:Margin = new 
Margin(null,unit);
+                       verticalPlacementMarginBottom.left = '-'+tipWidth;
+                       var horizontalPlacementMarginLeft:Margin = new 
Margin(null,unit);
+                       horizontalPlacementMarginLeft.top = '-'+tipWidth;
+                       var horizontalPlacementMarginRight:Margin = new 
Margin(null,unit);
+                       horizontalPlacementMarginRight.top = '-'+tipWidth;
+                       
+                       var bottomRotate:Transform = new Transform();
+                       bottomRotate.rotate = '180deg';
+                       var leftRotate:Transform = new Transform();
+                       leftRotate.rotate = '-90deg';
+                       var rightRotate:Transform = new Transform();
+                       rightRotate.rotate = '90deg';
+                       
+                       var locationStyles:Array = [
+                               new GroupPseudo([
+                                       new DataState('direction-top', [
+                                               verticalPlacementMarginTop,
+                                               new Top('100%'),
+                                               new Left(sideLocation)
+                                       ]),
+                                       new DataState('direction-left', [
+                                               horizontalPlacementMarginLeft,
+                                               leftRotate,
+                                               new Left('100%'),
+                                               new Top(sideLocation)
+                                       ]),
+                                       new DataState('direction-right', [
+                                               horizontalPlacementMarginRight,
+                                               rightRotate,
+                                               new Right('100%'),
+                                               new Top(sideLocation)
+                                       ]),
+                                       new DataState('direction-bottom', [
+                                               verticalPlacementMarginBottom,
+                                               bottomRotate,
+                                               new Bottom('100%'),
+                                               new Left(sideLocation)
+                                       ])
+                               ], host.getWrapperStyle())
+                       ]
                        
                        return [
                                new Position('absolute'),
@@ -291,5 +319,24 @@ package org.apache.royale.style.skins
                                default: return 1;
                        }
                }
+               
+               //Q:why are these here? 
+               //A: because the absolutely positioned tip child does not 
contribute to the host component's measured height and width
+               //these are needed for adaptive positioning. Putting this 
support in the skin will mean different skins can do different things internally
+               public function getExtraHeight():Number{
+                       var dir:String = host.direction;
+                       if (dir =='bottom' || dir=='top') {
+                               return 2 * border_radius;
+                       }
+                       return 0;
+               }
+               
+               public function getExtraWidth():Number{
+                       var dir:String = host.direction;
+                       if (dir =='left' || dir=='right') {
+                               return 2 * border_radius;
+                       }
+                       return 0;
+               }
        }
 }

Reply via email to