Adding images with TLF

TLF supports embedding images in text controls by using the InlineGraphicElement class. To add an image to the text object model, use the <img> tag in a <s:textFlow> tag or the default property, or create an instance of the InlineGraphicElement class.

The InlineGraphicElement class can point to an image file, such as a GIF, JPG, or PNG file.

You specify the location of the image by using the source property. The location can be relative to the deployed location of the application (for example, “images/butterfly.gif”) or it can be a full path to the image (for example, “http://yourserver.com/images/butterfly.gif”).

The following example loads a simple image from a local location:
<?xml version="1.0"?>
<!-- sparktextcontrols/SimpleInlineGraphic.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="doSomething()">

    <fx:Script>
        <![CDATA[
            import flashx.textLayout.elements.*;
            import flashx.textLayout.*;
            
            [Bindable]
            private var textFlow:TextFlow;

            private var img:InlineGraphicElement;
            
            private function doSomething():void {
                textFlow = new TextFlow();

                var p:ParagraphElement = new ParagraphElement();
                img = new InlineGraphicElement();
                img.source = "assets/butterfly.gif";
                img.height = 100;
                img.width = 100;
                p.addChild(img);
                textFlow.addChild(p);
            }
            ]]>
    </fx:Script>

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <s:Panel title="Simple Inline Graphic Image"
        width="90%" height="90%"
        horizontalCenter="0" verticalCenter="0">

        <s:RichEditableText id="richTxt" textAlign="justify" width="100%"
            textFlow="{textFlow}" />

    </s:Panel>

</s:Application>

The executing SWF file for the previous example is shown below:

As with text-based examples, you can use a variety of techniques to load the image with an InlineGraphicElement object. The following example uses child tags:
<?xml version="1.0"?>
<!-- sparktextcontrols/SimpleInlineGraphicTags.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <s:Panel title="Simple Inline Graphic Image"
        width="90%" height="90%"
        horizontalCenter="0" verticalCenter="0">

        <s:RichEditableText id="richTxt" textAlign="justify" width="100%">
            <s:textFlow>
                <s:TextFlow>
                    <s:p>
                        <s:img source="@Embed(source='../assets/butterfly.gif')" height="100" width="100"/>
                    </s:p>
                </s:TextFlow>
            </s:textFlow>
        </s:RichEditableText>
    </s:Panel>

</s:Application>

The executing SWF file for the previous example is shown below:

Rather than load the image at run time, you can also use an embedded image for the InlineGraphicImage object’s source, as the following example shows:
<?xml version="1.0"?>
<!-- sparktextcontrols/SimpleEmbed.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <fx:Script>
        [Embed(source="../assets/butterfly.gif")]
        [Bindable]
        public var imgCls:Class;
    </fx:Script>

        <s:RichEditableText id="richTxt" textAlign="justify" width="100%">
            <s:textFlow>
                <s:TextFlow>
                    <s:p>
                        <s:img id="myImage" source="{imgCls}" height="100" width="100"/>
                    </s:p>
                </s:TextFlow>
            </s:textFlow>
        </s:RichEditableText>
        
</s:Application>

The executing SWF file for the previous example is shown below:

The InlineGraphicElement class can also display a drawn element, such as a Sprite or an FXG component. The following example loads an FXG component into the InlineGraphicElement:
<?xml version="1.0"?>
<!-- sparktextcontrols/FXGInlineGraphic.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:comps="comps.*"
    creationComplete="doSomething()">

    <fx:Script>
        <![CDATA[
            import flashx.textLayout.elements.*;
            import flashx.textLayout.*;
            import comps.*;
            
            [Bindable]
            private var textFlow:TextFlow;

            private var img:InlineGraphicElement;
            
            private function doSomething():void {
                textFlow = new TextFlow();

                var p:ParagraphElement = new ParagraphElement();
                img = new InlineGraphicElement();
                img.source = new ArrowAbsolute();
                img.height = 100;
                img.width = 100;
                p.addChild(img);
                textFlow.addChild(p);
            }
            ]]>
    </fx:Script>

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <s:Panel title="FXG Inline Graphic Image"
        width="90%" height="90%"
        horizontalCenter="0" verticalCenter="0">
        <s:RichEditableText id="richTxt" textAlign="justify" width="100%"
            textFlow="{textFlow}" />
    </s:Panel>
</s:Application>

The executing SWF file for the previous example is shown below:

The FXG component used in this example is as follows:
<?xml version="1.0" encoding="utf-8"?>
<!-- textcontrols/comps/ArrowAbsolute.fxg -->
<fxg:Graphic xmlns:fxg="http://ns.adobe.com/fxg/2008" version="1">    
    <!-- Use Use compact syntax with absolute coordinates. -->
    <fxg:Path data="
         M 20 0 
         C 50 0 50 35 20 35
         L 15 35 
         L 15 45 
         L 0 32 
         L 15 19 
         L 15 29 
         L 20 29 
         C 44 29 44 6 20 6
    ">
         <!-- Define the border color of the arrow. -->
         <fxg:stroke>
              <fxg:SolidColorStroke color="#888888"/>
         </fxg:stroke>
         <!-- Define the fill for the arrow. -->
         <fxg:fill>
              <fxg:LinearGradient rotation="90">
                   <fxg:GradientEntry color="#000000" alpha="0.8"/>
                   <fxg:GradientEntry color="#FFFFFF" alpha="0.8"/>
              </fxg:LinearGradient>
         </fxg:fill>
    </fxg:Path>
</fxg:Graphic>

For more information about using FXG, see FXG and MXML graphics.

If you do not know the image’s dimensions, you can use the InlineGraphicElement class’s measuredHeight and measuredWidth properties to define the size of the image. You can only use these properties after the image loads. To do this, you can trigger a function that sizes the image off of the TextFlow object’s StatusChangeEvent event, as the following example shows:
<?xml version="1.0"?>
<!-- sparktextcontrols/LoadImageEvent.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()">

    <fx:Script>
        <![CDATA[
            import flashx.textLayout.events.StatusChangeEvent;
            import flashx.textLayout.elements.*;
            import flashx.textLayout.*;
            
            [Bindable]
            private var textFlow:TextFlow;

            private var img:InlineGraphicElement;
            
            private function initApp():void {
                textFlow = new TextFlow();
                textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, sizeGraphic);

                var p:ParagraphElement = new ParagraphElement();
                img = new InlineGraphicElement();
                img.source = "assets/butterfly.gif";                
                p.addChild(img);
                textFlow.addChild(p);
            }        

            private function sizeGraphic(e:StatusChangeEvent):void {
                if (e.status == "ready" || e.status == "sizePending") {
                    img.height = img.measuredHeight;
                    img.width = img.measuredWidth;
                }
            }
            ]]>
    </fx:Script>

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <s:Panel title="Sizing Inline Graphic Image"
        width="90%" height="90%"
        horizontalCenter="0" verticalCenter="0">

        <s:RichEditableText id="richTxt" textAlign="justify" width="100%"
            textFlow="{textFlow}" />

    </s:Panel>

