blob: 01f68fdc8fa6de643491ce0b49e4f6a2484ce88d [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta name="DC.Type" content="topic"/>
<meta name="DC.Title" content="Mirroring and bidirectional text"/>
<meta name="DC.Format" content="XHTML"/>
<meta name="DC.Identifier" content="WS022ac6da934778d01dbcea6412e9c9fa58e-8000_verapache"/>
<title>Mirroring and bidirectional text</title>
</head>
<body id="WS022ac6da934778d01dbcea6412e9c9fa58e-8000_verapache"><a name="WS022ac6da934778d01dbcea6412e9c9fa58e-8000_verapache"><!-- --></a>
<div class="nested1" id="WS19f279b149e7481c-22a007f412ea0cce8b3-8000_verapache"><a name="WS19f279b149e7481c-22a007f412ea0cce8b3-8000_verapache"><!-- --></a>
<h2 class="topictitle2">Introduction to mirroring and bidirectional
text</h2>
<div>
<div class="p">here are two primary ways to control the appearance of
an application that supports both left-to-right (LTR) and right-to-left
(RTL) languages:<ul>
<li>
<p>Layout mirroring — Layout mirroring is
the process of flipping the appearance of the layout controls. For
example, in an RTL application, vertical scroll bars should appear
on the left instead of the right. For horizontal scrollbars, the thumb
should appear on the right side of the control instead of the left.
Layout mirroring is commonly used to make a UI match the direction
of an RTL language.</p>
</li>
<li>
<p>Text direction — Text direction defines the direction that
text flows in the text controls. For RTL languages such as Hebrew
and Arabic, the characters should render from the right side to
the left. This also includes bidirectional text support, where a
control might need to render some of the text RTL, and some of the
text LTR in the same control. The Spark Flex text controls handle
directionality of the text internally. They do not use mirroring
to render text.</p>
</li>
</ul>
To change an application's layout from
LTR to RTL, set the <samp class="codeph">layoutDirection</samp> property of
the application object to "rtl". The direction of text is automatically set
based on the characters used, but you should also set the <samp class="codeph">direction</samp> style property
to "rtl" if the majority of your text is RTL. This property instructs
the text control to apply RTL rules to the text.</div>
<div class="p">The following example lets you change the <samp class="codeph">layoutDirection</samp> and <samp class="codeph">direction</samp> style
properties on the application from "ltr" to "rtl":<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring/DynamicMirroring.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
height="400" width="400"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import mx.core.LayoutDirection;
private function setDirectionProps():void {
panel1.setStyle('direction', ddl1.selectedItem);
panel1.setStyle('layoutDirection', ddl1.selectedItem);
}
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel id="panel1" title="Panel With Non-Mirrored Content" width="350"
layoutDirection="{LayoutDirection.LTR}"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="This panel contains content that is not mirrored."/&gt;
&lt;s:Button label="This Button is not mirrored in the container"/&gt;
&lt;s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setDirectionProps()"&gt;
&lt;s:ArrayList source="['ltr','rtl']"/&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Panel&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>Mirroring is not supported when you set the <samp class="codeph">compatibility-version</samp> compiler
option to 3.0.0 or when the theme is Halo or Mobile. Mirroring is
only supported by the Wireframe and Spark themes.</p>
</div>
<div><div class="relinfo"><strong>Related information</strong><br/>
<div><a href="https://www.w3.org/International/tutorials/bidi-xhtml/" target="_blank">W3C site on RTL/Internationalization</a></div>
<div><a href="https://unicode.org/reports/tr9/" target="_blank">Description of the Unicode bidirectional algorithm</a></div>
<div><a href="https://www.google.com/transliterate" target="_blank">Google transliteration</a></div>
<div><a href="flx_l10n_ln.html#WS19f279b149e7481c-1c03f02c12bd00c4763-8000_verapache">Localization</a></div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c-22a007f412ea0cce8b3-7fff_verapache"><a name="WS19f279b149e7481c-22a007f412ea0cce8b3-7fff_verapache"><!-- --></a>
<h3 class="topictitle3">Layout mirroring</h3>
<div>
<p>
<em>Layout mirroring</em> refers to how containers and controls
are drawn on the screen. The default direction is LTR. You can change
any container or control that implements the ILayoutDirectionElement
interface to lay out from right to left by setting the <samp class="codeph">layoutDirection</samp> property
to "rtl". This interface includes all controls that implement the
IVisualElement interface as well as some assets that do not implement
this interface.</p>
<div class="p">The recommended method of using <samp class="codeph">layoutDirection</samp> is
to set it on the Application container so that all child containers
and controls in the application inherit its value. You can set the <samp class="codeph">layoutDirection</samp> property
in one of the following ways:<ul>
<li>
<div class="p">In MXML. For example:<pre class="codeblock">&lt;s:Panel id="myPanel" layoutDirection="rtl"&gt;</pre>
</div>
</li>
<li>
<div class="p">With the <samp class="codeph">setStyle()</samp> method. For example:<pre class="codeblock">myPanel.setStyle("layoutDirection","rtl");</pre>
</div>
</li>
</ul>
The
following example shows two Panel containers. One sets the <samp class="codeph">layoutDirection</samp> property
to "rtl" and the other to "ltr":<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring/SimpleLayoutMirroring.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
height="400" width="400"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import mx.core.LayoutDirection;
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Panel With Non-Mirrored Content" width="350"
layoutDirection="{LayoutDirection.LTR}"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="This panel contains content that is not mirrored."/&gt;
&lt;s:Button label="This Button is not mirrored in the container"/&gt;
&lt;s:DropDownList requireSelection="true" selectedIndex="0"&gt;
&lt;s:ArrayList source="['Drop','Down','List']" /&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Panel&gt;
&lt;s:Panel title="Panel With Mirrored Content" width="350"
layoutDirection="{LayoutDirection.RTL}"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="This panel contains content that is mirrored."/&gt;
&lt;s:Button label="This Button is mirrored inside the container"/&gt;
&lt;s:DropDownList requireSelection="true" selectedIndex="0"&gt;
&lt;s:ArrayList source="['Drop','Down','List']" /&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Panel&gt;
&lt;/s:Application&gt;</pre>
</div>
<div class="p">Instead of using the strings "ltr" or "rtl", the <samp class="codeph">layoutDirection</samp> style
property can also take the following constants:<ul>
<li>
<p>
<samp class="codeph">mx.core.LayoutDirection.LTR</samp>
</p>
</li>
<li>
<p>
<samp class="codeph">mx.core.LayoutDirection.RTL</samp>
</p>
</li>
</ul>
</div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c49026d1312ea0d08723-8000_verapache"><a name="WS19f279b149e7481c49026d1312ea0d08723-8000_verapache"><!-- --></a>
<h3 class="topictitle3">Text direction</h3>
<div>
<p>
<em>Text direction</em> refers to the direction that characters
are rendered in text-based controls. Some languages, such as Hebrew
and Arabic, are read from right to left. Most text-based controls
auto-detect the direction of the text based on the character codes
of the text content, but specifying the direction ensures that the punctuation
follows the appropriate (RTL or LTR) rules. </p>
<p>As with the <samp class="codeph">layoutDirection</samp> property, you typically
set the <samp class="codeph">direction</samp> property on the application or
the parent container of the text-based control.</p>
<div class="p">You can set the <samp class="codeph">direction</samp> property in one of
the following ways:<ul>
<li>
<div class="p">In MXML. For example:<pre class="codeblock">&lt;s:Panel id="myPanel" direction="rtl"&gt;</pre>
</div>
</li>
<li>
<div class="p">With the <samp class="codeph">setStyle()</samp> method. For example:<pre class="codeblock">myPanel.setStyle("direction","rtl");</pre>
</div>
</li>
</ul>
The
following example shows two Panel containers. One sets the <samp class="codeph">direction</samp> property
to RTL and the other to LTR:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring/SimpleTextMirroring.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
height="400" width="400"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import mx.core.LayoutDirection;
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Panel With Non-Mirrored Content" width="350"
direction="ltr"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="This panel contains content that is not mirrored."/&gt;
&lt;s:Button label="This Button is not mirrored in the container."/&gt;
&lt;s:DropDownList requireSelection="true" selectedIndex="0"&gt;
&lt;s:ArrayList source="['Drop','Down','List']" /&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Panel&gt;
&lt;s:Panel title="Panel With Mirrored Content" width="350"
direction="rtl"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="This panel contains content that is mirrored."/&gt;
&lt;s:Button label="This Button is mirrored inside the container."/&gt;
&lt;s:DropDownList requireSelection="true" selectedIndex="0"&gt;
&lt;s:ArrayList source="['Drop','Down','List']" /&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Panel&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>The <samp class="codeph">direction</samp> style property only affects punctuation
in this example. The characters themselves are not rendered from
right to left because they use an LTR-based character set.</p>
<p>Support for setting the direction on text controls is built into
text controls in the Spark component set because those text controls
are based on FTE (Flash Text Engine). Text-based controls that are
based on the TextField control do not support mirroring or bidirectional
text. To use FTE with MX text-based controls, you must adjust your
compiler settings. For more information, see <a href="flx_mirroring_mr.html#WS19f279b149e7481c4c6270d212ea104536c-7fff_verapache">Mirroring
with text controls</a>.</p>
<p>
<em>Bidirectional text</em> refers to text that contains both RTL
and LTR content. For example, if you write a sentence in an RTL
language such as Hebrew, but include the name of a company, such
as Apache. The compiler recognizes characters codes that use RTL
and LTR and renders the text appropriately. </p>
<div class="p">The following example shows bidirectional text:<pre class="codeblock">&lt;?xml version="1.0"?&gt;
&lt;!-- mirroring/BiDiText.mxml --&gt;
&lt;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="addText()"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import flashx.textLayout.formats.*;
import spark.utils.TextFlowUtil;
private function addText():void {
myRT.textFlow = TextFlowUtil.importFromString("school is written " +
String.fromCharCode(0x0645, 0x062f, 0x0631, 0x0633, 0x0629) +
" in Arabic and " + String.fromCharCode(0x05E1, 0x05B5, 0x05E4, 0x05B6, 0x05E8) +
" in Hebrew.");
}
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Example of Bidirectional text"&gt;
&lt;s:RichText id="myRT" width="400" height="150"/&gt;
&lt;/s:Panel&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>In this example, the <samp class="codeph">direction</samp> property is set
to "rtl". This causes the punctuation to be reversed so that the
period is on the left.</p>
<p>In some cases, you cannot set the <samp class="codeph">direction</samp> style
in MXML because some components (such as the ProgressBar and TileList
controls) already define a <samp class="codeph">direction</samp> property that
defines other behavior. For more information, see <a href="flx_mirroring_mr.html#WS19f279b149e7481c-11cc159f12ea10f6efe-7ff8_verapache">Overlapping
direction properties</a>.</p>
</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c6e1d7c6912ea0d4e3f5-8000_verapache"><a name="WS19f279b149e7481c6e1d7c6912ea0d4e3f5-8000_verapache"><!-- --></a>
<h2 class="topictitle2">Inheritance</h2>
<div>
<p>The values of the <samp class="codeph">layoutDirection</samp> and <samp class="codeph">direction</samp> style
properties are inherited by most components from their parent. As
a result, you typically set these properties on the Application
tag so that the properties are used consistently across the entire
application. While it is possible to set these styles on individual
components, this can be a cumbersome and mistake-prone approach. </p>
<p>In addition, if you set the style properties on individual components,
you override the defaults set in the global.css file. These defaults
define expected behavior. For example, you typically do not want
to reverse the direction of an Image or VideoDisplay control when
you mirror the contents of an application.</p>
<p>Some components, such as text-based controls, and the Image,
BitmapImage, VideoPlayer, and VideoDisplay controls do not inherit
the value of the <samp class="codeph">layoutDirection</samp> style property.
These components override the values of this property in the defaults.css
file. They either do not support the property, support it in a different
manner, or do not inherit the value because inheriting it would
create unexpected results. </p>
<div class="p">The following table describes the components that do not inherit
the value of the <samp class="codeph">layoutDirection</samp> style property:
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e349">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e355">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e349 ">
<p>BitmapImage, Image</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e355 ">
<p>The Image (both Spark and MX) and BitmapImage
components do not inherit the value of the <samp class="codeph">layoutDirection</samp> property
from the container because Flex assumes that you do not want to
mirror the contents. </p>
<p>To override this behavior and reverse
the contents of the MX Image and Spark BitmapImage controls, set
the value of the <samp class="codeph">layoutDirection</samp> property directly
on the control. You cannot reverse the contents of the Spark Image
control with the <samp class="codeph">layoutDirection</samp> property. For
more information, see <a href="flx_mirroring_mr.html#WS19f279b149e7481c23c09e112ea115b9a5-8000_verapache">Images
and video controls</a>.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e349 ">
<p>VideoDisplay, VideoPlayer</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e355 ">
<p>The VideoDisplay and VideoPlayer components
do not inherit the value of the <samp class="codeph">layoutDirection</samp> property
for the same reason that the Image components do not: the assumption
is that the contents should not be mirrored. </p>
<p>However, you
can override the default behavior by setting the <samp class="codeph">layoutDirection</samp> property
directly on the control. In this case, the VideoDisplay control
mirrors the actual video being displayed. </p>
<p>The VideoPlayer
mirrors the subcontrols that are used to control the video but not
the video itself.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e349 ">
<p>Spark text-based controls, such as those
based on the TextBase class (Label and RichText) and those including
the RichEditableText control (RichEditableText, TextArea, and TextInput) </p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e355 ">
<p>The reason that the Spark text-based controls
do not inherit the value of the <samp class="codeph">layoutDirection</samp> property
is that they use FTE/TLF to auto-detect the direction of the text.
The text characters are not mirrored in the same way that UI controls
are mirrored. </p>
<p>The input cursor for the TextArea and TextInput
controls does not rely on the <samp class="codeph">layoutDirection</samp> property,
but rather on the value of the direction property to determine the
starting position of the cursor when the control gains focus.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>In addition to being a style, the <samp class="codeph">layoutDirection</samp> property
is defined on the ILayoutDirectionElement interface. All UIComponents
inherit the properties of this interface. As a result, you can also
set the <samp class="codeph">layoutDirection</samp> as a property on an object.
If a component's <samp class="codeph">layoutDirection</samp> property is set
to <samp class="codeph">null</samp>, the component inherits the value from
its parent. For components that implement the ILayoutDirectionElement
interface, this means that setting <samp class="codeph">layoutDirection=null</samp> is
equivalent to <samp class="codeph">setStyle("layoutDirection", undefined)</samp>.</p>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-34fd6ec412ea0f43cd3-8000_verapache"><a name="WS19f279b149e7481c-34fd6ec412ea0f43cd3-8000_verapache"><!-- --></a>
<h2 class="topictitle2">Components</h2>
<div>
<p>This section describes the behavior of the components when
you set <samp class="codeph">layoutDirection</samp> to "rtl" on the Application
container. In most cases, the behavior of Spark and MX controls
is the same.</p>
</div>
<div class="nested2" id="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7fff_verapache"><a name="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7fff_verapache"><!-- --></a>
<h3 class="topictitle3">Basic UI controls</h3>
<div>
<div class="p">
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e521">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e527">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>Alert</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The Alert title is on the right. The text
is not mirrored. Any icons are on the right. All buttons are arranged
the opposite of their LTR order. For example, if buttons were "OK"
and "Cancel", they appear as "Cancel" and "OK".</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>Button</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The appearance of the Button is mirrored
but the label text is not. If you use the Button control with an
embedded icon, this icon is aligned on the right but the image itself
is not reversed. </p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>CheckBox</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The label is rendered on the left. The check
icon is not mirrored.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>ColorPicker</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The layout of the selector box and text
input are reversed. The color grid is reversed, with the most common
colors appearing on the right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>DateChooser</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The direction of days and months are mirrored.
The text for the days and numbers is not mirrored. The forward month
arrow is on the left and back month arrow button is on the right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>DateField</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The calendar icon appears on the left with
the text input on the right. The calendar that opens looks like
a mirrored DateChooser control. When you place a DateField control,
be sure to leave enough room on the left side for the popup. </p>
<p>When
there is sufficient room on the left the DateChooser popup is aligned
correctly. If there is not enough area on the left, the calendar
that pops up can be cut off by the screen edge.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>DownloadProgressBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The DownloadProgressBar is not mirrored.
It always fills from left to right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>Image</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The contents of the Image control are not
mirrored. To mirror the contents of an MX Image control, set the
value of the <samp class="codeph">layoutDirection</samp> property directly
on the component. You cannot mirror the contents of the Spark Image
control. Use the Spark BitmapImage or MX Image control instead.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>Link</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>Button order is from right to left. All
icons are aligned on the right of each button.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>NumericStepper</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The text in the input is aligned to the
right. The navigation buttons are on the left. Numbers appear the
same.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>PopUpButton</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The text is aligned to the right. The drop
down icon is on the left.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>PopUpMenuButton</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>See PopUpButton and Menu.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>ProgressBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The ProgressBar control fills in the track
from right to left. The label is aligned to the right. The ProgressBar
also has a direction style property that you can use to set the direction
of the filling.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>RadioButton</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>Labels are on the left of the radio icon.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>RadioButtonGroup</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>See RadioButton control.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>ScrollBar, HScrollBar, VScrollBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>Vertical scrollbars are the same, regardless
of the value of the <samp class="codeph">layoutDirection</samp> property. For
horizontal scrollbars, the thumb defaults to the right, which is
scroll position 0.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>Slider, HSlider, VSlider</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>For the HSlider control, the slider thumb's
starting point is reversed. The minimum value is at the right-most
point on the slider, and the maximum value is at the left-most point.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>Spinner</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>This component does not change when mirrored.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>SWFLoader</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The SWFLoader control mirrors its contents.
In some cases, this might be undesireable. The workaround is to
explicitly set the value of the <samp class="codeph">layoutDirection</samp> property
on the SWFLoader control when you do not want it to mirror the contents.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>VideoDisplay</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The contents of the VideoDisplay control
are not mirrored, unless you explicitly set <samp class="codeph">layoutDirection</samp> directly
on the control.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e521 ">
<p>VideoPlayer</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e527 ">
<p>The contents of the VideoPlayer control
are never mirrored. The player controls are mirrored so that the
slider thumb starts on the right and the location of the play button
is on the right.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7ffe_verapache"><a name="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7ffe_verapache"><!-- --></a>
<h3 class="topictitle3">List-based controls</h3>
<div>
<div class="p">
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e902">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e908">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e902 ">
<p>ButtonBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e908 ">
<p>Button order is from right to left. All
icons are aligned on the right of each button.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e902 ">
<p>ComboBox</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e908 ">
<p>In the editable field, text is aligned to
the right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e902 ">
<p>DropDownList</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e908 ">
<p>The icon appears on the left side. List
items are right aligned.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e902 ">
<p>FileSystemComboBox</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e908 ">
<p>Same as the MX ComboBox control.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e902 ">
<p>FileSystemList</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e908 ">
<p>Same as the MX List control.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e902 ">
<p>List, HorizontalList</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e908 ">
<p>All items in the List are aligned to the
right. ScrollBars are on the left (if they are necessary). For a
horizontal list, item 0 begins on the right. Items are laid out
right to left. A horizontal scroll bar thumb is positioned at <samp class="codeph">scrollPosition</samp> 0
on the right. </p>
<p>Note that for HorizontalList, the <samp class="codeph">direction</samp> property
requires a value of <samp class="codeph">TileBaseDirection.HORIZONTAL</samp> or <samp class="codeph">TileBaseDirection.VERTICAL</samp>.
The <samp class="codeph">direction</samp> style supports "ltr" and "rtl". </p>
<p>The <samp class="codeph">direction</samp> property
on the MX List and Spark List controls cannot be set in ActionScript.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7ffd_verapache"><a name="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7ffd_verapache"><!-- --></a>
<h3 class="topictitle3">Containers</h3>
<div>
<div class="p">
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e1066">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e1072">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>Accordion</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The labels and icons are aligned to the
right in the Accordion headers. All of the child controls of the
Accordion panes inherit the <samp class="codeph">layoutDirection="rtl"</samp> setting, unless
the child controls override this value, either in the application
or in the defaults.css file.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>DividedBox</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The first content area of a DividedBox is
on the right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>Form</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>Form item labels are on the right on controls.
The form heading is aligned right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>Grid</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>Grid items move from right to left and top
to bottom.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>HTML (AIR only) </p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The contents of the HTML control are not
mirrored.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>Panel</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The title and any icons are aligned right.
All of the child controls of the Panel container inherit the <samp class="codeph">layoutDirection="rtl"</samp> setting,
unless the child controls override this value, either in the application
or in the defaults.css file.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>TabNavigator</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>Tabs are laid out from right to left.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>TileList</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The first item is at the top right of the
TileList. Items are laid out from right to left. The direction property
requires a value of <samp class="codeph">TileBaseDirection.HORIZONTAL</samp> or <samp class="codeph">TileBaseDirection.VERTICAL</samp>.
The <samp class="codeph">direction</samp> style supports "ltr" and "rtl". The <samp class="codeph">direction</samp> property
on the TileList control cannot be set in ActionScript.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>TitleWindow</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The title is aligned on the right. The close
button is aligned on the left.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>Window</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The title is aligned at the top right. All
children are right aligned.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1066 ">
<p>WindowedApplication (AIR only)</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1072 ">
<p>The WindowedApplication title is aligned
at the top right. Controls of the WindowedApplication are at the
top left. Status text is aligned on the right.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7ffc_verapache"><a name="WS19f279b149e7481c-34fd6ec412ea0f43cd3-7ffc_verapache"><!-- --></a>
<h3 class="topictitle3">Data-driven controls</h3>
<div>
<div class="p">
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e1298">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e1304">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>MX chart controls</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>For CartesianChart-based charting controls,
the point of origin is the lower right. To align the DataTips to
the right, use the <samp class="codeph">direction</samp> style property. For
more information, see <a href="flx_mirroring_mr.html#WS19f279b149e7481c-11cc159f12ea10f6efe-7ffb_verapache">Charting
controls</a>.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>DataGrid</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>Headers and all text are aligned right.
Sort arrows are aligned left. Focus in editors moves from right
to left. Column 0 is on the far right.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>FileSystemDataGrid</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>Same as the MX DataGrid control.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>FileSystemTree</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>Same as the MX Tree control.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>Menu</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>Items are aligned right and submenus open
to the left.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>MenuBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>MenuBar data provider items are laid out
from right to left. Submenus open to the left.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1298 ">
<p>Tree</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1304 ">
<p>Items are aligned on the right. Items open
to the left. The icons are reversed.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c4c6270d212ea104536c-8000_verapache"><a name="WS19f279b149e7481c4c6270d212ea104536c-8000_verapache"><!-- --></a>
<h3 class="topictitle3">Text-based controls</h3>
<div>
<p>The Spark text-based controls support bidirectionality.
They auto-detect the direction of text based on the character codes.
MX text-based controls do not support mirroring or bidirectionality.
When using Spark text-based controls, you should set the <samp class="codeph">direction</samp> property
on the parent container or application. Setting the <samp class="codeph">direction</samp> property
causes the control to render punctuation properly as well as place
the cursor in the correct location when the control gains focus.</p>
<p>For most text controls, changing the layout direction has no
effect. This is mostly because most text controls do not have chrome
that would require laying out differently. The following table describes
the effects of changing <samp class="codeph">layoutDirection</samp> on text
controls:</p>
<div class="p">
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e1474">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e1480">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>Label</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>No change when <samp class="codeph">layoutDirection="rtl"</samp>.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>RichEditableText</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>No change when <samp class="codeph">layoutDirection="rtl"</samp>.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>RichText</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>No change when <samp class="codeph">layoutDirection="rtl"</samp>.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>RichTextEditor</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>No change when <samp class="codeph">layoutDirection="rtl"</samp>.
Note that the RichTextEditor control does not support mirroring
or bidirectional text.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>Text</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>No change when <samp class="codeph">layoutDirection="rtl"</samp>.
Note that the Text control does not support mirroring or bidirectional
text.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>TextArea</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>Spark TextArea: Text is aligned right. ScrollBars
are on the left. Cursor starts on the right of the TextInput control,
but only if <samp class="codeph">direction="rtl"</samp>. </p>
<p>MX TextArea:
Does not support mirroring or bidirectional text. Use the Spark
TextArea control instead.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1474 ">
<p>TextInput</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e1480 ">
<p>Spark TextInput: Text is aligned right.
Cursor starts on the right of the TextInput control, but only if <samp class="codeph">direction="rtl"</samp>. </p>
<p>MX
TextInput: Does not support mirroring or bidirectional text. Use
the Spark TextInput control instead.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>For more information, see <a href="flx_mirroring_mr.html#WS19f279b149e7481c4c6270d212ea104536c-7fff_verapache">Mirroring
with text controls</a>.</p>
</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c4c6270d212ea104536c-7fff_verapache"><a name="WS19f279b149e7481c4c6270d212ea104536c-7fff_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring with text controls</h2>
<div>
<p>Text in applications that use layout mirroring should generally
read from right to left. Chrome on the text controls should lay
out with an emphasis on right to left navigation. </p>
<p>The Flex compiler auto-detects the direction that text should
read based on the Unicode values of the characters. When the characters
use an RTL language such as Arabic or Hebrew, TLF-based text controls
reverse the order in which they are written.</p>
<p>Flex adjusts the location of punctuation marks such as periods,
exclamation points, and parentheses when the <samp class="codeph">direction</samp> is
set to "rtl". In addition, Flex also adjusts number separators,
paragraph breaks, and soft hyphens, as well as other non-character
entities so that their position makes sense. The algorithms for
this are described in <a href="https://unicode.org/reports/tr9/" target="_blank">Description of the Unicode bidirectional
algorithm</a>. </p>
<p>The direction of the text itself is only reversed if the character
set contains codes that instruct the compiler to read from RTL.</p>
<p>All text-based controls in the Spark component set support the <samp class="codeph">direction</samp> property
because they support FTE/TLF. Many text-based controls in the MX component
set support the <samp class="codeph">direction</samp> property.</p>
<div class="p">If your application uses text-based controls in the MX component
set such as MX Label, you must configure the compiler to use FTE,
which supports bidirectional text. Otherwise, the text will render
from LTR regardless of the character set you use. To ensure that
MX controls use FTE, you can apply the MXFTEText.css theme file:<pre class="codeblock">mxmlc -theme+=themes/MXFTEText.css MyApp.mxml</pre>
</div>
<p>Selecting this option causes most internal dependencies on <a href="https://flex.apache.org/asdoc/mx/core/UITextField.html" target="_blank">UITextField</a> to
be replaced with <a href="https://flex.apache.org/asdoc/mx/core/UIFTETextField.html" target="_blank">UIFTETextField</a>, which supports
FTE. The MX TextInput, TextArea, and RichText text classes do not
include this support. You should replace these controls with the
equivalent Spark text-based controls.</p>
<p>For text controls that have columns, the <samp class="codeph">direction</samp> style
property also affects the column order. When <samp class="codeph">direction</samp> is
set to "rtl", the first column is on the right.</p>
<p>The MX RichTextEditor control does not support mirroring or bidirectional
text.</p>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-8000_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-8000_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring with skins</h2>
<div>
<p>If you create custom skins, you should be aware of the
effects on the skins when they are mirrored. In general you do not
have to change your skins to use mirroring. In some cases, however,
skins use absolute positioning to draw elements of the skin. You
might need to edit the skin classes to make them appear correctly
when setting <samp class="codeph">layoutDirection</samp> to "rtl".</p>
<p>Mirroring is supported for components that use the Spark and
Wireframe themes. It is not supported for components that use the
Halo theme, or when you set the <samp class="codeph">compatibility-version</samp> compiler
option to 3.0.0.</p>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7fff_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7fff_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring with effects</h2>
<div>
<p>Effects that specify a direction, such as Wipe, or that
incorporate a direction, such as WipeRight and WipeLeft, are not
reversed when <samp class="codeph">layoutDirection</samp> is set to "rtl".
The effect always wipes in the direction that is defined by the
effect, regardless of the value of the <samp class="codeph">layoutDirection</samp> property.</p>
<div class="p">The following example shows that when you change the <samp class="codeph">layoutDirection</samp>, the
direction of the Wipe does not change:<pre class="codeblock">&lt;?xml version="1.0"?&gt;
&lt;!-- mirroring\EffectMirroring.mxml --&gt;
&lt;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"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:states&gt;
&lt;s:State name="default"/&gt;
&lt;s:State name="vis"/&gt;
&lt;/s:states&gt;
&lt;s:transitions&gt;
&lt;s:Transition fromState="*" toState="*"&gt;
&lt;s:Sequence target="{myB}"&gt;
&lt;s:Wipe id="wipeEffect"
direction="right"
duration="1000"/&gt;
&lt;/s:Sequence&gt;
&lt;/s:Transition&gt;
&lt;/s:transitions&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
private function setDirectionProps():void {
this.setStyle('layoutDirection', ddl1.selectedItem);
}
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Wipe Effect"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;s:Button id="myB" label="Wipe Effect"
visible.default="false" visible.vis="true"/&gt;
&lt;s:Button label="Show Button"
click="currentState='vis'"/&gt;
&lt;s:Button label="Hide Button"
click="currentState='default'"/&gt;
&lt;/s:Panel&gt;
&lt;s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setDirectionProps()"&gt;
&lt;s:ArrayList source="['ltr','rtl']"/&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>Effects that specify x and y coordinates, such as Zoom and Move,
apply the transform operations relative to the object. Because mirroring
changes the location of the x coordinate, these effects are effectively
reversed when the value of the <samp class="codeph">layoutDirection</samp> property
is changed.</p>
<div class="p">The following example shows that when the <samp class="codeph">layoutDirection</samp> changes,
the zoom effect changes its destination point:<pre class="codeblock">&lt;?xml version="1.0"?&gt;
&lt;!-- mirroring\MoveEffectMirroring.mxml --&gt;
&lt;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"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Declarations&gt;
&lt;s:Move id="moveOut" target="{targetImg}" xBy="100"/&gt;
&lt;s:Move id="moveBack" target="{targetImg}" xBy="-100"/&gt;
&lt;/fx:Declarations&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
private function setDirectionProps():void {
this.setStyle('layoutDirection', ddl1.selectedItem);
}
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Move Effect Example" height="200" width="300"&gt;
&lt;s:Image id="targetImg" source="@Embed(source='../assets/logosmall.jpg')"/&gt;
&lt;s:Button id="b1"
left="5" bottom="5"
label="Move Out" click="moveOut.play();"/&gt;
&lt;s:Button id="b2"
left="120" bottom="5"
label="Move Back" click="moveBack.play();"/&gt;
&lt;/s:Panel&gt;
&lt;s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setDirectionProps()"&gt;
&lt;s:ArrayList source="['ltr','rtl']"/&gt;
&lt;/s:DropDownList&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>When using coordinate-based effects with controls that do not
inherit the <samp class="codeph">layoutDirection</samp> style property, you
might need to customize the target of the effect. </p>
<p>For example, if you apply the Scale effect to an Image control
while the application is RTL, the Image's coordinates will not be
mirrored. The result is that the Scale effect's point of origin
is the upper left even when the application is RTL. To have the
effect play correctly, you might need to explicitly set the Image
control's <samp class="codeph">layoutDirection</samp> to "rtl", but then the
image itself is reversed as well.</p>
<div class="p">The following example shows how the effect plays incorrectly
when the layout for the application is RTL, but the layout for the
image is not RTL:<pre class="codeblock">&lt;?xml version="1.0"?&gt;
&lt;!-- mirroring\ScaleEffectMirroring.mxml --&gt;
&lt;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"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Declarations&gt;
&lt;s:Scale id="scaleUp" target="{targetImg}" scaleXBy="2" scaleYBy="2"/&gt;
&lt;s:Scale id="scaleDown" target="{targetImg}" scaleXBy="-2" scaleYBy="-2"/&gt;
&lt;/fx:Declarations&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
private function setAppDirection():void {
this.setStyle('layoutDirection', ddl1.selectedItem);
}
private function setImageDirection():void {
/* Note that this example uses an MX Image control rather than a Spark Image control.
Spark images cannot be reversed with the layoutDirection property. */
targetImg.setStyle('layoutDirection', ddl2.selectedItem);
}
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Scale Effect Example" height="300" width="300"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;mx:Image id="targetImg" source="@Embed(source='../assets/logosmall.jpg')"/&gt;
&lt;s:Button id="b1" label="Increase" click="scaleUp.transformX=-100;scaleUp.play();"/&gt;
&lt;s:Button id="b2" label="Decrease" click="scaleDown.play();"/&gt;
&lt;/s:Panel&gt;
&lt;s:HGroup&gt;
&lt;s:Label text="Set Application's layoutDirection:"/&gt;
&lt;s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setAppDirection()"&gt;
&lt;s:ArrayList source="['ltr','rtl']"/&gt;
&lt;/s:DropDownList&gt;
&lt;/s:HGroup&gt;
&lt;s:HGroup&gt;
&lt;s:Label text="Set Image's layoutDirection:"/&gt;
&lt;s:DropDownList id="ddl2" requireSelection="true" selectedIndex="0" change="setImageDirection()"&gt;
&lt;s:ArrayList source="['ltr','rtl']"/&gt;
&lt;/s:DropDownList&gt;
&lt;/s:HGroup&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>To workaround this issue, you should use two separate images,
one for when the application's layout is RTL and one for when the
application's layout is LTR. Then load the appropriate image when
the layout changes.</p>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffe_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffe_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring graphics and video</h2>
<div class="nested2" id="WS19f279b149e7481c23c09e112ea115b9a5-8000_verapache"><a name="WS19f279b149e7481c23c09e112ea115b9a5-8000_verapache"><!-- --></a>
<h3 class="topictitle3">Images and video controls</h3>
<div>
<p>Image and video controls do not inherit layout direction.
The BitmapImage, Spark and MX Image, VideoPlayer, and VideoDisplay
controls do not mirror their contents when you set the <samp class="codeph">layoutDirection</samp> property
on the application or parent container. These controls override
the value of this property in the globals.css file because the expected
behavior of images or videos is that the contents are not mirrored. </p>
<p>You can override this behavior in most cases, so that the contents
of these controls is mirrored. You do this by setting the value
of the <samp class="codeph">layoutDirection</samp> property to "rtl" directly
on the control. This is true for all the controls mentioned except
Spark Image. The Spark Image control does not mirror its contents regardless
of the value of the <samp class="codeph">layoutDirection</samp> property because
it is actually a child of the BitmapImage control (and image-related
controls do not inherit the layout direction). To mirror the image,
use the Spark BitmapImage or MX Image control.</p>
<p>As with images, icons are typically not mirrored, even if the
component that uses the icon is reversed (except in some special
cases, such as the disclosure icon in a Tree control).</p>
<p>To mirror the contents of the MX Image, BitmapImage, or VideoDisplay
controls, set the <samp class="codeph">layoutDirection</samp> property directly
on the control. You cannot mirror the contents of the VideoPlayer
control or the Spark Image control. </p>
<div class="p">The following example sets the <samp class="codeph">layoutDirection</samp> on
the Application tag to "rtl", and then sets the <samp class="codeph">layoutDirection</samp> property
to "rtl" directly on several of the images. This example shows that
the first image is not mirrored because it does not override the <samp class="codeph">layoutDirection</samp> property
and does not inherit its value from the Application container. The
second image is also not mirrored because the Spark Image control
does not reverse when the property is set on it. The third and fourth
images are mirrored because the MX Image and Spark BitmapImage controls
support setting <samp class="codeph">layoutDirection</samp> directly on them.<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring\MirroredImage.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="750"
layoutDirection="rtl"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="application.layoutDirection = rtl"/&gt;
&lt;s:HGroup&gt;
&lt;s:Panel title="Spark Image with default layoutDirection" height="150" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;s:Image source="@Embed(source='../assets/logosmall.jpg')"/&gt;
&lt;/s:Panel&gt;
&lt;s:Panel title="Spark Image with layoutDirection=rtl" height="150" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;s:Image source="@Embed(source='../assets/logosmall.jpg')" layoutDirection="rtl"/&gt;
&lt;/s:Panel&gt;
&lt;/s:HGroup&gt;
&lt;s:HGroup&gt;
&lt;s:Panel title="MX Image with layoutDirection=rtl" height="150" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;mx:Image source="@Embed(source='../assets/logosmall.jpg')" layoutDirection="rtl"/&gt;
&lt;/s:Panel&gt;
&lt;s:Panel title="BitmapImage with layoutDirection=rtl" height="150" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;s:BitmapImage source="@Embed(source='../assets/logosmall.jpg')" layoutDirection="rtl"/&gt;
&lt;/s:Panel&gt;
&lt;/s:HGroup&gt;
&lt;/s:Application&gt;</pre>
</div>
<div class="p">You can also cause the contents of image controls to be mirrored
by setting the <samp class="codeph">scaleX</samp> property to -1 rather than
setting the <samp class="codeph">layoutDirection</samp> property; for example:<pre class="codeblock">sparkImage.scaleX = -1;</pre>
</div>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c23c09e112ea115b9a5-7fff_verapache"><a name="WS19f279b149e7481c23c09e112ea115b9a5-7fff_verapache"><!-- --></a>
<h3 class="topictitle3">FXG and MXML graphics</h3>
<div>
<p>FXG graphics and MXML graphics are mirrorred by default.
When the application or parent container sets the <samp class="codeph">layoutDirection</samp> property,
the FXG component and the MXML graphic are mirrorred.</p>
<div class="p">The following example shows a simple FXG component, and an MXML
graphic, that inherit the application's <samp class="codeph">layoutDirection</samp>,
and are therefore mirrored:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring\MirroredFXG.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:custom="*"
layoutDirection="rtl"
width="600" height="300"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;s:Label text="application.layoutDirection = rtl"/&gt;
&lt;s:HGroup&gt;
&lt;s:Panel title="FXG: layoutDirection = default" height="150" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;custom:ArrowAbsolute/&gt;
&lt;/s:Panel&gt;
&lt;s:Panel title="MXML: graphic layoutDirection = default" height="150" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingTop="15" paddingLeft="15"/&gt;
&lt;/s:layout&gt;
&lt;!-- Use absolute coordinates. --&gt;
&lt;s:Graphic&gt;
&lt;!-- Use Use compact syntax with absolute coordinates. --&gt;
&lt;s: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"&gt;
&lt;!-- Define the border color of the arrow. --&gt;
&lt;s:stroke&gt;
&lt;s:SolidColorStroke color="0x888888"/&gt;
&lt;/s:stroke&gt;
&lt;!-- Define the fill for the arrow. --&gt;
&lt;s:fill&gt;
&lt;s:LinearGradient rotation="90"&gt;
&lt;s:GradientEntry color="0x000000" alpha="0.8"/&gt;
&lt;s:GradientEntry color="0xFFFFFF" alpha="0.8"/&gt;
&lt;/s:LinearGradient&gt;
&lt;/s:fill&gt;
&lt;/s:Path&gt;
&lt;/s:Graphic&gt;
&lt;/s:Panel&gt;
&lt;/s:HGroup&gt;
&lt;/s:Application&gt;</pre>
</div>
<div class="p">This example uses the following FXG file as a custom component:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- fxg/comps/ArrowAbsolute.fxg --&gt;
&lt;Graphic xmlns="http://ns.adobe.com/fxg/2008" version="2"&gt;
&lt;!-- Use Use compact syntax with absolute coordinates. --&gt;
&lt;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"&gt;
&lt;!-- Define the border color of the arrow. --&gt;
&lt;stroke&gt;
&lt;SolidColorStroke color="#888888"/&gt;
&lt;/stroke&gt;
&lt;!-- Define the fill for the arrow. --&gt;
&lt;fill&gt;
&lt;LinearGradient rotation="90"&gt;
&lt;GradientEntry color="#000000" alpha="0.8"/&gt;
&lt;GradientEntry color="#FFFFFF" alpha="0.8"/&gt;
&lt;/LinearGradient&gt;
&lt;/fill&gt;
&lt;/Path&gt;
&lt;/Graphic&gt; </pre>
</div>
<div class="p">You can set the <samp class="codeph">layoutDirection</samp> of the parent
container on the Graphic tag directly; for example:<pre class="codeblock">&lt;s:Graphic layoutDirection='rtl'&gt;</pre>
</div>
<p>Flex mirrors the contents of the BitmapFill class when you set
the property on the container. This can cause undesireable results
when you set the <samp class="codeph">layoutDirection</samp> property on an
application that supports both RTL and LTR. To workaround this issue,
you can create two versions of the graphic. Then create a custom
skin for your control that uses the background image and use states
to pick the right one depending on the value of the application's <samp class="codeph">layoutDirection</samp>.</p>
</div>
</div>
<div class="nested2" id="WS19f279b149e7481c23c09e112ea115b9a5-7ffe_verapache"><a name="WS19f279b149e7481c23c09e112ea115b9a5-7ffe_verapache"><!-- --></a>
<h3 class="topictitle3">Coordinate systems</h3>
<div>
<div class="p">When using graphics, you specify the start point and end
point of paths. These locations are represented as coordinate X/Y
pairs such as (0,0). The default location for (0,0) is the upper
left corner of the container that you are drawing in. If you change
the layout direction, the coordinates, too, are mirrored. As a result, the
coordinates (0,0) in a container with <samp class="codeph">layoutDirection="rtl"</samp> refers
to the upper right corner of the container, as the following example
shows:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring/CoordinatesMirroring.mxml --&gt;
&lt;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"&gt;
&lt;s:layout&gt;
&lt;s:HorizontalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import mx.core.LayoutDirection;
]]&gt;
&lt;/fx:Script&gt;
&lt;mx:Panel title="LTR: from (0,0) to (100,100)"
height="75%" width="40%" layout="horizontal"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"&gt;
&lt;s:Group&gt;
&lt;s:Line xFrom="0" xTo="100" yFrom="0" yTo="100"&gt;
&lt;s:stroke&gt;
&lt;s:SolidColorStroke color="0x000000" weight="1"/&gt;
&lt;/s:stroke&gt;
&lt;/s:Line&gt;
&lt;/s:Group&gt;
&lt;/mx:Panel&gt;
&lt;mx:Panel title="RTL: from (0,0) to (100,100)" layoutDirection="{LayoutDirection.RTL}"
height="75%" width="40%" layout="horizontal"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"&gt;
&lt;s:Group&gt;
&lt;s:Line xFrom="0" xTo="100" yFrom="0" yTo="100"&gt;
&lt;s:stroke&gt;
&lt;s:SolidColorStroke color="0x000000" weight="1"/&gt;
&lt;/s:stroke&gt;
&lt;/s:Line&gt;
&lt;/s:Group&gt;
&lt;/mx:Panel&gt;
&lt;/s:Application&gt;</pre>
</div>
<p>This same logic applies to layout coordinates. When you set the
x and y position of a component in an LTR panel, the coordinates
start at the upper left. If the panel's layout direction is RTL,
the coordinates start in the upper right. However, calling the <samp class="codeph">Menu.show(0,0)</samp> method
will not pop up a menu at the top right, but rather, the top left
because global coordinates are used.</p>
<p>If you use the <samp class="codeph">localToGlobal()</samp> and <samp class="codeph">globalToLocal()</samp> methods,
or the DisplayObject <samp class="codeph">transform</samp> property, you should
be aware of the difference between a component's <samp class="codeph">layoutMatrix</samp> and <samp class="codeph">computedMatrix</samp>.
The <samp class="codeph">layoutMatrix</samp> is used to calculate the component's
layout relative to its siblings. The <samp class="codeph">computedMatrix</samp> incorporates
the <samp class="codeph">layoutMatrix</samp> and an IVisualElement's <samp class="codeph">postLayoutTransformOffsets</samp>,
which include the mirroring transform. The<samp class="codeph"> localToGlobal()</samp> and <samp class="codeph">globalToLocal()</samp> methods
and the <samp class="codeph">transform.concatenatedMatrix</samp> property reflect
the computed matrix. </p>
<div class="p">To transform a point to global coordinates using only the <samp class="codeph">layoutMatrix</samp>,
use the <samp class="codeph">MatrixUtil.getConcatenatedMatrix()</samp> method,
as the following example shows:<pre class="codeblock">var myGlobalPoint = MatrixUtil.getConcatenatedComputedMatrix(myIVisualElement).transformPoint(myPoint);</pre>
</div>
<p>When working with coordinates, you should be aware of how the
mirroring transform works. In an LTR application, X increases to
the right and the origin is the upper left corner. In an RTL layout,
X increases to the left and the origin is the upper right corner.
This is accomplished internally by scaling the X-axis by -1 and translating
the UIComponent by its width, after layout.</p>
<div class="p">The effect of this mirroring transform is as follows:<pre class="codeblock">element.x += width;
element.scaleX *= -1;</pre>
</div>
<p>All of the IVisualElement classes implement the mirroring transform
using the same mechanism that is used by the offsets transform.
That means that they are combined with the layout transform after
layout has occurred. The transforms do not affect the actual values
of the UIComponent's <samp class="codeph">x</samp> and <samp class="codeph">scaleX</samp> properties.</p>
</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffd_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffd_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring DataGrid controls</h2>
<div>
<p>You can use mirroring with a <a href="https://flex.apache.org/asdoc/spark/components/DataGrid.html" target="_blank">DataGrid</a> control
by setting the <samp class="codeph">layoutDirection</samp> property on the
application. Like most controls, the DataGrid control inherits this
value. Setting the layout direction to RTL causes the columns to
be arranged from right to left (column 0 is the right-most). This
also aligns the sort arrows to the left of the header text. If the
DataGrid is editable and the user clicks on a cell, the focus starts
on the right side of the grid.</p>
<p>To align the text in the cells to the right, reverse the direction
of the header text, and reverse the text in the individual cells
of a DataGrid, you must also set the <samp class="codeph">direction</samp> style
property to "rtl". You can set this on a parent container or on the
DataGrid itself.</p>
<div class="p">The following example sets both the <samp class="codeph">layoutDirection</samp> and <samp class="codeph">direction</samp> properties
to "rtl" so that the entire Spark DataGrid is mirrored:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring\MirroredDataGrid.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="600" height="400"
layoutDirection="rtl" direction="rtl"&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var dp:ArrayCollection = new ArrayCollection([
{Artist:'Train', Album:'Drops of Jupiter', Price:13.99},
{Artist:'Charred Walls of the Damned', Album:'Ghost Town', Price:8.99},
{Artist:'Bleading Deacons', Album:'Rule the Night', Price:11.99},
{Artist:'Three Stooges', Album:'Greatest Hits', Price:9.99} ]);
]]&gt;
&lt;/fx:Script&gt;
&lt;s:DataGrid id="myGrid" dataProvider="{dp}"
width="350" height="150"/&gt;
&lt;/s:Application&gt;</pre>
</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffc_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffc_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring layouts</h2>
<div>
<p>In a mirrored container, the roles of the left and right
layout constraints are effectively reversed: the left constraint
specifies the distance from the component's right edge to the right
edge of the container, and the right constraint specifies the distance
between the left edges.</p>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffb_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffb_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring charting controls</h2>
<div>
<p>To mirror charts, you set the <samp class="codeph">layoutDirection</samp> property
on the chart's parent container to RTL. Typically, you set it on
the Application container. Charting controls inherit the value of
this property set on the parent container. </p>
<p>In charts that are based on the CartesianChart class, such as
the AreaChart, LineChart, and PlotChart controls, setting the <samp class="codeph">layoutDirection</samp> property
to "rtl" sets the point of origin at the lower right of the chart,
rather than the lower left. For charts based on the PolarChart class,
such as the PieChart control, setting the <samp class="codeph">layoutDirection</samp> property
to "rtl" has no effect on the point of origin.</p>
<div class="p">The following example shows a chart that uses mirroring:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring\MirroredChart.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="srv.send()"
layoutDirection="rtl"
width="600" height="600"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;fx:Declarations&gt;
&lt;mx:HTTPService id="srv" url="http://aspexamples.adobe.com/chart_examples/expenses-xml.aspx"/&gt;
&lt;/fx:Declarations&gt;
&lt;fx:Style&gt;
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace charts "mx.charts.chartClasses.*";
charts|DataTip {
direction:rtl;
paddingRight:-10;
paddingLeft:5;
}
&lt;/fx:Style&gt;
&lt;s:Panel title="Column Chart"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout/&gt;
&lt;/s:layout&gt;
&lt;mx:ColumnChart id="myChart" dataProvider="{srv.lastResult.data.result}" showDataTips="true"&gt;
&lt;mx:horizontalAxis&gt;
&lt;mx:CategoryAxis id="haxis" categoryField="month" title="Month"/&gt;
&lt;/mx:horizontalAxis&gt;
&lt;mx:verticalAxis&gt;
&lt;mx:LinearAxis id="vaxis" title="Amount"/&gt;
&lt;/mx:verticalAxis&gt;
&lt;mx:series&gt;
&lt;mx:ColumnSeries
xField="month"
yField="profit"
displayName="Profit"/&gt;
&lt;mx:ColumnSeries
xField="month"
yField="expenses"
displayName="Expenses"/&gt;
&lt;/mx:series&gt;
&lt;/mx:ColumnChart&gt;
&lt;/s:Panel&gt;
&lt;/s:Application&gt; </pre>
</div>
<div class="p">You should be aware of some minor differences in the way charting
controls use spacing and alignment when the <samp class="codeph">layoutDirection</samp> is
"rtl". For example, to right align the contents of DataTips, set
the DataTip <samp class="codeph">direction</samp> style property to "rtl".
You might also need to adjust the padding properties to get the alignment
you want. For example:<pre class="codeblock">@namespace charts "mx.charts.chartClasses.*";
charts|DataTip {
direction:rtl;
paddingRight:-10;
paddingLeft:5;
}</pre>
In addition, when the <samp class="codeph">layoutDirection</samp> property
is set to "rtl":<ul>
<li>
<p>Gutter padding — The left and right gutter
style properties are reversed. The <samp class="codeph">gutterLeft</samp> property
changes the gutter padding on the right, and the <samp class="codeph">gutterRight</samp> property
changes the gutter padding on the left.</p>
</li>
<li>
<p>Axis labels — Setting <samp class="codeph">labelAlign="left"</samp> aligns
the label to the right, and <samp class="codeph">labelAlign="right"</samp> aligns
the label to the left.</p>
</li>
<li>
<p>Axis titles — The <samp class="codeph">textIndent</samp> property is
unaffected by the <samp class="codeph">layoutDirection</samp> property. Axis
titles do not support the <samp class="codeph">textAlign</samp> property, so
setting the <samp class="codeph">layoutDirection</samp> property has no effect
on this property.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffa_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ffa_verapache"><!-- --></a>
<h2 class="topictitle2">Using the LocaleID class</h2>
<div>
<p>The <a href="https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/globalization/LocaleID.html" target="_blank">LocaleID</a> class, available in
Flash Player 10.1 and higher, provides methods and properties for
using locale IDs. Locale IDs are strings that represent a particular
locale. They can be useful when deciding whether to change the layout
direction of an application.</p>
<div class="p">The LocaleID class includes the <samp class="codeph">isRightToLeft()</samp> method,
which returns <samp class="codeph">true</samp> if the currently set locale
uses an RTL character code set, but otherwise returns <samp class="codeph">false</samp>.
You can use this method to set the values of the <samp class="codeph">layoutDirection</samp> and <samp class="codeph">direction</samp> properties.
When you change locales in the following example, the application
checks the <samp class="codeph">isRightToLeft()</samp> method and sets the <samp class="codeph">layoutDirection</samp> and <samp class="codeph">direction</samp> properties
on the Application object accordingly:<pre class="codeblock">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- mirroring\LocaleIDMirroringExample.mxml --&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="300" height="300"
layoutDirection="{localeBasedDirection}"
direction="{localeBasedDirection}"
creationComplete="updateSelection()"&gt;
&lt;fx:Script&gt;
&lt;![CDATA[
import flash.globalization.LocaleID;
import mx.collections.ArrayCollection;
[Bindable]
public var localeBasedDirection:String;
[Bindable]
public var locID:LocaleID;
[Bindable]
public var myDP:ArrayCollection = new ArrayCollection(
[ {name:"US", locale:"en_US"},
{name:"Israel", locale:"he_IL"},
{name:"France", locale:"fr_FR"} ]);
private function updateSelection():void {
locID = new LocaleID(localeIdList.selectedItem.locale);
isRTLLabel.text = "RTL: " + locID.isRightToLeft().toString();
getRegionLabel.text = "Region: " + locID.getRegion();
getLanguageLabel.text = "Language: " + locID.getLanguage();
if (locID.isRightToLeft()) {
localeBasedDirection = "rtl";
} else {
localeBasedDirection = "ltr";
}
}
]]&gt;
&lt;/fx:Script&gt;
&lt;s:Panel title="Select Locale" height="200" width="250"&gt;
&lt;s:layout&gt;
&lt;s:VerticalLayout paddingLeft="10" paddingRight="10" paddingTop="10"/&gt;
&lt;/s:layout&gt;
&lt;s:VGroup&gt;
&lt;s:DropDownList id="localeIdList" selectedIndex="0"
dataProvider="{myDP}"
labelField="name"
change="updateSelection();"/&gt;
&lt;s:Label id="isRTLLabel"/&gt;
&lt;s:Label id="getRegionLabel"/&gt;
&lt;s:Label id="getLanguageLabel"/&gt;
&lt;/s:VGroup&gt;
&lt;/s:Panel&gt;
&lt;/s:Application&gt;</pre>
</div>
<div class="p">This example requires classes in the flash.globalization.* package,
which are available in the 10.1 or later playerglobal.swc file.
When compiling this example, be sure to set the target player version
to 10.1 or later. On the command-line, you can set the target Player
version by using the <samp class="codeph">target-player</samp> option; for example:<pre class="codeblock">mxmlc -target-player=10.1 MyApp.mxml</pre>
In
your applications, you will typically have some additional logic
that sets the locale in your application, such as looking at the
OS language code or accepting a user-configured setting. For information
on setting locales in your application, see <a href="flx_l10n_ln.html#WS19f279b149e7481c-99797f112bd080033f-8000_verapache">Setting
the locale</a>.</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ff9_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ff9_verapache"><!-- --></a>
<h2 class="topictitle2">Mirroring with ToolTips and Error
tips</h2>
<div>
<p>The <samp class="codeph">layoutDirection</samp> of the <a href="https://flex.apache.org/asdoc/mx/controls/ToolTip.html" target="_blank">ToolTip</a> class
is same as the component that is attached to the ToolTip, or LTR,
if the component does not implement the <a href="https://flex.apache.org/asdoc/mx/core/ILayoutDirectionElement.html" target="_blank">ILayoutDirectionElement</a> interface.</p>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ff8_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ff8_verapache"><!-- --></a>
<h2 class="topictitle2">Overlapping direction properties</h2>
<div>
<div class="p">Some components have a <samp class="codeph">direction</samp> style
property that is not related to text direction. These <samp class="codeph">direction</samp> style
properties typically take values not related to text direction.
The compiler could throw an error if you try to set the <samp class="codeph">direction</samp> property
with these values. The following table lists these components:
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all">
<thead align="left">
<tr>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e2331">
<p>Control</p>
</th>
<th class="cellrowborder" valign="top" width="NaN%" id="d305327e2337">
<p>Description</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.containers.Box</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
refers to the direction in which the container lays out its children.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.containers.FormItem</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
detemines whether the children of the FormItem are stacked vertically
or placed horizontally.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.controls.ProgressBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
refers to the direction in which the bar expands towards completion.
Possible values are "left" and "right". In general, you should set
this to "right" when the application's layout is RTL.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.controls.scrollClasses.ScrollBar</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
detemines whether the scrollbar is for scrolling vertically or horizontally.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.controls.sliderClasses.Slider</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
detemines whether the slider is oriented vertically or horizontally.
If you use an HSlider or VSlider, the control sets the value for
you.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.containers.Tile</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
refers to the direction in which the container lays out its children.</p>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2331 ">
<p>mx.controls.listClasses.TileBase (which includes
TileList and HorizontalList)</p>
</td>
<td class="cellrowborder" valign="top" width="NaN%" headers="d305327e2337 ">
<p>The <samp class="codeph">direction</samp> property
refers to the direction in which the container lays out its children.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="nested1" id="WS19f279b149e7481c-11cc159f12ea10f6efe-7ff7_verapache"><a name="WS19f279b149e7481c-11cc159f12ea10f6efe-7ff7_verapache"><!-- --></a>
<h2 class="topictitle2">Tips for using mirroring</h2>
<div>
<div class="p">Use the following tips when creating applications that
use layout mirroring:<ul>
<li>
<p>Avoid setting the <samp class="codeph">layoutDirection</samp> and
direction properties on individual components. Set them on the Application
container.</p>
</li>
<li>
<p>Avoid using the alignment properties of individual components
or blocks of text.</p>
</li>
<li>
<p>Avoid using absolute positioning.</p>
</li>
<li>
<p>If you want to mirror the contents of images (including icons)
and videos, you should reverse the image or video in your image
editing tools prior to importing them into your Flex application.
The Spark and MX Image, BitmapImage, and VideoPlayer controls do
not inherit the <samp class="codeph">layoutDirection</samp> property from their
parent container. The MX Image, Spark BitmapImage, and VideoDisplay
controls do mirror their contents if you set <samp class="codeph">layoutDirection</samp> on
the control directly. The Spark Image control does not mirror its
contents regardless of the value of its layout direction.</p>
</li>
<li>
<p>Spark text controls do not use layout mirroring. Instead,
they support bidirectionality of text internally. As a result, the
primitive text controls such as Label, RichText, and RichEditableText
do not support the <samp class="codeph">layoutDirection</samp> property. You
typically set the <samp class="codeph">direction</samp> style property to change
the directionality of the text in these controls.</p>
</li>
<li>
<p>If you use text-based controls from the MX component set
in your application, be sure to configure the compiler to use FTE
to display the text. To do this on the command line, apply the MXFTEText.css
theme file.</p>
</li>
<li>
<p>For Spark text controls or FTE text in MX components, use
the values <samp class="codeph">TextAlign.START</samp> and <samp class="codeph">TextAlign.END</samp> for
the <samp class="codeph">textAlign</samp> property, rather than <samp class="codeph">TextAlign.LEFT</samp> and <samp class="codeph">TextAlign.RIGHT</samp>.
Using <samp class="codeph">START</samp> and <samp class="codeph">END</samp> will work
in the expected manner, regardless of the direction of the text.</p>
</li>
<li>
<p>In many components, navigating with the arrow keys changes
depending on the directionality of the text. For example, the left
arrow will navigate toward the beginning of the text and the right
arrow key will navigate toward the end when the text is RTL.</p>
</li>
</ul>
</div>
</div>
<div>
<p><strong>Navigation</strong></p>
<p><a href="index.html">Using Flex</a> &raquo; <a href="flx_p6_enhancing_usability.html">Enhancing usability</a></p>
</div>
<p>Adobe, Adobe Flash, and Adobe Flash Player are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries and are used by permission from Adobe. No other license to the Adobe trademarks are granted.</p>
</div>
</body>
</html>