Menu

Mobile Text Components

SourceForge Editorial Staff

Mobile Text Components - Functional and Design Specification


Glossary

FTE - Flash Text Engine. A new text rendering engine added to Flash Player 10.
TLF - Text Layout Framework. A high-level text engine written on top of FTE.
TextField - The legacy text type in the Flash Player.
CFF - Compact Font Format. Embedded font format that can only be rendered by FTE and TLF.

Summary and Background

Goals:

  • Support the "common" Flex text components: Label, TextInput, and TextArea (single style only)
  • Provide highest possible text performance for critical areas like skins and item renderers
  • Support native predictive text input and editing (to the extent that AIR supports it)

Non-goals:

  • Multi-styled TextArea
  • Bi-di or mirroring support
  • Changes to FXG text import (will continue to use TLF, and be discouraged for mobile use)

Feature Summary

Primarily for performance reasons and support for native predictive text input and editing, mobile will use TextField-based text in all critical areas. This is expected to be a short-term solution until a performant version of FTE arrives on mobile. With this in mind, this feature is designed to be hidden from Flex developers for most of the common use cases. The only time you need to know the details is if you are creating a mobile-optimized skin or item renderer.

This feature includes:

  • A new StyleableTextField primitive. This extends TextField, adds support for styles, and implements the IDisplayText and IEditableText interfaces (see next bullet point). This class does not implement IUIComponent or ILayoutElement, so it cannot be used as a child in a container. It is designed to be used in ActionScript skins and item renderers only.
  • New IDisplayText and IEditableText interfaces. These define the contract for simple text display and editable text. Text skin parts in Spark components are updated to use these interfaces instead of the TextBase and RichEditableText types currently used. TextBase implements IDisplayText and RichEditableText implements IEditableText (which extends IDisplayText).
  • New mobile skins for TextInput and TextArea components. These skins utilize the new StyleableTextField primitive.

The existing Label component is unchanged. It is a non-skinned component based on FTE, so the performance is not as good as StyleableTextField, but is significantly better than TLF-based solutions. Since all performance-critical areas will be using StyleableTextField (skins and item renderers), the performance impact of Label should be minimal.

Usage Scenarios

Mark, an experienced Flex developer, is creating his first Flex Mobile application. He opens up design view and sees the familiar text components: Label, TextInput, and TextArea. Mark is able to quickly assemble the UI for his application, and is blissfully unaware of the underlying text primitives used by the skins.

Nigel is creating custom mobile skins and item renderers for his application. He uses the default skins as a starting point, and notices they are using a new StyleableTextField primitive. He looks at the documentation for StyleableTextField, sees that it is for use in optimized AS skins and item renderers, and decides to use it for his skins and item renderers.

Detailed Description

Performance considerations

There are three primary areas of performance consideration for mobile text:

  • Creation and display of many small labels. Testing included creation and display of 64 labels. In this test, FTE was slightly faster than TextField.
  • Creation and display of a few input controls. TLF-based text adds one second to startup time (on a droid) relative to TextField.
  • Resetting text of a static label (list item renderer recycling). Restting TextField text is at least 3 times faster than resetting FTE text.

StyleableTextField class

The StyleableTextField class is a lightweight subclass of the Flash TextField class. It implements the IDisplayText and IEditableText interfaces (see below), and supports minimal styling through CSS.

This class does not implement IUIComponent or IVisualElement, so it cannot be used in MXML markup. It is designed exclusively for use in ActionScript skins and item renderers only.

Styling is done by setting the styleProvider property and calling the styleChanged() method. See the "Examples and Usage" section for details on usage.

IDisplayText and IEditableText interfaces

The IDisplayText interface is used for display of static text. The IEditableText interface extends IDisplayText and adds support for text editing.

StyleableTextField implements IEditableText (and IDisplayText by extension). TextBase implements IDisplayText, and RichEditableText implements IEditableText.

See the API Description section for details on these interfaces.

Text skin parts

The text skin parts for all Spark components are changed to IDisplayText and IEditableText. Text skin parts extend InteractiveObject, so it is safe to cast the parts to InteractiveObject when needed.

IEditableText does not support TLF markup, so TextArea needs to check the type of the skin part before accessing TLF-specific functionality.

Here is a chart listing the Spark components that have text skin parts:

Component
Skin Part
Old Type
New Type
Notes

ButtonBase
labelDisplay
TextBase
IDisplayText
Base class for Button, RadioButton, CheckBox, etc.

SkinnableTextBase
textDisplay
RichEditableText
IEditableText
Base class for TextInput and TextArea

FormHeading
labelDisplay
TextBase
IDisplayText

FormItem
labelDisplay, sequenceLabelDisplay, errorTextDisplay
TextBase
IDisplayText

Panel
titleDisplay
TextBase
IDisplayText

