tags:

views:

3018

answers:

5

Our Flex app automatically resizes with the browser window, we've addressed a whole bunch of scaling issues quite easily but one that remains is tooltips. They show in the wrong location on screen, not being scaled properly based on the window size. Since tooltips are positioned automatically, how can we address this?

To clarify I am using the built-in flex tooltips. And the problem is not that tooltips don't move as the app resizes when they are shown. It's that if I resize the app, tooltips will now all be shown in the wrong place even through everything else automatically updates correctly.

A: 

I don't think there is a great solution to this problem since the ToolTipManager is not aware of when the currentTarget for a ToolTip changes location on the stage. The fix pretty much has to go into the Flex Framework itself. I have cludged together something that seems to work but it requires monkeypatching the Flex Framework.

  1. Copy mx.managers.ToolTipManager.as into your project in a "mx.managers" package you create.

  2. Add this method to the bottom of the file.

    public static function positionToolTip() : void { ToolTipManagerImpl(impl).positionTip(); }

  3. Call this method on the resize event of your application.

cliff.meyers
+1  A: 

Not sure if you found a solution to this one, but there's a simpler approach. This code hooks into the tooltip-show event, during the capture phase (before it displays), to scale and position it appropriately based on the scale of the containing element -- in "this" case, the parentApplication document. It also includes a bit of code that, in my case, helped keep the tooltips from drifting off the stage when scaled (so you might only need the first few lines -- t.scaleX and t.scaleY):

import mx.events.ToolTipEvent;

addEventListener(ToolTipEvent.TOOL_TIP_SHOW, handleToolTipShow, true, 0, true);

private function handleToolTipShow(event:ToolTipEvent):void
{
if (event && event.toolTip)
{
 var t:IToolTip = event.toolTip;

 // Scale the tip itself
 t.scaleX = this.scaleX;
 t.scaleY = this.scaleY;

 // Scale the offsets
 var xOffset:int = 10 * this.scaleX;
 var yOffset:int = 10 * this.scaleY;

 // Set the default positioning 
 t.x = parent.mouseX + xOffset;
 t.y = parent.mouseY + yOffset;

 // Set the adjusted height and width
 var th:Number = t.height * this.scaleX;
 var tw:Number = t.width * this.scaleY;

 var rightEdge:int = t.x + tw + xOffset;
 var playerRightEdge:int = parent.width;
 var bottomEdge:int = t.y + th + yOffset;
 var playerBottomEdge:int = parent.height;

 // Offscreen right
 if (rightEdge > playerRightEdge)
 {
  t.move(parent.mouseX - xOffset - tw, parent.mouseY + yOffset);
 }

 // Offscreen bottom
 if (bottomEdge > playerBottomEdge)
 {
  t.move(parent.mouseX + xOffset, parent.mouseY - yOffset - th);
 }
}

}

Hope it helps!

Christian Nunciato
A: 

Try converting the coordinates to Global using contentToGlobal()

A: 

@Christian Nunciato: Your solutions is quite apt for the Custom ToolTip implementation. You can also make a recommendation that the bounds that are being checked may not be of only the parent component but that of the entire application as well. In which case "parent" may be replaced with "parentApplication"

@Abhilash: Merely converting the contentToGlobal() doesn't solve the problem of tooltip falling off the screen edge. This customized solution will be required. If you have managed to accomplish it in an alternate way please share it with us.

@cliff.meyers: I didn't quite understand what you mentioned in your problem. Because I resized my application and Christian's solution worked just fine for me.