SDK 4.5 (Hero)TextLayout 随记

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])
		}
	}
}

你可能感兴趣的:(UI,xml,.net,Flex,Flash)