I want to create a custom check box which toggles between label and image

799 Views Asked by At

I want to create a custom reusable component by extending a spark Button class so that it has a checkbox and a label which says Show Image. When checkbox is selected an image will be displayed instead of the label. The Image path should be exposed as an API. How can we extend spark.components.Button to have it check box with labe or image (image path should be dynamic).

I tried to extend Button class as below but not sure how to create check box in it and how to pass image path as parameter to that.

package myClasses
{
    import spark.components.Button;

    public class ImageCheckBox extends Button
    {
        public function ImageButton()
        {
            super();
            this.buttonMode = true;
        }
    }
}

I want to use the custom components something like below in application.

<myClasses:ImageCheckBox skinClass="mySkins.HelpButtonSkin" path="...."" label="Show Image" />
1

There are 1 best solutions below

1
Anton On

Something like this

package myClasses {
import flash.events.Event;

import spark.components.CheckBox;
import spark.components.Image;
import spark.components.Label;
import spark.components.supportClasses.SkinnableComponent;

public class ImageCheckBox extends SkinnableComponent {
    [SkinPart(required=true)]
    public var checkBox:CheckBox;

    [SkinPart(required=true)]
    public var labelComp:Label;

    [SkinPart(required=true)]
    public var image:Image;

    private var pathChanged:Boolean = false;
    private var _path:String;
    public function get path():String {
        return _path;
    }

    public function set path(value:String):void {
        if (_path != value) {
            _path = value;
            pathChanged = true;
            invalidateProperties();
        }
    }

    private var labelChanged:Boolean = false;
    private var _label:String;
    public function get label():String {
        return _label;
    }

    public function set label(value:String):void {
        if (_label != value) {
            _label = value;
            labelChanged = true;
            invalidateProperties();
        }
    }

    public function ImageCheckBox() {
        super();
        setStyle("skinClass", ImageCheckBoxSkin);
    }

    override protected function partAdded(partName:String, instance:Object):void {
        super.partAdded(partName, instance);

        if (instance == checkBox) {
            checkBox.addEventListener(Event.CHANGE, checkBoxChangeHandler)
        }
        else if (instance == labelComp) {
            labelComp.text = label;
        }
        else if (instance == image) {
            image.source = path;
        }
    }

    override protected function partRemoved(partName:String, instance:Object):void {
        super.partRemoved(partName, instance);

        if (instance == checkBox) {
            checkBox.removeEventListener(Event.CHANGE, checkBoxChangeHandler)
        }
    }

    override protected function getCurrentSkinState():String {
        return checkBox.selected ? "selected" : super.getCurrentSkinState();
    }

    override protected function commitProperties():void {
        if (labelChanged) {
            labelChanged = false;
            labelComp.text = label;
        }

        if (pathChanged) {
            pathChanged = false;
            image.source = path;
        }

        super.commitProperties();
    }

    private function checkBoxChangeHandler(event:Event):void {
        invalidateSkinState();
    }
}}

And skin

<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx">

<!-- host component -->
<fx:Metadata>
    <![CDATA[
    /**
     * @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    [HostComponent("myClasses.ImageCheckBox")]
    ]]>
</fx:Metadata>

<s:states>
    <s:State name="normal"/>
    <s:State name="selected"/>
</s:states>

<s:HGroup width="100%" height="100%" gap="3">
    <s:CheckBox id="checkBox"
                verticalCenter="0"
                height="100%"/>
    <s:Label id="labelComp"
             verticalCenter="0" verticalAlign="middle"
             width="100%" height="100%"
             visible.normal="true" includeInLayout.normal="true"
             visible.selected="false" includeInLayout.selected="false"/>
    <s:Image id="image"
             verticalCenter="0"
             width="100%" height="100%"
             fillMode="scale" scaleMode="letterbox"
             visible.normal="false" includeInLayout.normal="false"
             visible.selected="true" includeInLayout.selected="true"/>
</s:HGroup>