</s:Application>

The executing SWF file for the previous example is shown below:

You can get a reference to the InlineGraphicElement’s graphic by using the graphic property. This property points to the embedded DisplayObject. This lets you interact with the InlineGraphicElement in the same ways that you can interact with any DisplayObject. For example, you can apply blend modes, change the alpha, rotate, and scale the image.

The following example changes the alpha of the DisplayObject when you move the slider:
<?xml version="1.0"?>
<!-- sparktextcontrols/DisplayObjectImageElement.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>

    <fx:Script>
        private function changeAlpha():void {
            myImage.graphic.alpha = .5;
        }
    </fx:Script>

        <s:RichEditableText id="richTxt" textAlign="justify" width="100%">
            <s:textFlow>
                <s:TextFlow>
                    <s:p>
                        <s:img id="myImage" 
                            source="@Embed(source='../assets/butterfly.gif')" 
                            height="100" width="100"/>
                    </s:p>
                </s:TextFlow>
            </s:textFlow>
        </s:RichEditableText>
        
        <s:HSlider id="hSlider" 
            minimum="0" maximum="1" 
            value="1" 
            stepSize="0.1"
            snapInterval="0.1" 
            liveDragging="true" 
            valueCommit="myImage.graphic.alpha=hSlider.value;"/>
            
</s:Application>

The executing SWF file for the previous example is shown below:

Note that the previous example uses a RichEditableText control and not a RichText control. The RichEditableText control supports user interaction, while the RichText control does not.