2012/09/13

To Customize a Tooltip with an Icon in Flex

Customization is undoubtedly the biggest characteristic of TWaver: node, link, attachment, even tooltip can be customized. It shows some more powerful and more complex functions. Now we will come to an example of customizing Tooltip.
Now let’s analyze the function in detail. Since that when mouse is over the target tooltip shows and does not when mouse is out, we can define a tooltip component to listen to the mouse-move events in the network: if there is an element under the mouse, then the tooltip component will show and the location of the tooltip will be dynamically calculated; otherwise it will be hidden.
this.network.addEventListener(MouseEvent.MOUSE_MOVE, function(e:MouseEvent):void
updateToolTip(e);
});

private function updateToolTip(e:MouseEvent):void {
    var element:IElement = network.getElementByMouseEvent(e, true, 5);
    if(lastElement == element){
        return;
    }
    lastElement = element;
    if(element is Link){
        var point:Point = network.getLogicalPoint(e);
        customTooltip.x = point.x - customTooltip.measuredWidth / 2;
        customTooltip.y = point.y - customTooltip.measuredHeight - 10;
        customTooltip.setText(element.getClient('message'));
        customTooltip.visible = true;
    }else{
        customTooltip.visible = false;
    }
}
Let’s go further to how to realize the tooltip component. First we need to define a class—tooltip, which inherits from canvas. In this way, we can add tooltip directly to network.topCanvas.
public class CustomToolTip extends Canvas {}
Since the interactions and the scroll bars are not needed in the tooltip component, they can be disabled in it.
public function CustomToolTip() {
    this.mouseEnabled = false;
    this.mouseChildren = false;
    this.horizontalScrollPolicy = ScrollPolicy.OFF;
    this.verticalScrollPolicy = ScrollPolicy.OFF;
    this.init();
}
The key point is how to draw the customized tooltip. We need to add the icon and the texts into the tooltip component and at the same time calculate their location in it.

var messageImage:Image = new Image();
messageImage.source =  new messageIcon();
messageImage.x = _hmargin;
messageImage.y = _vmargin;
this.addChild(messageImage);

_component = new UIComponent();
this.addChild(_component);

_message = new TextField();
_message.autoSize = TextFieldAutoSize.LEFT;
_message.x = _hmargin + _iconWidth + _hgap;
_message.y = _vmargin;
_component.addChild(_message);
Next, we need to calculate the width and the height of the tooltip shown in the network, which is dynamically calculated according to the size of texts set in it. Therefore we have rewritten the method measure to calculate the actual width and height of the tooltip.
override protected function measure():void {
    super.measure();
    this.measuredWidth = _hmargin * 2 + _iconWidth + _hgap + _message.width;
    this.measuredHeight = _vmargin + _iconHeight + _vgap + _arrowHeight;
}
Now we are going to make a figure like the shape of tooltip. We all know that tooltip is a rectangle and to beautify it we can make a rectangle with rounded corners, and do not forget that there should be a small triangle under it. The shape can be made by the drawing pen.
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    var g:Graphics = this.graphics;
    g.clear();
    var lineWidth:Number = 1;
    g.lineStyle(lineWidth, 0, 0.5, true, "normal", CapsStyle.ROUND, JointStyle.ROUND);

    var _width:Number = unscaledWidth, _height:Number = unscaledHeight;
    Utils.beginFill(g, 0xFFFFFF, 1, 0, 0, _width, _height, Consts.GRADIENT_LINEAR_EAST, 0xCCCCCC, 1);
    g.drawRoundRect(lineWidth, lineWidth, _width - lineWidth * 2, _height - lineWidth * 2 - _arrowHeight, 10, 10);
    g.moveTo(_arrowStart, _height - lineWidth - _arrowHeight);
    g.lineTo(_arrowStart, _height);
    g.lineTo(_arrowStart + _arrowWidth, _height - lineWidth - _arrowHeight);
    g.endFill();
    g.lineStyle(1, 0xFFFFFF);
    g.moveTo(_arrowStart, _height - lineWidth - _arrowHeight);
    g.lineTo(_arrowStart + _arrowWidth, _height - lineWidth - _arrowHeight);
}
When setting the text in the tooltip, the methods invalidateSize and invalidateDisplayList are needed to be called to recalculate the width and the height of the tooltip by the program.
public function setText(message:String):void {
            _message.htmlText = "<font color='#000000'>" + message + "</font>";
            this.invalidateSize();
            this.invalidateDisplayList();
        }
When Tooltip has been customized, it is necessary to bind up the element and the content in the customized tooltip.
link.setClient('message', '3333M');
customTooltip.setText(element.getClient('message'));

No comments:

Post a Comment