actionscript-3apache-flexflex4.5flex-mobilespark-skinning

Flex mobile Button skinning in ActionScript - multiline labelDisplay


I am working on a Flex mobile application, and have been optimizing its performance on mobile. I have read that skins must be written in ActionScript so I have tried to create my AS ButtonSkin.

public class mButtonSkin extends ButtonSkin
{
    private static var colorMatrix:Matrix = new Matrix();

    protected var radiusX:Number = 12;
    protected var mAngle:Number = 30;
    protected var labelWidth:Number;
    protected var labelHeight:Number;
    protected var paddingLeft:Number = 12;
    protected var paddingRight:Number = 12;
    protected var paddingTop:Number = 2;
    protected var paddingBottom:Number = 2;



    public function mButtonSkin() {
        super();
    }


    override protected function drawBackground(unscaledWidth:Number,unscaledHeight:Number) : void {
        colorMatrix.createGradientBox(width,height,mAngle);
        if (currentState == "up") {
            graphics.beginGradientFill(GradientType.LINEAR, 
                [hostComponent.getStyle("fill3"),hostComponent.getStyle("fill1")], [1,1], [0,255], colorMatrix);
        } else {
            graphics.beginFill(hostComponent.getStyle("fill4"));
        }

        graphics.lineStyle(0.5,hostComponent.getStyle("borderColor"),0.5);
        graphics.drawRoundRect(0,0,hostComponent.width,hostComponent.height,12);
        graphics.endFill();
    }


    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number) : void {
        labelDisplay.wordWrap = true;
        labelDisplay.multiline = true;

        labelDisplay.commitStyles();

        labelWidth = width - paddingLeft - paddingRight;
        labelHeight = height - paddingTop - paddingBottom;

        var x:Number = width / 2 - labelWidth / 2;
        var y:Number = height / 2 - getElementPreferredHeight(labelDisplay) / 2;

        setElementSize(labelDisplay,labelWidth,labelHeight);
        setElementPosition(labelDisplay,x,y);
    }


    override protected function labelDisplay_valueCommitHandler(event:FlexEvent) : void {
        labelDisplayShadow.text = "";
    }
}

Applying this skin in my buttons:

enter image description here

Button labelDisplay has wrong alignment (verticalAlignment must be middle).

After clicking the button:

enter image description here

My button's labelDisplay is now vertically-aligned to middle.

Did i miss something? What have I done wrong?


Solution

  • on the layoutContents function, before positioning the labelDisplay element, i checked first whether it's numLines property is greater than 1. here's my updated function:

        override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number) : void {
            labelDisplay.wordWrap = true;
            labelDisplay.multiline = true;
    
            labelWidth = width - paddingLeft - paddingRight;
            labelHeight = height - paddingTop - paddingBottom;
    
            var x:Number = width * .5 - labelWidth * .5;
            var y:Number = height * .5 - getElementPreferredHeight(labelDisplay) * .5;
    
            setElementSize(labelDisplay,labelWidth,labelHeight);
    
            if (labelDisplay.numLines == 1)
                setElementPosition(labelDisplay,x,y);
            else
                setElementPosition(labelDisplay, x, labelDisplay.getLayoutBoundsY());
        }
    

    this solution may not be useful to other devs out there but it solved my problem.