TextLayout前沿更新:
http://sourceforge.net/projects/tlf.adobe/files_beta/latest/
1.[2010.11.6] 动手修改
TextLayout使用说明:如果采用FlashBuilder,其自身也有TextLayout
Step1:
删除SDK 下面的 frameworks\libs\textLayout.swc(不能RSL)
Step2
把frameworks\projects\textLayout\src下面的flashx和flash包复制出来放到工程下面
Step3(flex4.5)
修改flashx.textLayout.property包下的三个文件
NumberPropertyHandler.as
public function NumberPropertyHandler(minValue:Number,maxValue:Number,limits:String=null)
{
_minValue = minValue;
_maxValue = maxValue;
if(!limits){
_limits = Property.ALL_LIMITS
}else{
_limits = limits;
}
}
IntPropertyHandler.as
public function IntPropertyHandler(minValue:int,maxValue:int,limits:String=null)
{
_minValue = minValue;
_maxValue = maxValue;
if(!limits){
_limits = Property.ALL_LIMITS
}else{
_limits = limits;
}
}
PercentPropertyHandler.as
public function PercentPropertyHandler(minValue:String,maxValue:String,limits:String=null)
{
_minValue = Property.toNumberIfPercent(minValue);
_maxValue = Property.toNumberIfPercent(maxValue);
if(!limits){
_limits = Property.ALL_LIMITS
}else{
_limits = limits;
}
}
Step4
修改编译参数:
-locale en_US -define=CONFIG::debug,true -define=CONFIG::release,true
Step5 新建工程
当前工程:也要删除,但不要删除文件 1045: Interface ISWFContext was not found.
新建工程 不会出现上述错误
2. 2010-11-6
Note1.
在EditManager.as 修改inertInlineGraphicElement方法时,由于参数名一样,throwError;
// Main Thread (Suspended: VerifyError: Error #1053: Illegal override of EditManager in flashx.textLayout.edit.EditManager.)
Note2.
var highlightFormat:TextLayoutFormat = new TextLayoutFormat();
highlightFormat.backgroundColor = 0xffee66;
var keywordsArray:Array = model.keywords.toLowerCase().split(' ');
var indexOfKeyword:int = 0;
for each (var currentKeyword:String in keywordsArray) {
while((indexOfKeyword = this.text.toLowerCase().indexOf(currentKeyword, indexOfKeyword)) >= 0) {
this.setFormatOfRange(highlightFormat, indexOfKeyword, indexOfKeyword + currentKeyword.length);
indexOfKeyword++;
}
}
Note3.
var txt:RichEditableText;
var html:String = "<b>some <i>rich</i> text</b>";
var mgr:EditManager = txt.textFlow.interactionManager as EditManager;
var flow:TextFlow = TextConverter.importToFlow(html,TextConverter.TEXT_FIELD_HTML_FORMAT);
mgr.pasteTextScrap(new TextScrap(flow));
3.2010.11.09
在Richard和Robin的帮助下,完成list的创建,编辑,删除
核心代码:
package net.diding.control
{
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.text.engine.TextLine;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuBuiltInItems;
import flash.ui.ContextMenuItem;
import flash.ui.Mouse;
import flash.ui.MouseCursor;
import flashx.textLayout.compose.TextFlowLine;
import flashx.textLayout.edit.EditManager;
import flashx.textLayout.edit.EditingMode;
import flashx.textLayout.edit.IEditManager;
import flashx.textLayout.edit.SelectionState;
import flashx.textLayout.elements.FlowElement;
import flashx.textLayout.elements.FlowGroupElement;
import flashx.textLayout.elements.LinkElement;
import flashx.textLayout.elements.ListElement;
import flashx.textLayout.elements.ListItemElement;
import flashx.textLayout.elements.ParagraphElement;
import flashx.textLayout.elements.SpanElement;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.events.CompositionCompleteEvent;
import flashx.textLayout.events.FlowElementMouseEvent;
import flashx.textLayout.events.UpdateCompleteEvent;
import flashx.textLayout.formats.ListMarkerFormat;
import flashx.textLayout.formats.ListStyleType;
import flashx.textLayout.formats.TextLayoutFormat;
import mx.controls.Alert;
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import net.diding.window.UnOrderedListWindow;
import spark.components.RichEditableText;
public class ListInsertManager extends EventDispatcher
{
private var _Manager:*;
private var showDisplay:*
private var richEditableText:RichEditableText
public function ListInsertManager(target:*=null)
{
super();
_Manager=target;
//richEditableText=_Manager.textflow.flowComposer.getControllerAt(0).container as RichEditableText;
//richEditableText.addEventListener(MouseEvent.MOUSE_DOWN, ListElementHandler2)
}
/***********************************************************
************************ Set list********************
* *********************************************************/
//open the window to set or modify or remove the unordered list
private var kindStr:String;
public function doOpenListWinHandler(listElement:ListElement=null, disPlayObj:*=null):void
{
if (listElement)
{
var window:UnOrderedListWindow=UnOrderedListWindow(PopUpManager.createPopUp(_Manager, UnOrderedListWindow, true));
window.getWinFindArg(this, listElement, true)
}
else if (_Manager.selStart != _Manager.selFinish)
{
var window2:UnOrderedListWindow=UnOrderedListWindow(PopUpManager.createPopUp(_Manager, UnOrderedListWindow, true));
window2.getWinFindArg(this);
}
else
{
Alert.show("Please select the paras", "Notice")
}
}
//set or modify the list
private var watchIndex:int;
public function setOrEditList(currentListElement:ListElement=null, listformat:TextLayoutFormat=null, lmf:ListMarkerFormat=null):void
{
var em:EditManager=EditManager(_Manager.textflow.interactionManager);
if (currentListElement != null)
{
//Edit
var beginIndex:int=currentListElement.getAbsoluteStart();
watchIndex=beginIndex
//var lastIndex:int=beginIndex + currentListElement.textLength+int(currentListElement.numChildren);
//em.selectRange(beginIndex, lastIndex)
/**************************************
* here
* i want to set the list just the same as i set url ,but failed
*if the listformat-->ListStyleType.NONE
*not really remove the list
* *************************************/
// em.createList(null, listformat, lmf)
currentListElement.listStyleType=listformat.listStyleType;
currentListElement.listStylePosition=listformat.listStylePosition;
currentListElement.paddingLeft=listformat.paddingLeft
//currentListElement.listMarkerFormat=lmf;
}
else
{
//Create
em.selectRange(_Manager.selStart, _Manager.selFinish);
watchIndex=_Manager.selStart;
em.createList(null, listformat, null);
//em.createSPGE(null, listformat,null);
}
_Manager.textflow.interactionManager.setFocus();
_Manager.textflow.flowComposer.updateAllControllers()
richEditableText=_Manager.textflow.flowComposer.getControllerAt(0).container as RichEditableText;
richEditableText.addEventListener(MouseEvent.MOUSE_DOWN, ListElementHandler)
}
/***************************************************
* ----I want to get the list that I clicked ,but failed-----
* here I want to get the list to modify or remove when i click the list,but
* when i click it in the list, always I get FlowGroupElement's numChildren is one;
* outside ,i will see the list and its numchilren. Why?
* **************************************************/
private var flowGropElement:FlowGroupElement;
private var currentListIdx:int;
private function ListElementHandler2(event:MouseEvent):void
{
trace("event.target===" + event.target)
trace("richEditableText---" + richEditableText.textFlow.numChildren)
trace("richEditableText's parent flowgroupElement---" + richEditableText.textFlow.parent)
var textflowNum:int=richEditableText.textFlow.numChildren
for (var i:int=0; i < textflowNum; i++)
{
trace(richEditableText.textFlow.getChildAt(i));
var flowElement:*=richEditableText.textFlow.getChildAt(i);
if (flowElement is ListElement)
{
currentListIdx=i;
var clickedList:ListElement=flowElement as ListElement;
trace("listElement's child==" + clickedList.numChildren)
//each sign as a char
trace("listElement's length==" + clickedList.textLength + int(clickedList.numChildren))
var absIndex:int=clickedList.getAbsoluteStart();
//var total:int=absIndex + clickedList.textLength + int(clickedList.numChildren)
var total:int=absIndex + clickedList.textLength
if (_Manager.selStart < total && _Manager.selStart > absIndex)
{
doOpenListWinHandler(clickedList, null)
trace("cliked me")
break;
}
}
}
}
private function ListElementHandler(event:MouseEvent):void
{
trace("event.target===" + event.target)
var textLine:TextLine=event.target as TextLine;
if (textLine)
{
trace("textLine.parent==" + textLine.parent) //textDisplay
if (textLine.userData)
{
var textFlowLine:TextFlowLine=textLine.userData as TextFlowLine;
if (textFlowLine)
{
var paraElement:ParagraphElement=textFlowLine.paragraph as ParagraphElement;
}
if (paraElement)
{
//The FlowGroupElement class is the base class for
//FlowElement objects
//that can have an array of children.
//These classes include
//TextFlow, ParagraphElement, DivElement, and LinkElement
flowGropElement=paraElement.parent as FlowGroupElement;
}
if (flowGropElement)
{
trace("flowGropElement numChildren==" + flowGropElement.numChildren)
var fgeChildNum:Number=flowGropElement.numChildren;
//currentfgeIdx=flowGropElement.getAbsoluteStart();
if (fgeChildNum == 1)
{
var tflow:ListElement=flowGropElement.getChildAt(0)as ListElement
/*
*The List class is used for grouping together items into a numbered
or unnumbered list. A ListElement's children may be of
type ListItemElement, ListElement, ParagraphElement,
or DivElement.
*/
trace("richEditableText---" + richEditableText.textFlow.numChildren)
trace("richEditableText's parent flowgroupElement---" + richEditableText.textFlow.parent)
var textflowNum:int=richEditableText.textFlow.numChildren
for (var i:int=0; i < textflowNum; i++)
{
trace(richEditableText.textFlow.getChildAt(i));
var flowElement:*=richEditableText.textFlow.getChildAt(i);
if (flowElement is ListElement)
{
currentListIdx=i;
var clickedList:ListElement=flowElement as ListElement;
trace("listElement's child==" + clickedList.numChildren)
//each sign as a char
trace("listElement's length==" + clickedList.textLength + int(clickedList.numChildren))
var absIndex:int=clickedList.getAbsoluteStart();
//var total:int=absIndex + clickedList.textLength + int(clickedList.numChildren)
var total:int=absIndex + clickedList.textLength
//is click listElement?
//maybe there are many listelements in it
if (_Manager.selStart < total && _Manager.selStart > absIndex)
{
//var em:IEditManager=IEditManager(_Manager.textflow.interactionManager);
//em.selectRange(absIndex,total)
doOpenListWinHandler(clickedList, null)
trace("cliked me")
break;
}
}
}
}
}
}
}
}
//private var flowGropElement:FlowGroupElement;
//private var currentListIdx:int;
//remove
public function delList(currentListElement:ListElement):void
{
var em:IEditManager=IEditManager(_Manager.textflow.interactionManager);
trace(currentListElement.numChildren);
var target:FlowGroupElement=currentListElement.parent;
var targetIndex:int=target.getChildIndex(currentListElement);
em.moveChildren(currentListElement, 0, currentListElement.numChildren, target, targetIndex);
}
}
}
4.2010.11.12.
Ige由于采用loop方式,效果不好,最终决定采用bmpd方式,
原来的方式:
richEditableText.addEventListener(MouseEvent.CLICK, imageClickHandlers);
private function imageClickHandlers(event:MouseEvent):void
{
var hitrect:Rectangle
var mouseX:Number=richEditableText.mouseX;
var mouseY:Number=richEditableText.mouseY;
var point:Point=new Point(mouseX, mouseY);
var isClickImg:Boolean=false;
var sendImg:InlineGraphicElement;
trace("_images.length===" + _images.length)
for (var i:uint=0; i < _images.length; i++)
{
var rect:Rectangle=_images[i].graphic.getBounds(richEditableText);
if (rect.contains(point.x, point.y))
{
var currentILG:InlineGraphicElement=_images[i]as InlineGraphicElement;
var absIndex:int=currentILG.getAbsoluteStart();
var between:int=absIndex + currentILG.textLength;
if (_Manager.selStart < between)
{
//编辑用
clickInlineGripicElement=currentILG;
isClickImg=true;
sendImg=currentILG;
break;
}
}
}
trace("是否点了图片====" + isClickImg)
if (isClickImg)
{
//放在后面将不能编辑图片
CMDManageImageClick(sendImg);
//switchToEditingMode(EditingMode.READ_ONLY);
isClickImg=false
}
else
{
if (imgMoveSacaleController)
imgMoveSacaleController.removePositionSelector();
}
}
//----------------------------------------------------------------------
private function CMDManageImageClick(getILG:InlineGraphicElement):void
{
//var em:EditManager=EditManager(_Manager._textFlow.interactionManager)
trace(_Manager.editingModeString)
//&&(em.editingMode=="readOnly")
if (getILG is InlineGraphicElement)
{
isBegin=_Manager.selStart;
isLast=_Manager.selFinish;
trace("isBegin" + isBegin)
trace("isBegin" + isLast)
if (isBegin == isLast)
//if (isBegin - isLast == -1 || isLast - isBegin == 1)
{
nowSelecting=true;
isBeginEditImage=true;
imgMoveSacaleController.AddManagerObject(getILG)
}
else
{
isBeginEditImage=false;
Alert.show("请选择图片");
//myImageClickManager.showMouse()
}
}
}
//图片的编辑,移动都能可视化操作,(两种界面)
//由于点击触发点的问题,改用DisplayObect,这样只能修改TLF 源代码
//侦听器放在前面
_Manager._textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, graphicStatusChangeEvent2);
EditManager(_Manager._textFlow.interactionManager).insertInlineGraphic(displayContainerSprite, _imageWidth, _imageHeight, "left",_path,"image", null)
//倒数两个参数为自定义的,主要是确定插入的是shape/image/swf/table,如果播入的image,则_path不能为空
_Manager._textFlow.flowComposer.updateAllControllers();
//export的xml
<TextFlow whiteSpaceCollapse="preserve"
version="2.0.0"
xmlns="http://ns.adobe.com/textLayout/2008">
<p>
<span>adds</span>
</p>
<p>
<span>adds</span>
<img height="60"
width="60"
source="http://127.0.0.1/companywebsite/php/images/Winter.jpg"
float="none"
objectKind="image"
objectUrl=""/>
<span>adddddddssssssssss</span>
</p>
<p>Flex is a free, open source framework for building highly interactive, expressive web applications that dep</p>
<p>Flex framework</p>
<p>Flex framework</p>
<p>I am a new paragraph and I'd like to start at the left below the image</p>
<p>
<span>adds</span>
<img height="70"
width="70"
source="[object DisplayContainerSprite]"
float="left"
objectKind="image"
objectUrl="http://127.0.0.1/companywebsite/php/images/Winter.jpg"/>
<span>adddddddssssssssss</span>
</p>
<p>
<span>adds</span>
<img height="121"
width="121"
source="[object DisplayContainerSprite]"
float="left"
objectKind="image"
objectUrl="http://127.0.0.1/companywebsite/php/images/ld.png"/>
<span>dsddsdsdsdssd</span>
</p>
</TextFlow>
要修改内容:IEditManager,EditManager, TextLayoutExporter, TextLayoutImporter, InsertInlineGraphicOperation, ParaEdit等
由于采用嵌入的方式处理图片
所以,需要从数据库或xml读取,预处理object的图片,之前遇到一个异步问题:
http://bbs.airia.cn/thread-43376-1-2.html
//发了帖,用Timer,效果不好,最终采用预处理textflowXML
//加载的xml文件,改用XMLDoc来处理’
private var textflow_xml:XML;
private function completeHandlerM(event:Event):void
{
//trace("loadKind===="+loadKind)
var myLoader:URLLoader=URLLoader(event.target);
textflow_xml=XML(myLoader.data);
var listStr:String=textflow_xml.toXMLString();
var result:XMLDocument=new XMLDocument();
result.ignoreWhite=true;
result.parseXML(listStr);
trace("总共==" + result.childNodes.length)
var textflow:XMLNode=result.childNodes[0];
trace("textflow的字节点== " + textflow.childNodes.length)
for (var j:int=0; j < textflow.childNodes.length; j++)
{
var tempXMLNode:XMLNode=textflow.childNodes[j];
doCheckNodes(tempXMLNode)
}
doLoadingImageAssetsFromDocInfo()
}
private var imgArr:Array=[];
private function doCheckNodes(getxmlNode:XMLNode):void
{
trace(getxmlNode)
trace("传过来的长度===" + getxmlNode.childNodes.length)
if (getxmlNode.childNodes.length < 2)
{
var xmlNodeName:String=getxmlNode.nodeName;
trace("len==1==" + xmlNodeName);
if (xmlNodeName == "img")
{
trace("图像值===" + Object(getxmlNode.attributes).source);
if (Object(getxmlNode.attributes).source == "[object DisplayContainerSprite]")
{
var tempObj:Object=new Object();
tempObj.type=Object(getxmlNode.attributes).objectKind;
tempObj.width=Object(getxmlNode.attributes).width
tempObj.height=Object(getxmlNode.attributes).height
tempObj.path=Object(getxmlNode.attributes).objectUrl
imgArr.push(tempObj)
}
}
}
if (getxmlNode.childNodes.length > 1)
{
for (var i:int=0; i < getxmlNode.childNodes.length; i++)
{
doCheckNodes(getxmlNode.childNodes[i])
}
}
}