You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by bi...@apache.org on 2014/08/23 10:48:22 UTC

svn commit: r1619987 [21/22] - in /flex/site/trunk/content/tourdeflex: ./ mx/ mx/charts/ mx/containers/ mx/containers/assets/ mx/controls/ mx/controls/assets/ mx/core/ mx/effects/ mx/effects/assets/ mx/formatters/ mx/printing/ mx/states/ mx/validators/...

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarker.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarker.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarker.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarker.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,98 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+	
+	public class ParagraphPropertyMarker extends RulerMarker
+	{
+		public function ParagraphPropertyMarker(inRuler:RulerBar, inProperty:String)
+		{
+			super(inRuler, 6, 13, 0, 0, 0);
+			setStyle("propkind", inProperty);
+			setStyle("rightToLeftPar", false);
+			mProperty = inProperty;
+		}
+		
+		public function get property():String
+		{
+			return mProperty;
+		}
+		
+		override protected function get alignToRight():Boolean
+		{
+			switch(mProperty)
+			{
+			case TextLayoutFormat.textIndentProperty.name:
+				return mRightToLeftPar ? true : false;
+			case TextLayoutFormat.paragraphStartIndentProperty.name:
+				return mRightToLeftPar;
+			case TextLayoutFormat.paragraphEndIndentProperty.name:
+				return !mRightToLeftPar;
+			}
+			return false;
+		}
+		
+		override protected function get originPosition():Number
+		{
+			return mRelativeToPosition;
+		}
+
+		public function set relativeToPosition(inRelPos:Number):void
+		{
+			mRelativeToPosition = inRelPos;
+			positionMarker();
+		}
+		
+		override public function get hOffset():Number
+		{
+			switch(mProperty)
+			{
+			case TextLayoutFormat.textIndentProperty.name:
+				return mRightToLeftPar ? -6 : 0;
+			case TextLayoutFormat.paragraphStartIndentProperty.name:
+				return mRightToLeftPar ? -6 : 0;
+			case TextLayoutFormat.paragraphEndIndentProperty.name:
+				return mRightToLeftPar ? 0 : -6;
+			}
+			return 0;
+		}
+		
+		public function set rightToLeftPar(inRightToLeft:Boolean):void
+		{
+			if (inRightToLeft != mRightToLeftPar)
+			{
+				mRightToLeftPar = inRightToLeft;
+				setStyle("rightToLeftPar", mRightToLeftPar);
+				
+				if (mProperty == TextLayoutFormat.paragraphStartIndentProperty.name)
+					mProperty = TextLayoutFormat.paragraphEndIndentProperty.name;
+				else if (mProperty == TextLayoutFormat.paragraphEndIndentProperty.name)
+					mProperty = TextLayoutFormat.paragraphStartIndentProperty.name;
+			}
+		}
+		
+		private var mProperty:String;
+		private var mRelativeToPosition:Number = 0;
+		private var mRightToLeftPar:Boolean = false;
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarker.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarkerSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarkerSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarkerSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarkerSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,103 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import mx.skins.RectangularBorder;
+
+	public class ParagraphPropertyMarkerSkin extends RectangularBorder
+	{
+		public function ParagraphPropertyMarkerSkin()
+		{
+			super();
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+		    super.updateDisplayList(w, h);
+		    
+		    var propKind:String = getStyle("propkind");
+		    var rightToLeftPar:Boolean = getStyle("rightToLeftPar");
+		    
+		    var t:Number = 0;
+		    var b:Number = h;
+		    
+			graphics.clear();
+
+			graphics.beginFill(0x000000);
+			if (rightToLeftPar)
+			{
+				switch(propKind) {
+				case "textIndent":
+					b = (h - 1) / 2;
+					graphics.moveTo(w, 0);
+					graphics.lineTo(w, b);
+					graphics.lineTo(0, b);
+					graphics.lineTo(w, 0);
+					break;
+				case "paragraphStartIndent":
+					graphics.moveTo(0, 0);
+					graphics.lineTo(0, h);
+					graphics.lineTo(w, h / 2);
+					graphics.lineTo(0, 0);
+					break;
+				case "paragraphEndIndent":
+					t = h - (h - 1) / 2;
+					graphics.moveTo(w, h);
+					graphics.lineTo(0, t);
+					graphics.lineTo(w, t);
+					graphics.lineTo(w, h);
+					break;
+				}
+			}
+			else
+			{
+				switch(propKind) {
+				case "textIndent":
+					b = (h - 1) / 2;
+					graphics.moveTo(0, 0);
+					graphics.lineTo(w, b);
+					graphics.lineTo(0, b);
+					graphics.lineTo(0, 0);
+					break;
+				case "paragraphStartIndent":
+					t = h - (h - 1) / 2;
+					graphics.moveTo(0, h);
+					graphics.lineTo(0, t);
+					graphics.lineTo(w, t);
+					graphics.lineTo(0, h);
+					break;
+				case "paragraphEndIndent":
+					graphics.moveTo(w, 0);
+					graphics.lineTo(w, h);
+					graphics.lineTo(0, h / 2);
+					graphics.lineTo(w, 0);
+					break;
+				}
+			}
+			graphics.endFill();
+			
+			// this makes the whole rect hittable
+	  		graphics.lineStyle();
+	    	graphics.beginFill(0x0000ff, 0);
+	    	graphics.drawRect(0, t, w, b);
+	    	graphics.endFill();
+		}
+	}
+}

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/ParagraphPropertyMarkerSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerBar.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerBar.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerBar.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerBar.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,672 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import bxf.ui.inspectors.DynamicPropertyEditorBase;
+	
+	import flash.display.DisplayObject;
+	import flash.display.GradientType;
+	import flash.events.MouseEvent;
+	import flash.geom.Matrix;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TabAlignment;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.edit.EditManager;
+	import flashx.textLayout.edit.ElementRange;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.events.SelectionEvent;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.ITabStopFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TabStopFormat;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.ui.inspectors.TabPropertyEditor;
+	import flashx.textLayout.ui.inspectors.TextInspectorController;
+	
+	import mx.containers.Canvas;
+	import mx.core.ScrollPolicy;
+	import mx.core.UIComponent;
+	import mx.events.PropertyChangeEvent;
+	import mx.events.ResizeEvent;
+	use namespace tlf_internal;
+	
+	public class RulerBar extends Canvas
+	{
+		public static const RULER_HORIZONTAL:String = "horizontal";
+		public static const RULER_VERTICAL:String = "vertical";
+		
+		public function RulerBar()
+		{
+			super();
+			horizontalScrollPolicy = ScrollPolicy.OFF;
+			verticalScrollPolicy = ScrollPolicy.OFF;
+			mDefaultTabStop = new TabStopFormat(TabStopFormat.defaultFormat);
+			addEventListener(MouseEvent.MOUSE_DOWN, onRulerMouseDown);
+			selectMarker(null);
+			TextInspectorController.Instance().AddRuler(this);
+			curParagraphFormat = null;
+		}
+		
+		override public function initialize():void
+		{
+			super.initialize();
+			adjustForActive();
+		}
+		
+		public function creationComplete():void
+		{
+			if (mSyncToPanel)
+			{
+				mSyncToPanel.addEventListener(ResizeEvent.RESIZE, onSyncPanelResize);
+			}
+			SyncRulerToPanel();
+			mIndentMarker = addParagraphPropertyMarker(TextLayoutFormat.textIndentProperty.name);
+			mLeftMarginMarker = addParagraphPropertyMarker(TextLayoutFormat.paragraphStartIndentProperty.name);
+			mRightMarginMarker = addParagraphPropertyMarker(TextLayoutFormat.paragraphEndIndentProperty.name);
+		}
+		
+ 		public function set activeFlow(inFlow:TextFlow):void
+		{
+			if (inFlow && !inFlow.interactionManager is EditManager)
+				throw new Error("Can't set the active flow to a flow without an EditManager.");
+			if (mActiveFlow)
+			{
+				mActiveFlow.removeEventListener(SelectionEvent.SELECTION_CHANGE, onTextSelectionChanged);
+				mEditManager = null;
+			}
+			mActiveFlow = inFlow;
+			mLastSelActiveIdx = -1;
+			mLastSelAnchorIdx = -1;
+			mTabSet = null;
+			RemoveTabMarkers();
+			selectMarker(null);
+			
+			if (mActiveFlow)
+			{
+				mEditManager = mActiveFlow.interactionManager as EditManager;
+				mActiveFlow.addEventListener(SelectionEvent.SELECTION_CHANGE, onTextSelectionChanged);
+			}
+			else
+				onTextSelectionChanged(null);
+		}
+		
+		public function get activeFlow():TextFlow
+		{
+			return mActiveFlow;
+		}
+		
+		public function set active(inActive:Boolean):void
+		{
+			mActive = inActive;
+			selectMarker(null);
+			adjustForActive();
+		}
+		
+		public function get active():Boolean
+		{
+			return mActive;
+		}
+
+		private function set rightRuler(inActive:Boolean):void
+		{
+			mRightRuler = inActive;
+			adjustForActive();
+		}
+		
+		private function get rightRuler():Boolean
+		{
+			return mRightRuler;
+		}
+		
+		private function adjustForActive():void
+		{
+			if (parent)
+			{
+				if (mActive && mRightRuler)
+				{
+					parent.visible = true;
+					if (parent is Canvas)
+						(parent as Canvas).includeInLayout = true;
+				}
+				else
+				{
+					parent.visible = false;
+					if (parent is Canvas)
+						(parent as Canvas).includeInLayout = false;
+				}
+			}
+		}
+		
+		public function set orientation(inOrientation:String):void
+		{
+			if (inOrientation != mOrientation && (inOrientation == RULER_HORIZONTAL || inOrientation == RULER_VERTICAL))
+			{
+				mOrientation = inOrientation;
+			}
+		}
+		
+		public function set syncToPanel(inPanel:UIComponent):void
+		{
+			mSyncToPanel = inPanel;
+		}
+		
+		public function set tabPropertyEditor(inEditor:TabPropertyEditor):void
+		{
+			mPropertyEditor = inEditor;
+			mPropertyEditor.addEventListener(DynamicPropertyEditorBase.MODELCHANGED_EVENT, onFormatValueChanged, false, 0, true);
+			mPropertyEditor.addEventListener(DynamicPropertyEditorBase.MODELEDITED_EVENT, onFormatValueChanged, false, 0, true);
+			selectMarker(mSelectedMarker);
+		}
+		
+ 		private function onSyncPanelResize(evt:ResizeEvent):void
+ 		{
+ 			RedrawRuler();
+ 		}
+ 		
+ 		public function RedrawRuler():void
+ 		{
+ 			SyncRulerToPanel();
+ 			if (curParagraphFormat != null) {
+ 				ShowTabs(curParagraphFormat);
+ 			} 			
+ 		}
+
+  		private function SyncRulerToPanel():void
+ 		{
+ 			if (mActiveFlow && mActiveFlow.flowComposer && rightRuler)
+ 			{
+ 				var selStart:int = Math.min(mActiveFlow.interactionManager.activePosition, mActiveFlow.interactionManager.anchorPosition);
+ 				var line:TextFlowLine = selStart != -1 ? mActiveFlow.flowComposer.findLineAtPosition(selStart) : null;
+ 				if (line)
+ 				{
+ 					var controller:ContainerController;
+ 					var containerDO:DisplayObject;
+ 					if (line.controller)
+ 					{
+ 						controller = line.controller;
+ 						containerDO = controller.container as DisplayObject;
+ 					}
+ 					else
+ 					{
+ 						// get the last container
+ 						controller = mActiveFlow.flowComposer.getControllerAt(mActiveFlow.flowComposer.numControllers-1);
+ 						containerDO = controller.container as DisplayObject;
+ 					}
+ 					var localOrigin:Point = parent.globalToLocal(containerDO.parent.localToGlobal(new Point(containerDO.x, containerDO.y)));
+	 				var columnBounds:Rectangle;
+	 				var columnIndex:int = line.columnIndex;
+	 				if (columnIndex == -1)
+	 					columnBounds = controller.columnState.getColumnAt(controller.columnState.columnCount - 1);
+	 				else
+	 				{
+	 					// columnIndex is an index into all the columns in the flow, so to get the actual
+	 					// column bounds 
+	 					var idx:int = 0;
+	 					var ch:ContainerController = mActiveFlow.flowComposer.getControllerAt(idx);
+	 					while (ch && ch != controller)
+	 					{
+	 						columnIndex -= ch.columnState.columnCount;
+	 						idx++;
+ 							ch = idx == mActiveFlow.flowComposer.numControllers ? null : mActiveFlow.flowComposer.getControllerAt(idx);
+	 					}
+	 					// Pin the column number to the actual range of column indices. I have found this
+	 					// is needed when the insertion point is inside a table (because the line's container
+	 					// is not in the flow's list of containers) or when the insertion point is in regular
+	 					// text after a table (the column number doesn't make sense, and I think it's a bug, which
+	 					// I have written to Robin about.
+	 					columnIndex = Math.max(0, Math.min(line.columnIndex, controller.columnState.columnCount - 1));
+	 					columnBounds = controller.columnState.getColumnAt(columnIndex);
+	 				}
+	 				
+		 			if (columnBounds)
+		 			{
+			 			if (mOrientation == RULER_HORIZONTAL)
+			 			{
+			 				x = localOrigin.x + columnBounds.x;
+			 				y = 0;
+			 				height = parent.height;
+				 			width = columnBounds.width;
+			 			}
+			 			else
+			 			{
+			 				x = parent.width;
+			 				y = localOrigin.y + columnBounds.y;
+			 				rotation = 90;
+			   				height = parent.width;
+							width = columnBounds.height;
+						}
+		 			}
+	 			}
+ 			}
+ 		}
+
+		private function onTextSelectionChanged(e:SelectionEvent):void
+		{
+			curParagraphFormat = null;
+			if (mEditManager && (mEditManager.activePosition != mLastSelActiveIdx || mEditManager.anchorPosition != mLastSelAnchorIdx))
+			{
+				mLastSelActiveIdx = mActiveFlow.interactionManager.activePosition;
+				mLastSelAnchorIdx = mActiveFlow.interactionManager.anchorPosition;
+				selectMarker(null);
+			}
+			if (e)
+			{
+				var selState:SelectionState = e.selectionState;
+				var selectedElementRange:ElementRange =  selState ? ElementRange.createElementRange(selState.textFlow, selState.absoluteStart, selState.absoluteEnd) : null;
+				if (selectedElementRange)
+				{
+		 			var rootElement:ContainerFormattedElement = selectedElementRange.firstLeaf.getAncestorWithContainer();
+		 			if ((rootElement.computedFormat.blockProgression == BlockProgression.RL) == (mOrientation == RULER_VERTICAL))
+		 			{
+		 				// should be active
+		 				if (rightRuler != true)
+		 				{
+		 					mTabSet = null;
+		 				}
+		 				if (!rightRuler)
+		 					rightRuler = true;
+		 			}
+		 			else
+		 			{
+		 				// should be inactive
+		 				if (rightRuler != false)
+		 				{
+		 					mTabSet = null;
+		 				}
+		 				if (rightRuler)
+		 					rightRuler = false;
+		 			}
+					
+	  				curParagraphFormat = new TextLayoutFormat(selectedElementRange.firstParagraph.computedFormat);
+	  				setRightToLeft(curParagraphFormat.direction == flashx.textLayout.formats.Direction.RTL);					
+					ShowTabs(curParagraphFormat);
+				}
+				else
+					ShowTabs(null);
+			}
+			else
+				ShowTabs(null);
+		}
+		
+		
+		private function RemoveTabMarkers():void
+		{
+			var markers:Array = getChildren();
+			for each (var marker:UIComponent in markers)
+				if (marker is TabMarker)
+					this.removeChild(marker);
+		}
+		
+		
+		private function ShowTabs(inFormat:ITextLayoutFormat):void
+		{
+			SyncRulerToPanel();
+			var tabs:Array = inFormat ? ((inFormat.tabStops && (inFormat.tabStops.length > 0)) ? inFormat.tabStops as Array : null) : null;
+			if (isNewTabSet(tabs))
+			{
+				mTabSet = tabs;
+				if (mUpdateFromSelection)
+				{
+					RemoveTabMarkers();
+					var oldSel:RulerMarker = mSelectedMarker;
+					selectMarker(null);
+					if (mTabSet)
+						for each(var tab:TabStopFormat in mTabSet)
+						{
+							var tabMarker:TabMarker = addTabMarker(tab);
+							if (oldSel && oldSel.pos == tabMarker.pos)
+								selectMarker(tabMarker);
+						}
+				}
+			}
+			if (inFormat)
+			{
+				if(mIndentMarker)
+				{
+					mIndentMarker.rightToLeftPar = mRightToLeft;
+					mIndentMarker.pos = Number(inFormat.textIndent);
+					mIndentMarker.relativeToPosition = inFormat.paragraphStartIndent;
+				}
+				
+				if(mLeftMarginMarker)
+				{
+					mLeftMarginMarker.rightToLeftPar = mRightToLeft;
+					mLeftMarginMarker.pos = rightToLeft ? Number(inFormat.paragraphEndIndent): Number(inFormat.paragraphStartIndent);
+				}
+				
+				if(mRightMarginMarker)
+				{
+					mRightMarginMarker.rightToLeftPar = mRightToLeft;
+					mRightMarginMarker.pos = rightToLeft ? Number(inFormat.paragraphStartIndent): Number(inFormat.paragraphEndIndent);
+				}
+			}
+		}
+		
+		
+		private function addTabMarker(tabAttrs:ITabStopFormat):TabMarker
+		{
+			var tabMarker:TabMarker = new TabMarker(this, tabAttrs);
+			tabMarker.addEventListener(MouseEvent.MOUSE_DOWN, onMarkerMouseDown);
+			addChild(tabMarker);
+			return tabMarker;
+		}
+		
+		
+		private function addParagraphPropertyMarker(inProperty:String):ParagraphPropertyMarker
+		{
+			var propMarker:ParagraphPropertyMarker = new ParagraphPropertyMarker(this, inProperty);
+			propMarker.addEventListener(MouseEvent.MOUSE_DOWN, onMarkerMouseDown);
+			addChild(propMarker);
+			return propMarker;
+		}
+		
+		
+		private function isNewTabSet(inTabs:Array):Boolean
+		{
+			if (inTabs == mTabSet)
+				return false;
+			if ((inTabs == null) != (mTabSet == null))
+				return true;
+			if (inTabs)
+			{
+				if (inTabs.length == mTabSet.length)
+				{
+					var n:int = inTabs.length;
+					for (var i:int = 0; i < n; ++i)
+					{
+						if (inTabs[i] != mTabSet[i])
+							return true;
+					}
+					return false;
+				}
+				else
+					return true;
+			}
+			return false;
+		}
+
+
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+		    super.updateDisplayList(w, h);
+		    
+			graphics.clear();
+			var m:Matrix = new Matrix();
+			m.createGradientBox(height, height, Math.PI / 2);
+			graphics.beginGradientFill(GradientType.LINEAR, [0xffffff, 0xe0e0e0], [1, 1], [0, 255], m);
+			graphics.drawRect(0, 0, w, h);
+			graphics.endFill();
+			
+			graphics.lineStyle(1, 0x404040, 1.0, true);
+			for (var x:int = 0; x < w; x += 10)
+			{
+				var rulerX:Number = rightToLeft ? w - x - 1 : x;
+				if (x % 100 == 0)
+					graphics.moveTo(rulerX, 12);
+				else if (x % 50 == 0)
+					graphics.moveTo(rulerX, 9);
+				else
+					graphics.moveTo(rulerX, 5);
+				graphics.lineTo(rulerX, 0);
+			}
+		}
+		
+		private function onMarkerMouseDown(e:MouseEvent):void
+		{
+			if (mEditManager)
+			{
+				var cookie:Object;
+				if (e.target is TabMarker)
+				{
+					var tabMarker:TabMarker = e.target as TabMarker;
+					selectMarker(tabMarker);
+					e.stopPropagation();
+					cookie = new Object();
+					cookie["marker"] = tabMarker;
+					cookie["offset"] = e.localX;
+					cookie["onRuler"] = true;
+					mUpdateFromSelection = false;
+					new RulerDragTracker(this.parentApplication as UIComponent, this, cookie).BeginTracking(e, false);
+				}
+				else if (e.target is ParagraphPropertyMarker)
+				{
+					var propMarker:ParagraphPropertyMarker = e.target as ParagraphPropertyMarker;
+					selectMarker(null);
+					e.stopPropagation();
+					cookie = new Object();
+					cookie["marker"] = propMarker;
+					cookie["offset"] = e.localX;
+					new RulerDragTracker(this.parentApplication as UIComponent, this, cookie).BeginTracking(e, false);
+				}
+			}
+		}
+		
+		private function onRulerMouseDown(e:MouseEvent):void
+		{
+			if (e.target is RulerBar && mEditManager)
+			{
+				var tabMarker:TabMarker = addTabMarker(mDefaultTabStop);
+				tabMarker.markerLeft = e.localX + tabMarker.hOffset;
+				selectMarker(tabMarker);
+				mUpdateFromSelection = false;
+				setFormatFromRuler();
+				e.stopPropagation();
+				var cookie:Object = new Object();
+				cookie["marker"] = tabMarker;
+				cookie["offset"] = -tabMarker.hOffset;
+				cookie["onRuler"] = true;
+				new RulerDragTracker(this.parentApplication as UIComponent, this, cookie, 0).BeginTracking(e, false);
+			}
+		}
+		
+		public function TrackDrag(inCurPos:Point, inCookie:Object, inCommit:Boolean):void
+		{
+			if (inCookie)
+			{
+				if (inCookie["marker"] is TabMarker)
+				{
+					var tabMarker:TabMarker = inCookie["marker"] as TabMarker;
+					var wasOnRuler:Boolean = inCookie["onRuler"];
+					if (inCookie["onRuler"] && inCurPos.y > height + 16)
+					{
+						inCookie["onRuler"] = false;
+						removeChild(tabMarker);
+						selectMarker(null);
+					}
+					else if (!inCookie["onRuler"] && inCurPos.y <= height + 16)
+					{
+						inCookie["onRuler"] = true;
+						addChild(tabMarker);
+						selectMarker(tabMarker);
+					}
+					
+					tabMarker.markerLeft = inCurPos.x - inCookie["offset"];
+					if (wasOnRuler || inCookie["onRuler"])
+						setFormatFromRuler();
+				}
+				else if (inCookie["marker"] is ParagraphPropertyMarker)
+				{
+					var propMarker:ParagraphPropertyMarker = inCookie["marker"] as ParagraphPropertyMarker;
+					propMarker.markerLeft = inCurPos.x - inCookie["offset"];
+					var pa:TextLayoutFormat = new TextLayoutFormat();
+					pa[propMarker.property] = propMarker.pos;
+					mEditManager.applyParagraphFormat(pa);
+				}
+			}
+			if (inCommit)
+				mUpdateFromSelection = true;
+		}
+		
+		public function DragCancelled():void
+		{
+			mUpdateFromSelection = true;
+		}
+
+		private function selectMarker(inMarker:RulerMarker):void
+		{
+			if (mSelectedMarker)
+				mSelectedMarker.setStyle("selected", false);
+			mSelectedMarker = inMarker;
+			if (mSelectedMarker)
+				mSelectedMarker.setStyle("selected", true);
+			updatePropertyEditor();
+		}
+		
+		private function updatePropertyEditor():void
+		{
+			if (mRightRuler && mPropertyEditor && mTabPanelActive)
+			{
+				mPropertyEditor.reset();
+				mPropertyEditor.properties["rulervisible"] = TextInspectorController.Instance().rulerVisible;
+				if (TextInspectorController.Instance().rulerVisible)
+				{
+					var tab:ITabStopFormat = mSelectedMarker as ITabStopFormat;
+					if (!tab)
+						tab = mDefaultTabStop as ITabStopFormat;
+					if (tab)
+					{
+						mPropertyEditor.properties["alignment"] = tab.alignment;
+						if (tab != mDefaultTabStop)
+							mPropertyEditor.properties["position"] = tab.position;
+						if (tab.alignment == flash.text.engine.TabAlignment.DECIMAL)
+							mPropertyEditor.properties["decimalAlignmentToken"] = tab.decimalAlignmentToken;
+					}
+				}
+				mPropertyEditor.rebuildUI();
+			}
+		}
+		
+		private function onFormatValueChanged(e:PropertyChangeEvent):void
+		{
+			if (mRightRuler)
+			{
+				var property:String = e.property as String;
+				if (property == "rulervisible")
+					TextInspectorController.Instance().rulerVisible = (e.newValue == "true" ? true : false);
+				else
+				{
+					if (e.type == DynamicPropertyEditorBase.MODELEDITED_EVENT)
+						mUpdateFromSelection = false;
+					var tab:Object = mSelectedMarker;
+					if (!tab)
+						tab = mDefaultTabStop;
+					var newValue:Object = e.newValue;
+					if (property == "position")
+						newValue = Number(newValue);
+					tab[property] = newValue;
+					if (property == "alignment" && newValue == flash.text.engine.TabAlignment.DECIMAL && tab["decimalAlignmentToken"] == null)
+						tab["decimalAlignmentToken"] = "";
+					if (mSelectedMarker)
+						setFormatFromRuler();
+					if (e.type == DynamicPropertyEditorBase.MODELCHANGED_EVENT)
+						mUpdateFromSelection = true;
+					updatePropertyEditor();
+				}
+			}
+		}
+
+		private function setFormatFromRuler():void
+		{
+			var newTabs:Array = [];
+			if (mSelectedMarker && mSelectedMarker.parent)
+				newTabs.push(new TabStopFormat(mSelectedMarker as ITabStopFormat));
+			var markers:Array = getChildren();
+			for each (var marker:UIComponent in markers)
+				if (marker is TabMarker)
+				{
+					var tab:TabMarker = marker as TabMarker;
+					if (isUniquePosition(newTabs, tab.pos))
+						newTabs.push(new TabStopFormat(tab));
+					
+				}
+			newTabs.sortOn("position", Array.NUMERIC);
+			var pa:TextLayoutFormat = new TextLayoutFormat();
+			pa.tabStops = newTabs;
+			mEditManager.applyParagraphFormat(pa);
+			updatePropertyEditor();
+		}
+		
+		private static function isUniquePosition(inTabFormat:Array, inNewPosition:Number):Boolean
+		{
+			for each (var tab:TabStopFormat in inTabFormat)
+				if (tab.position == inNewPosition)
+					return false;
+			return true;
+		}
+
+		public function set tabPanelActive(inActive:Boolean):void
+		{
+			if (mTabPanelActive != inActive)
+			{
+				mTabPanelActive = inActive;
+				if (mTabPanelActive)
+					updatePropertyEditor();
+			}
+		}
+		
+		public function get tabPanelActive():Boolean
+		{
+			return mTabPanelActive;
+		}
+		
+		public function get rightToLeft():Boolean
+		{
+			return mRightToLeft;
+		}
+		
+		private function setRightToLeft(inRTL:Boolean):void
+		{
+			if (inRTL != mRightToLeft)
+			{
+				mTabSet = null;
+				mRightToLeft = inRTL;
+				invalidateDisplayList();
+			}
+		}
+		
+		private var mActive:Boolean = true;
+		private var mActiveFlow:TextFlow = null;
+		private var mEditManager:EditManager = null;
+		private var mTabSet:Array = null;
+		private var mSelectedMarker:RulerMarker = null;
+		private var mUpdateFromSelection:Boolean = true;
+		private var mDefaultTabStop:TabStopFormat;
+		private var mPropertyEditor:TabPropertyEditor = null;
+		private var mOrientation:String = RULER_HORIZONTAL;
+		private var mSyncToPanel:UIComponent = null;
+		private var mRightRuler:Boolean = true;
+		private var mLastSelAnchorIdx:int = -1;
+		private var mLastSelActiveIdx:int = -1;
+		private var mIndentMarker:ParagraphPropertyMarker = null;
+		private var mLeftMarginMarker:ParagraphPropertyMarker = null;
+		private var mRightMarginMarker:ParagraphPropertyMarker = null;
+		private var mTabPanelActive:Boolean = false;
+		private var mRightToLeft:Boolean = false;
+		private var curParagraphFormat:TextLayoutFormat = null;
+		
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerBar.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerDragTracker.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerDragTracker.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerDragTracker.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerDragTracker.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,88 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import flash.events.MouseEvent;
+	import flash.geom.Point;
+	
+	import mx.core.UIComponent;
+	
+	import bxf.ui.toolkit.Tracker;
+
+	public class RulerDragTracker extends Tracker
+	{
+		public function RulerDragTracker(inPeerToTrackTo:UIComponent, inController:RulerBar, inCookie:Object, inDragThreshold:Number = 2)
+		{
+			super(inPeerToTrackTo, 0, 0);
+			mController = inController;
+			mDragCookie = inCookie;
+			mDragThreshold = inDragThreshold;
+		}
+		
+		/**	Override to get cursor adjust hook and mouse down. 
+		 * @param inMouseEvent mouse info.
+		 * @param inCursorAdjust true if this is a mouse up track.*/
+		override public function BeginTracking(inMouseEvent:MouseEvent, inCursorAdjust:Boolean):void
+		{
+			super.BeginTracking(inMouseEvent, inCursorAdjust);
+		}
+		
+		/**	Override to get mouse move. 
+		 * @param inMouseEvent mouse info.*/
+		override public function ContinueTracking(inMouseEvent:MouseEvent):void
+		{
+			super.ContinueTracking(inMouseEvent);
+			if (!mDragThresholdReached)
+			{
+				if (Point.distance(mAnchorPt, mTrackPt) >= mDragThreshold)
+					mDragThresholdReached = true;
+			}
+			if (mDragThresholdReached)
+				mController.TrackDrag(mTrackPt, mDragCookie, false);
+			inMouseEvent.stopPropagation();
+		}
+		
+		/**	Override to get mouse up. 
+		 * @param inMouseEvent mouse info.*/
+		override public function EndTracking(inMouseEvent:MouseEvent):void
+		{
+			super.EndTracking(inMouseEvent);
+			if (mDragThresholdReached)
+				mController.TrackDrag(mTrackPt, mDragCookie, true);
+			else
+				mController.DragCancelled();
+			inMouseEvent.stopPropagation();
+		}
+		
+		override protected function TrackPoint(inMouseEvent:MouseEvent, inAlsoSetAnchor:Boolean): void
+		{
+			mTrackPt.x = inMouseEvent.stageX;
+			mTrackPt.y = inMouseEvent.stageY;
+			mTrackPt = mController.globalToLocal(mTrackPt);
+			if (inAlsoSetAnchor)
+				mAnchorPt = mTrackPt.clone();
+		}
+
+		private var mController:RulerBar = null;
+		private var mDragCookie:Object = null;
+		private var mDragThreshold:Number;
+		private var mDragThresholdReached:Boolean = false;
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerDragTracker.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerMarker.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerMarker.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerMarker.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerMarker.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,124 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import mx.containers.Canvas;
+
+	public class RulerMarker extends Canvas
+	{
+		public function RulerMarker(inRuler:RulerBar, inWidth:Number, inHeight:Number, inHOffset:Number, inVOffset:Number, inPos:Number)
+		{
+			super();
+			width = inWidth;
+			height = inHeight;
+			mHOffset = inHOffset;
+			mVOffset = inVOffset;
+			mPos = inPos;
+			mRuler = inRuler;
+		}
+		
+		override public function initialize():void
+		{
+			super.initialize();
+			positionMarker();
+		}
+		
+		protected function positionMarker():void
+		{
+			if (parent)
+			{
+				if (alignToRight)
+				{
+					x = parent.width - originPosition - pos + hOffset;
+					y = parent.height - height + vOffset;
+				}
+				else
+				{
+					x = originPosition + pos + hOffset;
+					y = parent.height - height + vOffset;
+				}
+			}
+		}
+		
+		protected function get alignToRight():Boolean
+		{
+			return ruler.rightToLeft;
+		}
+		
+		protected function get originPosition():Number
+		{
+			return 0;
+		}
+
+		public function set pos(inPos:Number):void
+		{
+			mPos = inPos;
+			positionMarker();
+		}
+		
+		public function get pos():Number
+		{
+			return mPos;
+		}
+		
+		public function set hOffset(inOffset:Number):void
+		{
+			mHOffset = inOffset;
+			positionMarker();
+		}
+		
+		public function get hOffset():Number
+		{
+			return mHOffset;
+		}
+		
+		public function set vOffset(inOffset:Number):void
+		{
+			mVOffset = inOffset;
+			positionMarker();
+		}
+		
+		public function get vOffset():Number
+		{
+			return mVOffset;
+		}
+		
+		public function get ruler():RulerBar
+		{
+			return mRuler;
+		}
+		
+		public function set markerLeft(inNewLeft:Number):void
+		{
+			if (parent)
+			{
+				if (alignToRight)
+					pos = parent.width - (inNewLeft + hOffset > parent.width ? parent.width : inNewLeft + hOffset)  - originPosition;
+				else
+					pos = (inNewLeft < 0 ? 0 : inNewLeft) - originPosition - hOffset;
+			}
+		}
+
+		private var mPos:Number;
+		private var mHOffset:Number;
+		private var mVOffset:Number;
+		private var mRuler:RulerBar = null;
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/RulerMarker.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarker.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarker.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarker.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarker.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import mx.messaging.management.Attribute;
+	
+	import flashx.textLayout.formats.ITabStopFormat;
+	
+	public class TabMarker extends RulerMarker implements ITabStopFormat
+	{
+		public function TabMarker(inRuler:RulerBar, tabAttrs:ITabStopFormat)
+		{
+			super(inRuler, 9, 10, -4, 0, Number(tabAttrs.position));
+			mTabKind = tabAttrs.alignment;
+			mAlignmentToken = tabAttrs.decimalAlignmentToken;
+			setStyle("tabkind", mTabKind);
+		}
+		
+		public function get alignment():*
+		{
+			return mTabKind;
+		}
+		
+		public function set alignment(inAlignment:String):void
+		{
+			mTabKind = inAlignment;
+			setStyle("tabkind", mTabKind);
+		}
+		
+		public function get decimalAlignmentToken():*
+		{
+			return mAlignmentToken;
+		}
+		
+		public function set decimalAlignmenyToken(inToken:String):void
+		{
+			mAlignmentToken = inToken;
+		}
+		
+		public function set decimalAlignmentToken(inToken:String):void
+		{
+			mAlignmentToken = inToken;
+		}
+		
+		public function get position():*
+		{
+			return pos;
+		}
+		
+		public function set position(inPosition:Object):void
+		{
+			pos = inPosition as Number;
+		}
+		
+		
+		public function isDifferentPosition(element:*, index:int, arr:Array):Boolean
+		{
+			var other:TabMarker = element as TabMarker;
+			if (other)
+				return other.position != position;
+			else
+				return true;
+		}
+		
+
+		private var mTabKind:String;
+		private var mAlignmentToken:String = null;
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarker.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarkerSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarkerSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarkerSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarkerSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,94 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.rulers
+{
+	import flash.text.engine.TabAlignment;
+	
+	import mx.skins.RectangularBorder;
+
+	public class TabMarkerSkin extends RectangularBorder
+	{
+		public function TabMarkerSkin()
+		{
+			super();
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+		    super.updateDisplayList(w, h);
+		    
+		    var tabKind:String = getStyle("tabkind");
+		    
+			graphics.clear();
+
+		    graphics.lineStyle(3, 0xffffff);
+		    drawOrnament(tabKind, w, h);
+		    graphics.lineStyle(1, 0x000000);
+		    drawOrnament(tabKind, w, h);
+		    
+		    if (tabKind == flash.text.engine.TabAlignment.DECIMAL)
+		    {
+				graphics.beginFill(0x000000);
+				graphics.drawCircle(w / 2 + 3, (h - w / 2) / 2, .75);
+				graphics.endFill();
+		    }
+		    
+			graphics.beginFill(0x000000);
+			graphics.moveTo(0, h - w / 2);
+			graphics.lineTo(w / 2, h);
+			graphics.lineTo(w, h - w / 2);
+			graphics.lineTo(0, h - w / 2);
+			graphics.endFill();
+			
+		    var selected:Boolean = getStyle("selected");
+	  		graphics.lineStyle();
+	    	graphics.beginFill(0x0000ff, selected ? .3 : 0);
+	    	graphics.drawRect(0, 0, w, h);
+	    	graphics.endFill();
+		}
+
+		private function drawOrnament(inKind:String, w:Number, h:Number):void
+		{
+			switch (inKind)
+			{
+			case flash.text.engine.TabAlignment.START:
+				graphics.moveTo(w / 2, h - w / 2);
+				graphics.lineTo(w / 2, 1);
+				graphics.lineTo(w, 1);
+				break;
+			case flash.text.engine.TabAlignment.CENTER:
+				graphics.moveTo(w / 2, h - w / 2);
+				graphics.lineTo(w / 2, 0);
+				break;
+			case flash.text.engine.TabAlignment.END:
+				graphics.moveTo(w / 2, h - w / 2);
+				graphics.lineTo(w / 2, 1);
+				graphics.lineTo(0, 1);
+				break;
+			case flash.text.engine.TabAlignment.DECIMAL:
+				graphics.moveTo(w / 2, h - w / 2);
+				graphics.lineTo(w / 2, 0);
+				break;
+			}
+		}
+		
+
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/rulers/TabMarkerSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/PopupMenuSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/PopupMenuSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/PopupMenuSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/PopupMenuSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flashx.textLayout.ui.styles
+{
+	import flash.filters.DropShadowFilter;
+	
+	import mx.skins.RectangularBorder;
+
+	public class PopupMenuSkin extends RectangularBorder
+	{
+		public function PopupMenuSkin()
+		{
+			super();
+			filters = [new DropShadowFilter(2, 90, 0x000000, .45, 2, 2)];
+		}
+
+		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
+		{
+			super.updateDisplayList(unscaledWidth, unscaledHeight);
+			
+	 		if (getStyle("cornerRadius") != undefined)
+				mCornerRadius = getStyle("cornerRadius");
+			if (getStyle("backColor") != undefined)
+				mBackColor = getStyle("backColor");
+			if (getStyle("backAlpha") != undefined)
+				mBackAlpha = getStyle("backAlpha");
+			if (getStyle("lineColor") != undefined)
+				mLineColor = getStyle("lineColor");
+			if (getStyle("lineAlpha") != undefined)
+				mLineAlpha = getStyle("lineAlpha");
+			if (getStyle("lineWidth") != undefined)
+				mLineWidth = getStyle("lineWidth");
+	
+			graphics.clear();
+	 		graphics.lineStyle(mLineWidth, mLineColor, mLineAlpha);
+			graphics.beginFill(mBackColor, mBackAlpha);
+			graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
+			graphics.endFill();
+				
+		}
+	
+	 	private var mCornerRadius:Number = 0;
+	 	private var mLineWidth:Number = 1;
+	 	private var mBackColor:uint = 0x1a1a1a;
+	 	private var mBackAlpha:Number = 0.9;
+	 	private var mLineColor:uint = 0xffffff;
+	 	private var mLineAlpha:Number = 0.15;
+
+
+	}
+	
+	
+}

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/PopupMenuSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarDownArrowUpSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarDownArrowUpSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarDownArrowUpSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarDownArrowUpSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flashx.textLayout.ui.styles
+{
+	import mx.skins.RectangularBorder;
+
+	public class ScrollbarDownArrowUpSkin extends RectangularBorder
+	{
+		public function ScrollbarDownArrowUpSkin()
+		{
+			super();
+		}
+		
+		override public function get measuredWidth():Number
+		{
+			return 13;
+		}
+		
+		override public function get measuredHeight():Number
+		{
+			return 14;
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+			super.updateDisplayList(w, h);
+		}
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarDownArrowUpSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbOverSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbOverSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbOverSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbOverSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,89 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flashx.textLayout.ui.styles
+{
+	import mx.skins.RectangularBorder;
+	import mx.utils.GraphicsUtil;
+	import flash.display.LineScaleMode;
+	import flash.display.CapsStyle;
+	
+	public class ScrollbarThumbOverSkin extends RectangularBorder
+	{
+		public function ScrollbarThumbOverSkin()
+		{
+			super();
+		}
+		
+		override public function get measuredWidth():Number
+		{
+			return 11;
+		}
+		
+		override public function get measuredHeight():Number
+		{
+			return 10;
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+			super.updateDisplayList(w, h);
+			
+			var thumbFill:uint = 0x222222;
+			var thumbFillAlpha:Number = 1.0;
+			var thumbStroke:uint = 0x2A2A2A;
+			var thumbStrokeAlpha:Number = 1.0;
+
+			var trackStroke:uint = 0x2A2A2A;
+			var trackStrokeAlpha:Number = 1.0;
+						
+ 			if (getStyle("thumbOverFill") != undefined)
+				thumbFill = getStyle("thumbOverFill");
+ 			if (getStyle("thumbOverFillAlpha") != undefined)
+				thumbFillAlpha = getStyle("thumbOverFillAlpha");
+ 			if (getStyle("thumbOverStroke") != undefined)
+				thumbStroke = getStyle("thumbOverStroke");
+ 			if (getStyle("thumbOverStrokeAlpha") != undefined)
+				thumbStrokeAlpha = getStyle("thumbOverStrokeAlpha");
+ 			if (getStyle("trackStroke") != undefined)
+				trackStroke = getStyle("trackStroke");
+ 			if (getStyle("trackStrokeAlpha") != undefined)
+				trackStrokeAlpha = getStyle("trackStrokeAlpha");
+
+			graphics.clear();
+			// draw the top line of the thumb to match the track
+			graphics.lineStyle(1, trackStroke, trackStrokeAlpha);
+			graphics.moveTo(0, 0);
+			graphics.lineTo(w-1, 0);
+
+			// fill in the thumb
+			graphics.beginFill(thumbFill, thumbFillAlpha);
+			graphics.drawRect(0, 0, w-1, h-2);
+			graphics.endFill();
+			
+			// draw the border of the thumb
+			graphics.lineStyle(1, thumbStroke, thumbStrokeAlpha);
+			graphics.drawRect(0, 1, w-1, h-3);
+			
+			// draw the bottom line of the thumb to match the track
+			graphics.lineStyle(1, trackStroke, trackStrokeAlpha);
+			graphics.moveTo(0, h-1);
+			graphics.lineTo(w, h-1);
+			
+		}
+	}}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbOverSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbUpSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbUpSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbUpSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbUpSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,89 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flashx.textLayout.ui.styles
+{
+	import mx.skins.RectangularBorder;
+	import mx.utils.GraphicsUtil;
+	import flash.display.LineScaleMode;
+	import flash.display.CapsStyle;
+	
+	public class ScrollbarThumbUpSkin extends RectangularBorder
+	{
+		public function ScrollbarThumbUpSkin()
+		{
+			super();
+		}
+		
+		override public function get measuredWidth():Number
+		{
+			return 11;
+		}
+		
+		override public function get measuredHeight():Number
+		{
+			return 10;
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+			super.updateDisplayList(w, h);
+			
+			var thumbFill:uint = 0x222222;
+			var thumbFillAlpha:Number = 1.0;
+			var thumbStroke:uint = 0x2A2A2A;
+			var thumbStrokeAlpha:Number = 1.0;
+
+			var trackStroke:uint = 0x2A2A2A;
+			var trackStrokeAlpha:Number = 1.0;
+						
+ 			if (getStyle("thumbFill") != undefined)
+				thumbFill = getStyle("thumbFill");
+ 			if (getStyle("thumbFillAlpha") != undefined)
+				thumbFillAlpha = getStyle("thumbFillAlpha");
+ 			if (getStyle("thumbStroke") != undefined)
+				thumbStroke = getStyle("thumbStroke");
+ 			if (getStyle("thumbStrokeAlpha") != undefined)
+				thumbStrokeAlpha = getStyle("thumbStrokeAlpha");
+ 			if (getStyle("trackStroke") != undefined)
+				trackStroke = getStyle("trackStroke");
+ 			if (getStyle("trackStrokeAlpha") != undefined)
+				trackStrokeAlpha = getStyle("trackStrokeAlpha");
+
+			graphics.clear();
+			// draw the top line of the thumb to match the track
+			graphics.lineStyle(1, trackStroke, trackStrokeAlpha);
+			graphics.moveTo(0, 0);
+			graphics.lineTo(w-1, 0);
+
+			// fill in the thumb
+			graphics.beginFill(thumbFill, thumbFillAlpha);
+			graphics.drawRect(0, 0, w-1, h-2);
+			graphics.endFill();
+			
+			// draw the border of the thumb
+			graphics.lineStyle(1, thumbStroke, thumbStrokeAlpha);
+			graphics.drawRect(0, 1, w-1, h-3);
+			
+			// draw the bottom line of the thumb to match the track
+			graphics.lineStyle(1, trackStroke, trackStrokeAlpha);
+			graphics.moveTo(0, h-1);
+			graphics.lineTo(w, h-1);
+			
+		}
+	}}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarThumbUpSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarTrackSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarTrackSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarTrackSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarTrackSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flashx.textLayout.ui.styles
+{
+	import flash.display.CapsStyle;
+	import flash.display.LineScaleMode;
+	
+	import mx.skins.RectangularBorder;
+
+	public class ScrollbarTrackSkin extends RectangularBorder
+	{
+		public function ScrollbarTrackSkin()
+		{
+			super();
+		}
+		
+		override public function get measuredWidth():Number
+		{
+			return 13;
+		}
+		
+		override public function get measuredHeight():Number
+		{
+			return 10;
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+			super.updateDisplayList(w, h);
+			
+			var trackFill:uint = 0x000000;
+			var trackFillAlpha:Number = 1.0;
+			var trackStroke:uint = 0x2A2A2A;
+			var trackStrokeAlpha:Number = 1.0;
+			
+ 			if (getStyle("trackFill") != undefined)
+				trackFill = getStyle("trackFill");
+ 			if (getStyle("trackFillAlpha") != undefined)
+				trackFillAlpha = getStyle("trackFillAlpha");
+ 			if (getStyle("trackStroke") != undefined)
+				trackStroke = getStyle("trackStroke");
+ 			if (getStyle("trackStrokeInnerAlpha") != undefined)
+				trackStrokeAlpha = getStyle("trackStrokeAlpha");
+
+			graphics.clear();
+			graphics.beginFill(trackFill, trackFillAlpha);
+			graphics.drawRect(0, 0, w-1, h);
+			graphics.endFill();
+			graphics.lineStyle(1, trackStroke, trackStrokeAlpha, true, LineScaleMode.NONE, CapsStyle.SQUARE);
+			graphics.drawRect(0, 0, w-1, h);
+		}
+	}}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarTrackSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarUpArrowUpSkin.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarUpArrowUpSkin.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarUpArrowUpSkin.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarUpArrowUpSkin.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flashx.textLayout.ui.styles
+{
+	import mx.skins.RectangularBorder;
+
+	public class ScrollbarUpArrowUpSkin extends RectangularBorder
+	{
+		public function ScrollbarUpArrowUpSkin()
+		{
+			super();
+		}
+		
+		override public function get measuredWidth():Number
+		{
+			return 13;
+		}
+		
+		override public function get measuredHeight():Number
+		{
+			return 14;
+		}
+		
+		override protected function updateDisplayList(w:Number, h:Number):void
+		{
+			super.updateDisplayList(w, h);
+		}
+	}
+}
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/flashx/textLayout/ui/styles/ScrollbarUpArrowUpSkin.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FeatureSetChangeEvent.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FeatureSetChangeEvent.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FeatureSetChangeEvent.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FeatureSetChangeEvent.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,42 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package textEditBar
+{
+import flash.events.Event;
+import flashx.textLayout.elements.TextFlow;
+
+public class FeatureSetChangeEvent extends Event
+{
+	public const FEATURE_SET:String = "featureSet";
+	
+	public var featureSet:String;
+
+	public function FeatureSetChangeEvent(newFeatureSet:String, type:String = FEATURE_SET,
+							  bubbles:Boolean = false,
+							  cancelable:Boolean = false)
+	{
+		super(type, bubbles, cancelable);
+		featureSet = newFeatureSet;
+	}
+	override public function clone():Event
+	{
+		return new FeatureSetChangeEvent(featureSet, type, bubbles, cancelable);
+	}
+}		// end class
+}

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FeatureSetChangeEvent.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileEvent.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileEvent.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileEvent.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileEvent.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package textEditBar
+{
+import flash.events.Event;
+import flash.net.FileReference;
+
+public class FileEvent extends Event
+{
+	public var fileName:FileReference;
+	
+	public const FILE_CHOOSE:String = "fileChoose";
+
+	public function FileEvent(newFileName:FileReference, type:String = FILE_CHOOSE,
+							  bubbles:Boolean = false,
+							  cancelable:Boolean = false)
+	{
+		super(type, bubbles, cancelable);
+		fileName = newFileName;
+	}
+	
+	override public function clone():Event
+	{
+		return new FileEvent(fileName, type, bubbles, cancelable);
+	}
+}		// end class
+}		// end package
\ No newline at end of file

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileEvent.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileIOHelper.as
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileIOHelper.as?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileIOHelper.as (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileIOHelper.as Sat Aug 23 08:47:51 2014
@@ -0,0 +1,268 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+package textEditBar
+{
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	import flash.events.IOErrorEvent;
+	import flash.net.FileReference;
+	
+	import flashx.textLayout.conversion.ConversionType;
+	import flashx.textLayout.conversion.ITextExporter;
+	import flashx.textLayout.conversion.ITextImporter;
+	import flashx.textLayout.conversion.TextConverter;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.TextFlow;
+	
+	import mx.managers.CursorManager;
+	import mx.managers.PopUpManager;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.mxml.HTTPService;
+	
+	import textEditBar.StatusPopup;
+	
+	public class FileIOHelper
+	{
+		static public var parentWindow:DisplayObject;
+		static public var changeContent:Function;
+
+		static private var _openedFile:String;
+		
+		// called when the app has a specific file it wants to read (at startup)
+		static public function fileOpen(fileName:String):void
+		{
+			var localHTTP:HTTPService = new HTTPService();
+  			localHTTP.url = fileName;
+  			_openedFile = fileName;
+			localHTTP.method = "GET";
+			localHTTP.resultFormat="text"
+			localHTTP.showBusyCursor=true;
+			localHTTP.addEventListener(ResultEvent.RESULT,parseIntoFlowFromHTTP,false,0,true);
+			localHTTP.addEventListener(IOErrorEvent.IO_ERROR,errorOnReadFromHTTP,false,0,true);
+			localHTTP.send();
+		}
+
+		// called when user picks a file
+		static public function fileChoose(fileName:FileReference) : void
+		{
+			fileName.addEventListener(Event.COMPLETE,onFileReferenceLoadComplete,false,0,true);
+			fileName.addEventListener(IOErrorEvent.IO_ERROR,errorOnReadFromFileReference,false,0,true);
+			fileName.load();
+		}
+		
+		static private function onFileReferenceLoadComplete(event:Event):void
+		{
+			var fileReference:FileReference = FileReference(event.target);
+	   		_extension= getExtension(fileReference.name).toLowerCase();
+	   		_fileData = String(fileReference.data);
+	   		parseCurrentDataWithExtension();
+		}
+
+		static private function errorOnReadFromFileReference(event:IOErrorEvent):void
+        {
+        	var curFileReference:FileReference = FileReference(event.target);
+        	// Text content will be an error string
+			var errorString:String = "Error reading file " + curFileReference.name;
+ 			errorString += "\n";
+ 			errorString += event.toString();
+ 			_extension = "txt";
+ 			_fileData = errorString;
+ 			parseCurrentDataWithExtension();
+			//CursorManager.removeBusyCursor(); //get rid of hourglass cursor. 			
+  		}
+  		
+ 		static private function parseIntoFlowFromHTTP(event:ResultEvent):void 
+ 		{
+	   		_fileData = String(event.result);
+	   		_extension = getExtension(_openedFile).toLowerCase();
+	   		parseCurrentDataWithExtension();
+	   		_openedFile = null;
+ 		}
+ 		
+ 		static private function errorOnReadFromHTTP(event:Object):void
+ 		{
+ 			// Text content will be an error string
+			var errorString:String = "Error reading file " + _openedFile;
+ 			errorString += "\n";
+ 			errorString += event.fault;
+ 			_extension = "txt";
+ 			_fileData = errorString;
+ 			parseCurrentDataWithExtension();
+			CursorManager.removeBusyCursor(); //get rid of hourglass cursor. 
+ 	   		_openedFile = null;
+		}
+		
+		static private function getExtension(fileName:String):String
+		{
+			var dotPos:int = fileName.lastIndexOf(".");
+			if (dotPos >= 0)
+				return fileName.substring(dotPos + 1);
+			return fileName;
+		}
+		
+		// hold onto these two in case we need to recreate textFlow
+		static private var _extension:String;
+		static private var _fileData:String;
+		
+		static public function parseCurrentDataWithExtension():void
+		{
+	   		switch (_extension)
+	   		{
+	   			case "xml":		// use Vellum markup
+	   				parseStringIntoFlow(_fileData, TextConverter.TEXT_LAYOUT_FORMAT);
+	   				break;
+	   			case "txt":
+	   				parseStringIntoFlow(_fileData, TextConverter.PLAIN_TEXT_FORMAT);
+	   				break;
+				case "html":
+	   				parseStringIntoFlow(_fileData, TextConverter.TEXT_FIELD_HTML_FORMAT);
+	   				break;
+
+	   		}
+		}
+				
+		static private function parseStringIntoFlow(source:String, format:String):void
+		{
+			var textImporter:ITextImporter = TextConverter.getImporter(format);
+			var newFlow:TextFlow = textImporter.importToFlow(source);
+			reportImportErrors(textImporter.errors);
+			// no TextFlow found - Flow will display an empty TextFlow by design 
+			// - alternative is to do some kind of error string
+			changeContent(newFlow ? newFlow : new TextFlow());
+		} 
+ 		
+		static private function reportImportErrors(errors:Vector.<String>):void
+		{
+			if (errors)
+			{
+				var errorText:String = "ERRORS REPORTED ON IMPORT";
+				for each(var e:String in errors)
+					errorText += "\n" + e;
+					
+				var dlg:StatusPopup = new StatusPopup();
+				dlg.closeFunction = closeStatusPopup;
+
+				PopUpManager.addPopUp(dlg, parentWindow, true);
+				PopUpManager.centerPopUp(dlg);
+				// stick it in the upper left
+				dlg.x = 0;
+				dlg.y = 0;
+			
+				dlg.textArea.text = errorText;
+			}
+		}
+ 		static private function closeStatusPopup(dlg:StatusPopup):void
+ 		{
+ 			PopUpManager.removePopUp(dlg);
+ 		}
+ 			
+		static private function importStatusPopupContent(dlg:StatusPopup):void
+		{
+			switch(dlg.textFormat)
+			{
+				case TextConverter.TEXT_LAYOUT_FORMAT:
+					_extension = "xml";
+					break;
+				case TextConverter.TEXT_FIELD_HTML_FORMAT:
+					_extension = "html";
+					break;
+			}
+			_fileData = dlg.textArea.text;
+			parseCurrentDataWithExtension();
+			PopUpManager.removePopUp(dlg);
+		}
+		
+		static private function saveStatusPopupContent(dlg:StatusPopup):void
+		{
+			var extension:String;
+			switch(dlg.textFormat)
+			{
+				case TextConverter.TEXT_LAYOUT_FORMAT:
+					extension = "xml";
+					break;
+				case TextConverter.TEXT_FIELD_HTML_FORMAT:
+					extension = "html";
+					break;
+			}
+			
+	  		var fileReference:FileReference = new FileReference();
+  			fileReference.save(dlg.textArea.text,extension == null ? null : "NewFile."+extension);
+		}
+		
+
+
+		// Export related code
+		static public function textLayoutExport(activeFlow:TextFlow) : void
+		{		
+			export(activeFlow, TextConverter.TEXT_LAYOUT_FORMAT);
+		}
+
+
+		static public function htmlExport(activeFlow:TextFlow) : void
+		{
+			export(activeFlow, TextConverter.TEXT_FIELD_HTML_FORMAT);
+		}
+
+		static private const xmlBoilerPlate:String = '<?xml version="1.0" encoding="utf-8"?>\n';
+										
+		static public function export(activeFlow:TextFlow, format:String) : void
+		{
+			//CONFIG::debug
+			{	
+				var originalSettings:Object = XML.settings();
+				try
+				{
+					XML.ignoreProcessingInstructions = false;		
+					XML.ignoreWhitespace = false;
+					XML.prettyPrinting = false;
+					
+					
+					var exporter:ITextExporter = TextConverter.getExporter(format);
+					var xmlExport:XML = exporter.export(activeFlow, ConversionType.XML_TYPE) as XML;
+					var result:String = xmlBoilerPlate + xmlExport;					
+					XML.setSettings(originalSettings);
+				}
+				
+				catch(e:Error)
+				{
+					XML.setSettings(originalSettings);
+					throw(e);
+				}
+			}
+			
+			// show it in the pop-up dialog
+			var dlg:StatusPopup = new StatusPopup();
+			dlg.closeFunction = closeStatusPopup;
+			dlg.importFunction = importStatusPopupContent;
+			dlg.saveFunction   = saveStatusPopupContent;
+			dlg.textFormat = format;
+			
+			PopUpManager.addPopUp(dlg, parentWindow, true);
+			PopUpManager.centerPopUp(dlg);
+			// stick it in the upper left
+			dlg.x = 0;
+			dlg.y = 0;
+	
+			dlg.textArea.text = result.replace(/\u000D\u000A/g, "\r"); // workaround for TextArea bug SDK-14797
+		}
+		
+
+
+	}
+}

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileIOHelper.as
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileServices.mxml
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileServices.mxml?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileServices.mxml (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileServices.mxml Sat Aug 23 08:47:51 2014
@@ -0,0 +1,96 @@
+<?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.
+
+-->
+
+<!--This widget allows the user to enter a file name and when the "ReadFile" button is pressed, it 
+reads the file, and passes through the file contents as a ContentEvent. It expects an XML file in
+TextLayout format.-->
+
+<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" creationComplete="handleCreationComplete()" >
+	<mx:Metadata>
+	[Event(name="fileChoose", type="textEditBar.FileEvent")]
+	[Event(name="textLayoutExport", type="flash.events.Event")]
+	[Event(name="htmlExport", type="flash.events.Event")]
+ 	</mx:Metadata>
+
+  <mx:Script>
+		<![CDATA[
+			import flash.events.Event;
+			import flash.system.Capabilities;
+			import flashx.textLayout.elements.TextFlow;
+			import mx.events.MenuEvent;
+			import mx.controls.Alert;
+			import flashx.textLayout.edit.EditingMode;
+			import flashx.textLayout.edit.ElementRange;
+			import flashx.textLayout.edit.ISelectionManager;
+			import flashx.textLayout.edit.IEditManager;
+			import flashx.textLayout.BuildInfo;
+			
+			public var activeFlow:TextFlow;
+			
+			[Bindable]
+			public var buildString:String = "Build: " + BuildInfo.kBuildNumber + "(" + Capabilities.version + ")";
+
+			internal function handleCreationComplete():void
+			{
+				buildLabel.left = (this.x + this.width - 20) - buildLabel.width;
+			}
+			// Update UI panel in response to change in selection
+			public function update(range:ElementRange):void
+			{
+				if (!activeFlow)
+					return;
+					
+			}
+			
+			private var fileReference:FileReference;
+			
+			public function currentFileName():String
+			{
+				return fileReference != null ? fileReference.name : null;
+			}
+			
+			public function openDialog():void
+			{
+	  			var markupFilter:FileFilter = new FileFilter("Documents","*.xml;*.fxg;*.html");
+	  			fileReference = new FileReference();
+  				fileReference.browse([markupFilter]);
+  				fileReference.addEventListener(Event.SELECT,onFileSelect);
+			}
+			
+			private function onFileSelect(event:Event):void 
+			{
+	  			try {
+	  				dispatchEvent(new FileEvent(fileReference));
+		  			//fileReference.load();
+		  		} catch (err:Event) {
+		  			Alert.show(err.toString());
+		  		}
+	  		}
+		   
+           ]]>
+    </mx:Script>
+
+   	<mx:Button label="Open..." click="openDialog()"/>
+   		
+	<mx:Button id="textLayoutExportButton" label="Markup..." click="dispatchEvent(new Event('textLayoutExport'));"/>
+	<mx:Button id="htmlExportButton" label="HTML Markup..." click="dispatchEvent(new Event('htmlExport'));"/>
+
+	<mx:Label id="buildLabel" text="{buildString}" fontWeight="bold" paddingTop="3" paddingBottom="1"/>
+</mx:HBox>

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/FileServices.mxml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/GraphicBar.mxml
URL: http://svn.apache.org/viewvc/flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/GraphicBar.mxml?rev=1619987&view=auto
==============================================================================
--- flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/GraphicBar.mxml (added)
+++ flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/GraphicBar.mxml Sat Aug 23 08:47:51 2014
@@ -0,0 +1,153 @@
+<?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.
+
+-->
+
+<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:textEditBar="textEditBar.*" 
+	addedToStage="onAddedToStage()" removedFromStage="onRemovedFromStage()" horizontalScrollPolicy="off" verticalScrollPolicy="off">
+	
+	<mx:Script>
+		<![CDATA[
+			import flashx.textLayout.edit.ElementRange;
+			import flashx.textLayout.edit.IEditManager;
+			import flashx.textLayout.elements.InlineGraphicElement;
+			import flashx.textLayout.elements.TextFlow;
+			import flashx.textLayout.formats.FormatValue;
+			import flashx.textLayout.tlf_internal;
+			
+			use namespace tlf_internal;
+			
+			public var activeFlow:TextFlow;
+			
+			protected function applyChange():void
+			{
+				changeForeignElement(imageURL.text, imageWidth.text, imageHeight.text, "none", doChangeImage);				
+			}
+			
+	  		protected function changeForeignElement(foreignElementUrl:String, width:String, height:String, float:String, changeCurrent:Boolean):void
+	 		{
+	 			if (activeFlow && activeFlow.interactionManager is IEditManager)
+	 			{
+					if (changeCurrent)
+	 					IEditManager(activeFlow.interactionManager).modifyInlineGraphic(foreignElementUrl, width, height, float);
+					else
+						IEditManager(activeFlow.interactionManager).insertInlineGraphic(foreignElementUrl, width, height, float);
+	 				activeFlow.interactionManager.setFocus();
+	 			}
+	 		}
+		
+			protected var doChangeImage:Boolean = false;
+			
+			public function update(range:ElementRange):void
+ 			{
+ 				if (onStage)
+ 				{
+ 					if (range ==  null)
+ 						visible = false;
+ 					else
+ 					{
+ 						if (!visible)
+ 							visible = true;
+
+	 					var makeItTheChangeButton:Boolean = false;
+	 					
+	 					// this logic is a complicated by the fact that we extend the end of the selection because the FE is at the end of the paragraph
+	 					if (range && range.firstLeaf is InlineGraphicElement && range.absoluteStart == range.firstLeaf.getAbsoluteStart())
+	 					{
+	 						// two cases just the FE and just the FE plus the paragraph terminator
+	 						if (range.absoluteEnd == range.absoluteStart+1 || (range.firstParagraph == range.lastParagraph && range.absoluteEnd == range.absoluteStart+2 && range.absoluteEnd == range.lastParagraph.getAbsoluteStart() + range.lastParagraph.textLength))
+	 							makeItTheChangeButton = true; 
+	 					}
+	 					
+	 					// block selection of just the FE
+	 					if (makeItTheChangeButton)
+	 						updateForChange(InlineGraphicElement(range.firstLeaf));
+	 					else
+	 						updateForInsert(range)
+ 					}
+ 				}
+				lastRange = range;	
+ 			}
+ 			
+ 			protected function updateForChange(inlineElement:InlineGraphicElement):void
+ 			{
+				var sourceString:String = inlineElement.source.toString()
+				var widthString:String = inlineElement.width === undefined ? FormatValue.AUTO : inlineElement.width.toString();
+				var heightString:String = inlineElement.height === undefined ? FormatValue.AUTO : inlineElement.height.toString();
+ 				doUpdate(sourceString, widthString, heightString, true, true);
+ 			}
+			
+ 			protected function updateForInsert(range:ElementRange):void
+ 			{
+ 				doUpdate("", 
+ 					InlineGraphicElement.tlf_internal::widthPropertyDefinition.defaultValue.toString(),
+ 					InlineGraphicElement.tlf_internal::heightPropertyDefinition.defaultValue.toString(),
+ 					false, range && range.firstLeaf);
+	 		}
+	 		
+ 			private function doUpdate(url:String, width:String, height:String, modify:Boolean, enableImage:Boolean):void
+ 			{
+  				imageURL.text = url;
+ 				imageWidth.text = width;
+ 				imageHeight.text = height;
+ 				imageButton.label = modify ? "Change" : "Insert";
+ 				doChangeImage = modify;
+ 				imageButton.enabled = enableImage;			
+ 			}
+
+			private var onStage:Boolean = false;
+			private var addedFrameEventListener:Boolean = false;
+			protected var lastRange:ElementRange = null;
+			private function onAddedToStage():void
+			{
+				// the dataProviders aren't set up yet - delay to the frame
+				onStage = true;
+				if (!addedFrameEventListener)
+				{
+					addedFrameEventListener = true;
+					addEventListener("enterFrame",onEnterFrame);
+				}
+			}
+				
+			private function onEnterFrame(p:Event):void
+			{
+				this.removeEventListener("enterFrame",onEnterFrame);
+				addedFrameEventListener = false;	
+				
+				var temp:ElementRange = lastRange;
+				lastRange = null;
+				update(temp);
+					
+			}
+			
+			private function onRemovedFromStage():void
+			{
+				onStage = false;
+			}
+		]]>
+	</mx:Script>
+
+	<mx:Label text="Image URL:" fontWeight="bold"/>
+	<mx:TextInput id="imageURL" width="140"/>
+	<mx:Label text="Width:" fontWeight="bold"/>
+	<mx:TextInput id="imageWidth" width="60"/>
+	<mx:Label text="Height:" fontWeight="bold"/>
+	<mx:TextInput id="imageHeight" width="60"/>			
+	<mx:Button id="imageButton" label="Insert Image" 
+		click="applyChange();" />
+</mx:HBox>

Propchange: flex/site/trunk/content/tourdeflex/spark/tlf/textEditBar/GraphicBar.mxml
------------------------------------------------------------------------------
    svn:eol-style = native