blob: 6f4b6130d52b3e34c431675c47231d0f8aaf7d5b [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.
-->
<!-- Demonstrate some example controls. This example does not attempt to create a control for every property in the TextLayoutFramework -->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
height="570" label="Text Editor Example" backgroundColor="#FFFFFF"
horizontalScrollPolicy="off" initialize="init()" verticalScrollPolicy="on">
<mx:Script>
<![CDATA[
import com.adobe.linguistics.spelling.SpellUIForTLF;
import com.adobe.linguistics.spelling.framework.SpellingService;
import com.adobe.linguistics.spelling.ui.IHighlighter;
import com.adobe.linguistics.spelling.ui.IWordProcessor;
import com.adobe.linguistics.utils.Token;
import flash.display.Sprite;
import flash.system.Capabilities;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.conversion.TextConverter;
import flashx.textLayout.edit.EditManager;
import flashx.textLayout.edit.ElementRange;
import flashx.textLayout.edit.IEditManager;
import flashx.textLayout.edit.SelectionState;
import flashx.textLayout.elements.Configuration;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.events.SelectionEvent;
import flashx.textLayout.events.StatusChangeEvent;
import flashx.textLayout.formats.BlockProgression;
import flashx.textLayout.formats.Direction;
import flashx.textLayout.formats.ITextLayoutFormat;
import flashx.textLayout.formats.TextAlign;
import flashx.textLayout.formats.TextLayoutFormat;
import flashx.textLayout.formats.VerticalAlign;
import flashx.textLayout.tlf_internal;
import flashx.undo.UndoManager;
// the textFlow being worked on
private var _textFlow:TextFlow = null;
private var _myContainerController:MyContainerController=null;
// container to hold the text
private var _container:Sprite = null;
// ///////////////////////////////////////
// data providers for enumerated list boxes
// ///////////////////////////////////////
static private const textAlignData:Array = [
{ label:"Justify", data:TextAlign.JUSTIFY},
{ label:"Left", data:TextAlign.LEFT},
{ label:"Right", data:TextAlign.RIGHT},
{ label:"Center", data:TextAlign.CENTER},
{ label:"End", data:TextAlign.END},
{ label:"Start", data:TextAlign.START}
];
static private const verticalAlignData:Array = [
{ label:"Bottom", data:VerticalAlign.BOTTOM },
{ label:"Justify", data:VerticalAlign.JUSTIFY },
{ label:"Middle", data:VerticalAlign.MIDDLE },
{ label:"Top", data:VerticalAlign.TOP }
];
static private const blockProgressionData:Array = [
{ label:"TopToBottom", data:BlockProgression.TB },
{ label:"RightToleft", data:BlockProgression.RL }
];
static private const directionData:Array = [
{ label:"LeftToRight", data:Direction.LTR },
{ label:"RightToleft", data:Direction.RTL }
];
/**
* initialization
*/
private function init():void
{
// create a sprite to hold the TextLines
_container = new Sprite();
textArea.rawChildren.addChild(_container);
fontFamily.dataProvider = populateFontFamily();
versionInfo.text = "Vellum: 3.x" + (Configuration.tlf_internal::debugCodeEnabled ? " Debug" : " Release")
+ ", Flex: " + mx_internal::VERSION
+ ", Player: " + Capabilities.version;
}
/**
* Create an array of available font families
*/
static private function populateFontFamily():Array
{
// really this returns an array of fonts - would be nice to strip it down to just the families
var fonts:Array = Font.enumerateFonts(true);
var fontfamily:Array = new Array();
fonts.sortOn("fontName", Array.CASEINSENSITIVE);
for(var i:int = 0; i< fonts.length; i++)
{
// trace(fonts[i].fontName);
fontfamily.push({label: fonts[i].fontName, data: fonts[i].fontName});
}
return fontfamily;
}
/** called to set the size of this panel */
public function setSize(w:int,h:int):void
{
this.width = w;
this.height = h;
textArea.width = width;
textArea.height = height > bottomTabs.height ? this.height-bottomTabs.height : 0;
if (_textFlow)
{
_textFlow.flowComposer.getControllerAt(0).setCompositionSize(textArea.width,textArea.height);
_textFlow.flowComposer.updateAllControllers();
}
}
/** called when the bottom tabs finally gets sized. */
private function bottomTabsResize():void
{
setSize(width,height);
}
/** The TextFlow to edit. */
public function get textFlow():TextFlow
{ return _textFlow; }
public function set textFlow(newFlow:TextFlow):void
{
// clear any old flow if present
if (_textFlow)
{
_textFlow.flowComposer = null;
_textFlow = null;
}
_textFlow = newFlow;
if (_textFlow)
{
_myContainerController=new MyContainerController(_container,textArea.width,textArea.height);
_textFlow.flowComposer.addController(_myContainerController);
// setup event listeners for selection changed and ILG loaded
_textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE,selectionChangeListener,false,0,true);
_textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,graphicStatusChangeEvent,false,0,true);
// make _textFlow editable with undo
_textFlow.interactionManager = new EditManager(new UndoManager());
// initialize with a selection before the first character
_textFlow.interactionManager.selectRange(0,0);
// compose the new textFlow and give it focus
_textFlow.flowComposer.updateAllControllers();
_textFlow.interactionManager.setFocus();
}
}
/** Receives an event any time an ILG with a computed size finishes loading. */
private function graphicStatusChangeEvent(evt:StatusChangeEvent):void
{
// recompose if the evt is from an element in this textFlow
if (_textFlow && evt.element.getTextFlow() == _textFlow)
_textFlow.flowComposer.updateAllControllers();
}
/** Receives an event any time the selection is changed. Update the UI */
private function selectionChangeListener(e:SelectionEvent):void
{
var selectionState:SelectionState = e.selectionState;
var selectedElementRange:ElementRange = ElementRange.createElementRange(selectionState.textFlow, selectionState.absoluteStart, selectionState.absoluteEnd);
// set display according to the values at the beginning of the selection range. For point selection/characterFormat use getCommonCharacterFormat as that tracks pending attributes waiting for the next character
var characterFormat:ITextLayoutFormat = _textFlow.interactionManager.activePosition == _textFlow.interactionManager.anchorPosition ? _textFlow.interactionManager.getCommonCharacterFormat() : selectedElementRange.characterFormat;
var paragraphFormat:ITextLayoutFormat = selectedElementRange.paragraphFormat;
var containerFormat:ITextLayoutFormat = selectedElementRange.containerFormat;
updateComboBox(fontFamily,characterFormat.fontFamily);
fontSize.text = characterFormat.fontSize.toString();
lineHeight.text = characterFormat.lineHeight.toString();
updateComboBox(textAlign,paragraphFormat.textAlign);
textIndent.text = paragraphFormat.textIndent.toString();
columnCount.text = containerFormat.columnCount.toString();
columnGap.text = containerFormat.columnGap.toString();
updateComboBox(verticalAlign,containerFormat.verticalAlign);
updateComboBox(blockProgression,_textFlow.computedFormat.blockProgression);
updateComboBox(directionBox,_textFlow.computedFormat.direction);
}
/** Helper function to update a comboBox in the UI */
private function updateComboBox(box:ComboBox,val:String):void
{
for (var i:int = 0; i < box.dataProvider.length; i++)
{
if (box.dataProvider[i].data == val)
{
box.selectedIndex = i;
return;
}
}
box.text = val;
}
/**
* These functions are helpers for the various widgets to actually perform the operations on the TextFlow
*/
private function changeFontFamily(newFontFamily:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.fontFamily = newFontFamily;
IEditManager(_textFlow.interactionManager).applyLeafFormat(cf);
_textFlow.interactionManager.setFocus();
}
}
private function changeFontSize(newFontSize:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.fontSize = newFontSize;
IEditManager(_textFlow.interactionManager).applyLeafFormat(cf);
_textFlow.interactionManager.setFocus();
}
}
private function changeLeading(newLeading:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.lineHeight = newLeading;
IEditManager(_textFlow.interactionManager).applyLeafFormat(cf);
_textFlow.interactionManager.setFocus();
}
}
private function changeTextAlign(newAlign:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var pf:TextLayoutFormat = new TextLayoutFormat();
pf.textAlign = newAlign;
IEditManager(_textFlow.interactionManager).applyParagraphFormat(pf);
_textFlow.interactionManager.setFocus();
}
}
private function changeTextIndent(newIndent:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var pf:TextLayoutFormat = new TextLayoutFormat();
pf.textIndent = newIndent;
IEditManager(_textFlow.interactionManager).applyParagraphFormat(pf);
_textFlow.interactionManager.setFocus();
}
}
private function changeColumnCount(newCount:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.columnCount = newCount;
IEditManager(_textFlow.interactionManager).applyContainerFormat(cf);
_textFlow.interactionManager.setFocus();
}
}
private function changeColumnGap(newGap:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.columnGap = newGap;
IEditManager(_textFlow.interactionManager).applyContainerFormat(cf);
_textFlow.interactionManager.setFocus();
}
}
private function changeVerticalAlign(newAlign:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.verticalAlign = newAlign;
IEditManager(_textFlow.interactionManager).applyContainerFormat(cf);
_textFlow.interactionManager.setFocus();
}
}
private function changeBlockProgression(newProgression:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var cf:TextLayoutFormat = new TextLayoutFormat();
cf.blockProgression = newProgression;
IEditManager(_textFlow.interactionManager).applyFormatToElement(_textFlow,cf);
_textFlow.interactionManager.setFocus();
}
}
/** Set direction on the rootElement. This effects both columnDirection and default reading order. */
private function changeDirection(newDirection:String):void
{
if (_textFlow && _textFlow.interactionManager is IEditManager)
{
var pf:TextLayoutFormat = new TextLayoutFormat();
pf.direction = newDirection;
IEditManager(_textFlow.interactionManager).applyFormatToElement(_textFlow,pf);
_textFlow.interactionManager.setFocus();
}
}
protected function doSpell():void
{
if(spellLang.text)
SpellUIForTLF.enableSpelling(_textFlow,spellLang.text );
_myContainerController.language=spellLang.text;
}
protected function undoSpell():void
{
SpellUIForTLF.disableSpelling(_textFlow);
_myContainerController.setFuncsNull();
}
]]>
</mx:Script>
<!-- <mx:VBox horizontalScrollPolicy="off" verticalScrollPolicy="off" width="100%" height="100%"> -->
<mx:TabNavigator id="bottomTabs" width="100%" creationPolicy="all" paddingLeft="4" paddingBottom="8" backgroundColor="#D9D9D9" color="#202020" horizontalScrollPolicy="on" verticalScrollPolicy="on" resize="bottomTabsResize()">
<mx:HBox label="Text" backgroundColor="#D9D9D9" width="496" horizontalScrollPolicy="off" verticalScrollPolicy="off" >
<mx:Label text="Font:"/>
<mx:ComboBox id="fontFamily" editable="true" enter="changeFontFamily(fontFamily.text)" close="changeFontFamily(fontFamily.text)" width="200"/>
<mx:Label text="Size:"/>
<mx:TextInput id="fontSize" enter="changeFontSize(fontSize.text)" width="40"/>
<mx:Label text="LineHeight:"/>
<mx:TextInput id="lineHeight" enter="changeLeading(lineHeight.text)" width="40"/>
</mx:HBox>
<mx:HBox label="Para" backgroundColor="#D9D9D9" width="496">
<mx:Label text="Alignment:"/>
<mx:ComboBox id="textAlign" close="changeTextAlign(textAlign.selectedItem.data)" dataProvider="{textAlignData}"/>
<mx:Label text="FirstLineIdent:"/>
<mx:TextInput id="textIndent" enter="changeTextIndent(textIndent.text)" width="40"/>
</mx:HBox>
<mx:HBox label="Container" backgroundColor="#D9D9D9" width="496">
<mx:Label text="Columns:"/>
<mx:TextInput id="columnCount" toolTip="auto or a number" enter="changeColumnCount(columnCount.text)" width="40"/>
<mx:Label text="Gap:"/>
<mx:TextInput id="columnGap" toolTip="a number" enter="changeColumnGap(columnGap.text)" width="40"/>
<mx:Label text="VerticalAlignment:"/>
<mx:ComboBox id="verticalAlign" close="changeVerticalAlign(verticalAlign.selectedItem.data)" dataProvider="{verticalAlignData}"/>
</mx:HBox>
<mx:HBox label="Flow" backgroundColor="#D9D9D9" width="496">
<mx:Label text="Progression:"/>
<mx:ComboBox id="blockProgression" close="changeBlockProgression(blockProgression.selectedItem.data)" dataProvider="{blockProgressionData}"/>
<mx:Label text="Direction:"/>
<mx:ComboBox id="directionBox" close="changeDirection(directionBox.selectedItem.data)" dataProvider="{directionData}"/>
</mx:HBox>
<mx:HBox label="Version" backgroundColor="#D9D9D9" width="496">
<mx:TextInput id="versionInfo" editable="false" width="100%"/>
</mx:HBox>
<mx:HBox label="Spelling" backgroundColor="#D9D9D9" width="496">
<mx:TextInput text="en_US" id="spellLang" editable="true" width="20%"/>
<mx:Button id="spellBut" label="Enable Spelling" click="doSpell()"/>
<mx:Button id="unspellBut" label="Disable Spelling" click="undoSpell()"/>
</mx:HBox>
</mx:TabNavigator>
<mx:Canvas id="textArea" width="520" height="400"/>
<!-- </mx:VBox> -->
</mx:VBox>