VideoPlayer
currentTimeDisplay, durationDisplay
TextBase
IDisplayText

Unsupported TextArea properties and methods

The following TextArea properties and methods are not supported in mobile:

Name
Type
Notes

content
property
TLF markup is not supported

heightInLines
property

textFlow
property

widthInChars
property

selectionHighlighting
property
Always uses WHEN_FOCUSED

getFormatOfRange()
method

setFormatOfRange()
method

Text styles supported by StyleableTextField

The following text styles are supported by StyleableTextField. These are the only text styles that will function on TextInput and TextArea for mobile.

  • textAlign
  • fontFamily
  • fontWeight
  • color
  • fontSize
  • textDecoration
  • textIndent
  • leading
  • letterSpacing

Keyboard and Focus

TextInput (and editable TextArea) support on-screen keyboards and predictive text entry to the extent these are supported by AIR. AIR ensures the editable text is never obscured by the on-screen keyboard, and will scroll the screen contents vertically if needed.

The standard focus ring is drawn around editable text components. Support for 5-way/trackball navigation is planned for post-beta, and details will be in a separate spec.

Touch interaction

Touch+drag gestures always select text (when text is selectable or editable). If the text is inside a Scroller, the Scroller will only scroll if the gesture is outside the text component.

API Description

IDisplayText

package spark.core
{
    /**
     *  The IDisplayText interface defines the properties and methods
     *  for simple text display.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.1
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */
    public interface IDisplayText
    {
        /**
         *  The text displayed by this text component.
         *
         *  <p>The formatting of this text is controlled by CSS styles.
         *  The supported styles depend on the subclass.</p>
         *
         *  @default ""
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get text():String;
        function set text(value:String):void;


        /**
         *  A flag that indicates whether the text has been truncated.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get isTruncated():Boolean;
    }
}

IEditableText

package spark.core
{
    /**
     *  The IEditableText interface defines the properties and methods
     *  for editable text.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.1
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */
    public interface IEditableText extends IDisplayText
    {
        /**
         *  @copy flash.text.TextField#displayAsPassword
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get displayAsPassword():Boolean;
        function set displayAsPassword(value:Boolean):void;

        /**
         *  Flag that indicates whether the text is editable.
         *
         *  @default false
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get editable():Boolean;
        function set editable(value:Boolean):void;

        /**
         *  @copy flash.text.TextField#maxChars
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get maxChars():int;
        function set maxChars(value:int):void;

        /**
         *  @copy flash.text.TextField#restrict
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get restrict():String;
        function set restrict(value:String):void;

        /**
         *  @copy flash.text.TextField#selectable
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get selectable():Boolean;
        function set selectable(value:Boolean):void;

        /**
         *  @copy flash.display.DisplayObject#accessibilityProperties
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get accessibilityProperties():AccessibilityProperties;
        function set accessibilityProperties(value:AccessibilityProperties):void;

        /**
         *  @copy flash.display.InteractiveObject#tabIndex
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get tabIndex():int;
        function set tabIndex(value:int):void;

        /**
         *  @copy mx.core.UIComponent#focusEnabled
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get focusEnabled():Boolean;
        function set focusEnabled(value:Boolean):void;

        /**
         *  @copy flash.text.TextField#multiline
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get multiline():Boolean;
        function set multiline(value:Boolean):void;

        /**
         *  @copy mx.core.UIComponent#enabled
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function get enabled():Boolean;
        function set enabled(value:Boolean):void;

        /**
         *  Scroll so the specified range is in view.
         *
         *  @param anchorPosition The anchor position of the selection range.
         *  @param activePosition The active position of the selection range.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function scrollToRange(anchorPosition:int, activePosition:int):void;

        /**
         *  Inserts the specified text into the text component
         *  as if you had typed it.
         *
         *  <p>If a range was selected, the new text replaces the selected text.
         *  If there was an insertion point, the new text is inserted there.</p>
         *
         *  <p>An insertion point is then set after the new text.
         *  If necessary, the text will scroll to ensure
         *  that the insertion point is visible.</p>
         *
         *  @param text The text to be inserted.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function insertText(text:String):void;

        /**
         *  Appends the specified text to the end of the text component,
         *  as if you had clicked at the end and typed.
         *
         *  <p>An insertion point is then set after the new text.
         *  If necessary, the text will scroll to ensure
         *  that the insertion point is visible.</p>
         *
         *  @param text The text to be appended.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function appendText(text:String):void;

        /**
         *  Selects a specified range of characters.
         *
         *  <p>If either position is negative, it will deselect the text range.</p>
         *
         *  @param anchorPosition The character position specifying the end
         *  of the selection that stays fixed when the selection is extended.
         *
         *  @param activePosition The character position specifying the end
         *  of the selection that moves when the selection is extended.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function selectRange(anchorIndex:int, activeIndex:int):void;

        /**
         *  Selects all of the text.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        function selectAll():void;
    }
}

StyleableTextField

package spark.components.supportClasses
{
    /**
     *  The StyleableTextField class is a text primitive for use in ActionScript
     *  skins and item renderers. It cannot be used in MXML markup.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.1
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */
    public class StyleableTextField extends TextField implements IEditableText
    {
        //////////////////////////////////////////////////////
        //  IDisplayText properties and methods
        //////////////////////////////////////////////////////

        //////////////////////////////////////////////////////
        //  IEditableText properties and methods
        //////////////////////////////////////////////////////

        //////////////////////////////////////////////////////
        //  Properties
        //////////////////////////////////////////////////////

        /**
         *  The object that provides styles for this text component. This
         *  property must be set for the text to pick up the correct styles.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        public var styleProvider:IStyleClient;

        //////////////////////////////////////////////////////
        //  Methods
        //////////////////////////////////////////////////////

        /**
         *  Commit the styles into the TextField. This method must be called
         *  before the text is displayed, and any time the styles have changed.
         *  This method does nothing if the styles have already been committed.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        public function commitStyles():void

        /**
         *  Notify the text field that a style is changed. This method is typically
         *  called by the styleChanged() method of the style provider.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.1
         *  @playerversion AIR 2.0
         *  @productversion Flex 4.5
         */
        public function styleChanged(styleProp:String):void

        /**
         *  Truncate text to make it fit horizontally in the area defined for the control,
         *  and append an ellipsis, three periods (...), to the text.
         *
         *  @param truncationIndicator The text to be appended after truncation.
         *  If you pass <code>null</code>, a localizable string
         *  such as <code>"..."</code> will be used.
         *
         *  @return <code>true</code> if the text needed truncation.
         *
         *  @langversion 3.0
         *  @playerversion Flash 9
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
         */
        public function truncateToFit(truncationIndicator:String = "..."):Boolean
    }
}

Examples and Usage

This example shows how to incorporate StyleableTextField into a Button skin:

...

public var labelDisplay:StyleableTextField;

...

override protected function createChildren():void
{
    ...

    // Create the StyleableTextField
    textDisplay = new StyleableTextField(createInFontContext(StyleableTextField));

    // Set the styleProvider of the text field. The text field will be picking up
    // styles from this skin.
    textDisplay.styleProvider = this;

    // For editable text...
    textDisplay.editable = true|false;

    // For selectable text...
    textDisplay.selectable = true|false;

    // For multiline text...
    textDisplay.multiline = true|false;

    // For word-wrapped text...
    textDisplay.wordWrap = true|false;

    addChild(textDisplay);

    ...
}

override protected function measure():void
{
    ...

    // Use the UIComponent.measureText() function for measuring

    var lineMetrics:TextLineMetrics = measureText(textDisplay.text);

    ...
}

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
    ...

    // Commit the styles in the text field
    textDisplay.commitStyles();
    textDisplay.width = textWidth;
    textDisplay.height = textHeight;
    textDisplay.x = textX;
    textDisplay.y = textY;

    // Truncate the text
    textDisplay.truncateToFit();

    ....
}

override public function styleChanged(styleProp:String):void
{
    ...

    textDisplay.styleChanged(styleProp);

    ...
}

Compiler Work

None.

Backwards Compatibility

None.

Syntax changes

None.

Behavior

The mobile skin for TextArea doesn't support TLF-formatted text.

Warnings/Deprecation

None.

Accessibility

None.

Performance

See overview and detailed description sections.

Globalization

The first release of mobile will not support bidi or mirroring. This will come in a future release.

Localization

Compiler Features

None.

Framework Features

Possibly an RTE when accessing TLF-specific properties on TextArea.

Cross-Platform Considerations

None.

Issues and Recommendations

|| Description || Resolution || Status || | Embedded Font Support - Label uses CFF fonts, StyleableTextField (which is used for all skins and item renderers) uses the older style embedded fonts. There are two options for font embedding: 1). Embed two versions of the font (cff and non-cff). 2). Use TextArea (non-editable, without border) instead of Label. | We will embed non-cff fonts by default, and recommend using TextArea instead of Label when embedding fonts. | Closed | | How to disable mutli-style support in TextArea. ASDoc will mention unsupported properties. Should we throw an RTE, or just silently fail? | Unsupported properties and methods will be clearly noted in ASDoc. The compiler can't provide compiler errors or warnings since the functionality is determined by the skin, not the component. At runtime we will silently fail when accessing unsupported properties or methods. | Closed | | How do we reconcile gesture support for scrolling vs. selection/editing? | Initially the touch+drag gesture will always select text (and cancel any pending scrolling on an outer Scroller). We will evaluate this behavior post-beta and make adjustments as needed. | Closed |
\


Related

Wiki: Flex 4.5

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.