You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ha...@apache.org on 2014/10/05 21:40:40 UTC
[3/5] Commit of table work
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/edit/SelectionManager.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/edit/SelectionManager.as b/textLayout/src/flashx/textLayout/edit/SelectionManager.as
index dd6f117..6de1c2b 100644
--- a/textLayout/src/flashx/textLayout/edit/SelectionManager.as
+++ b/textLayout/src/flashx/textLayout/edit/SelectionManager.as
@@ -20,8 +20,10 @@ package flashx.textLayout.edit
{
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
+ import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
+ import flash.display.Shape;
import flash.display.Stage;
import flash.errors.IllegalOperationError;
import flash.events.ContextMenuEvent;
@@ -31,8 +33,10 @@ package flashx.textLayout.edit
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TextEvent;
+ import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
+ import flash.text.engine.TextBlock;
import flash.text.engine.TextLine;
import flash.text.engine.TextLineValidity;
import flash.text.engine.TextRotation;
@@ -40,14 +44,20 @@ package flashx.textLayout.edit
import flash.ui.Keyboard;
import flash.ui.Mouse;
import flash.ui.MouseCursor;
+ import flash.ui.MouseCursorData;
+ import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
import flashx.textLayout.compose.IFlowComposer;
import flashx.textLayout.compose.TextFlowLine;
+ import flashx.textLayout.compose.TextFlowTableBlock;
import flashx.textLayout.container.ColumnState;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.debug.Debugging;
import flashx.textLayout.debug.assert;
+ import flashx.textLayout.elements.CellContainer;
+ import flashx.textLayout.elements.CellCoordinates;
+ import flashx.textLayout.elements.CellRange;
import flashx.textLayout.elements.Configuration;
import flashx.textLayout.elements.FlowElement;
import flashx.textLayout.elements.FlowLeafElement;
@@ -55,7 +65,9 @@ package flashx.textLayout.edit
import flashx.textLayout.elements.IConfiguration;
import flashx.textLayout.elements.InlineGraphicElement;
import flashx.textLayout.elements.ParagraphElement;
- import flashx.textLayout.elements.TableDataCellElement;
+ import flashx.textLayout.elements.TableBlockContainer;
+ import flashx.textLayout.elements.TableCellElement;
+ import flashx.textLayout.elements.TableColElement;
import flashx.textLayout.elements.TableElement;
import flashx.textLayout.elements.TableRowElement;
import flashx.textLayout.elements.TextFlow;
@@ -122,23 +134,325 @@ package flashx.textLayout.edit
* @langversion 3.0
*/
public class SelectionManager implements ISelectionManager
- {
+ {
+ static tlf_internal var useTableSelectionCursors:Boolean = false;
+ /**
+ * Cursor for selection of table
+ **/
+ public static var SelectTable:String = "selectTable";
+
+ /**
+ * Cursor for selection of table row
+ **/
+ public static var SelectTableRow:String = "selectTableRow";
+
+ /**
+ * Cursor for selection of table column
+ **/
+ public static var SelectTableColumn:String = "selectTableColumn";
+
private var _focusedSelectionFormat:SelectionFormat;
private var _unfocusedSelectionFormat:SelectionFormat;
private var _inactiveSelectionFormat:SelectionFormat;
+ private var _focusedCellSelectionFormat:SelectionFormat;
+ private var _unfocusedCellSelectionFormat:SelectionFormat;
+ private var _inactiveCellSelectionFormat:SelectionFormat;
private var _selFormatState:String = SelectionFormatState.UNFOCUSED;
private var _isActive:Boolean;
/** The TextFlow of the selection. */
private var _textFlow:TextFlow;
+
+ protected var _subManager:ISelectionManager;
+ protected var _superManager:ISelectionManager;
+
+ private var _currentTable:TableElement;
+
+ // this should probably be produced dynamically rather than keep a reference.
+ private var _cellRange:CellRange;
+
+ //TODO the following functions need proper comments and should be moved to a logical location within the class.
+
+ public function get currentTable():TableElement
+ {
+ return _currentTable;
+ }
+ public function set currentTable(table:TableElement):void
+ {
+ _currentTable = table;
+ }
+
+ public function hasCellRangeSelection():Boolean
+ {
+ if (!_currentTable) {
+ return false;
+ }
+
+ //we should really check the anchorCellPosition and activeCellPosition instead
+ if (!_cellRange) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Select a table cell text flow
+ **/
+ public function selectCellTextFlow(cell:TableCellElement):void {
+
+ if (cell && cell.table) {
+ var selectionManager:SelectionManager = cell.textFlow.interactionManager as SelectionManager;
+
+ clear();
+
+ if (selectionManager) {
+ selectionManager.currentTable = cell.table;
+ selectionManager.selectAll();
+
+ // this seems to be required to work but it should not be
+ selectionManager.setFocus();
+ }
+ }
+ }
+
+ /**
+ * Select a table cell.
+ **/
+ public function selectCell(cell:TableCellElement):void {
+ var beginCoordinates:CellCoordinates;
+ var endCoordinates:CellCoordinates;
+
+ if (cell) {
+ beginCoordinates = new CellCoordinates(cell.rowIndex, cell.colIndex);
+ endCoordinates = new CellCoordinates(cell.rowIndex, cell.colIndex);
+
+ if (beginCoordinates.isValid()) {
+ selectCellRange(beginCoordinates, endCoordinates);
+ }
+ }
+ }
+
+ /**
+ * Select table cells at the specified index.
+ **/
+ public function selectCellAt(table:TableElement, rowIndex:int, colIndex:int):void {
+ var cell:TableCellElement = table.getCellAt(rowIndex, colIndex);
+
+ if (cell) {
+ selectCell(cell);
+ }
+ }
+
+ /**
+ * Select table cells at the specified index
+ **/
+ public function selectCells(cells:Vector.<TableCellElement>):void {
+ var startX:int = int.MAX_VALUE;
+ var startY:int = int.MAX_VALUE;
+ var endX:int = int.MIN_VALUE;
+ var endY:int = int.MIN_VALUE;
+ var cell:TableCellElement;
+ var table:TableElement;
+ for each(cell in cells)
+ {
+ if(cell)
+ {
+ if(table == null)
+ table = cell.getTable();
+
+ var col:int = cell.colIndex;
+ var row:int = cell.rowIndex;
+ if(col < startX)
+ startX = col;
+ if(col > endX)
+ endX = col;
+ if(row < startY)
+ startY = row;
+ if(row > endY)
+ endY = row;
+ }
+ }
+ if(startX <= endX && startY <= endY)
+ selectCellRange(
+ new CellCoordinates(startY,startX,table),
+ new CellCoordinates(endY,endX,table)
+ );
+ }
+
+ /**
+ * Select the specified table row.
+ **/
+ public function selectRow(row:TableRowElement):void {
+ var beginCoordinates:CellCoordinates;
+ var endCoordinates:CellCoordinates;
+
+ if (row) {
+ beginCoordinates = new CellCoordinates(row.rowIndex, 0);
+ endCoordinates = new CellCoordinates(row.rowIndex, row.numCells);
+
+ if (beginCoordinates.isValid() && endCoordinates.isValid()) {
+ selectCellRange(beginCoordinates, endCoordinates);
+ }
+ }
+ }
+
+ /**
+ * Select a table row at the specified index
+ **/
+ public function selectRowAt(table:TableElement, index:int):void {
+ var row:TableRowElement = table ? table.getRowAt(index) : null;
+
+ if (row) {
+ selectRow(row);
+ }
+ }
+
+ /**
+ * Selects the table rows provided
+ **/
+ public function selectRows(rows:Array):void {
+ var cells:Vector.<TableCellElement> = new Vector.<TableCellElement>();
+ var table:TableElement;
+ var cell:TableCellElement;
+
+ if (rows && rows.length) {
+
+ for (var i:int;i<rows.length;i++)
+ {
+ var row:TableRowElement = rows[i] as TableRowElement;
+
+ if (row)
+ {
+ for each(cell in row.cells)
+ cells.push(cell);
+ }
+ }
+
+ selectCells(cells);
+ }
+ }
+
+ /**
+ * Select a table column.
+ **/
+ public function selectColumn(column:TableColElement):void {
+ var table:TableElement = column.table;
+
+ if (column && table) {
+ selectCells(table.getCellsForColumn(column));
+ }
+ }
+
+ /**
+ * Select a table column at the specified index
+ **/
+ public function selectColumnAt(table:TableElement, index:int):void {
+ var column:TableColElement = table.getColumnAt(index);
+
+ if (column && table) {
+ return selectColumn(column);
+ }
+ }
+
+ /**
+ * Selects the table columns provided
+ **/
+ public function selectColumns(columns:Array):void {
+ var cells:Vector.<TableCellElement> = new Vector.<TableCellElement>();
+ var cell:TableCellElement;
+
+ if (columns && columns.length) {
+
+ for (var i:int;i<columns.length;i++)
+ {
+ var column:TableColElement = columns[i] as TableColElement;
+
+ if (column)
+ {
+ for each(cell in column.cells)
+ cells.push(cell);
+ }
+
+ }
+
+ selectCells(cells);
+ }
+ }
+
+ /**
+ * Select all cells in a table.
+ **/
+ public function selectTable(table:TableElement):void {
+
+ if (table)
+ {
+ var startCoords:CellCoordinates = new CellCoordinates(0,0,table);
+ var endCoords:CellCoordinates = new CellCoordinates(table.numRows-1,table.numColumns-1,table);
+ selectCellRange(startCoords,endCoords);
+ }
+
+ }
+
+ /**
+ * Select a range of table cells.
+ **/
+ public function selectCellRange(anchorCoords:CellCoordinates, activeCoords:CellCoordinates):void
+ {
+ var blocks:Vector.<TextFlowTableBlock>;
+ var block:TextFlowTableBlock;
+ var controller:ContainerController;
+
+ if (selectionType == SelectionType.TEXT) {
+ clear();
+ }
+ clearCellSelections();
+
+ if (anchorCoords && activeCoords) {
+ _cellRange = new CellRange(_currentTable, anchorCoords, activeCoords);
+ activeCellPosition = activeCoords;
+ blocks = _currentTable.getTableBlocksInRange(anchorCoords, activeCoords);
+
+ for each(block in blocks) {
+ block.controller.clearSelectionShapes();
+ block.controller.addCellSelectionShapes(currentCellSelectionFormat.rangeColor, block, anchorCoords, activeCoords);
+ }
+ if(subManager)
+ {
+ subManager.selectRange(-1,-1);
+ subManager = null;
+ }
+ }
+ else
+ {
+ _cellRange = null;
+ activeCellPosition.column = -1;
+ activeCellPosition.row = -1;
+ }
+ selectionChanged();
+ }
+
+ public function getCellRange():CellRange
+ {
+ // not really a good implementation. We'll fix this later
+ return _cellRange;
+ }
+ public function setCellRange(range:CellRange):void
+ {
+ selectCellRange(range.anchorCoordinates,range.activeCoordinates);
+ //_cellRange = range;
+ // do something about actually drawing the selection.
+ }
// current range of selection
/** Anchor point of the current selection, as an index into the TextFlow. */
private var anchorMark:Mark;
/** Active end of the current selection, as an index into the TextFlow. */
private var activeMark:Mark;
-
- // used to save pending attributes at a point selection
+ private var _anchorCellPosition:CellCoordinates;
+ private var _activeCellPosition:CellCoordinates;
+
+ // used to save pending attributes at a point selection
private var _pointFormat:ITextLayoutFormat;
/**
* The format that will be applied to inserted text.
@@ -190,6 +504,8 @@ package flashx.textLayout.edit
_textFlow = null;
anchorMark = createMark();
activeMark = createMark();
+ anchorCellPosition = createCellMark();
+ activeCellPosition = createCellMark();
_pointFormat = null;
_isActive = false;
CONFIG::debug
@@ -197,7 +513,12 @@ package flashx.textLayout.edit
this.id = smCount.toString();
smCount++;
}
+
+ Mouse.registerCursor(SelectTable, createSelectTableCursor());
+ Mouse.registerCursor(SelectTableRow, createSelectTableRowCursor());
+ Mouse.registerCursor(SelectTableColumn, createSelectTableColumnCursor());
}
+
/**
* @copy ISelectionManager#getSelectionState()
*
@@ -211,7 +532,10 @@ package flashx.textLayout.edit
*/
public function getSelectionState():SelectionState
{
- return new SelectionState(_textFlow, anchorMark.position, activeMark.position, pointFormat);
+ if(subManager)
+ return subManager.getSelectionState();
+
+ return new SelectionState(_textFlow, anchorMark.position, activeMark.position, pointFormat, _cellRange);
}
/**
@@ -238,8 +562,45 @@ package flashx.textLayout.edit
* @langversion 3.0
*/
public function hasSelection():Boolean
- { return anchorMark.position != -1; }
+ {
+ return selectionType == SelectionType.TEXT;
+ }
+
+ /**
+ * @copy ISelectionManager#hasAnySelection()
+ *
+ * @includeExample examples\SelectionManager_hasSelection.as -noswf
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function hasAnySelection():Boolean
+ {
+ return selectionType != SelectionType.NONE;
+ }
+ /**
+ * Indicates the type of selection.
+ *
+ * <p>The <code>selectionType</code> describes the kind of selection.
+ * It can either be <code>SelectionType.TEXT</code> or <code>SelectionType.CELLS</code>
+ *
+ * @see flashx.textLayout.edit.SelectionType
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function get selectionType() : String
+ {
+ if(anchorMark.position != -1)
+ return SelectionType.TEXT;
+ else if(anchorCellPosition.isValid())
+ return SelectionType.CELLS;
+
+ return SelectionType.NONE;
+ }
/**
* @copy ISelectionManager#isRangeSelection()
*
@@ -277,6 +638,8 @@ package flashx.textLayout.edit
flushPendingOperations();
clear();
+ clearCellSelections();
+ _cellRange = null;
// If we switch into read-only mode, make sure the cursor isn't showing a text selection IBeam
if (!value) // see Watson 2637162
@@ -348,7 +711,29 @@ package flashx.textLayout.edit
}
return focusedSelectionFormat;
}
-
+
+ /**
+ * @copy ISelectionManager#currentCellSelectionFormat
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.edit.SelectionFormat
+ */
+ public function get currentCellSelectionFormat():SelectionFormat
+ {
+ if (_selFormatState == SelectionFormatState.UNFOCUSED)
+ {
+ return unfocusedCellSelectionFormat;
+ }
+ else if (_selFormatState == SelectionFormatState.INACTIVE)
+ {
+ return inactiveCellSelectionFormat;
+ }
+ return focusedCellSelectionFormat;
+ }
+
/**
* @copy ISelectionManager#focusedSelectionFormat
*
@@ -420,7 +805,79 @@ package flashx.textLayout.edit
{
return _inactiveSelectionFormat ? _inactiveSelectionFormat : (_textFlow ? _textFlow.configuration.inactiveSelectionFormat : null);
}
-
+
+ /**
+ * @copy ISelectionManager#focusedCellSelectionFormat
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.edit.SelectionFormat
+ */
+ public function set focusedCellSelectionFormat(val:SelectionFormat):void
+ {
+ _focusedCellSelectionFormat = val;
+ if (this._selFormatState == SelectionFormatState.FOCUSED)
+ refreshSelection();
+ }
+
+ /**
+ * @private - docs on setter
+ */
+ public function get focusedCellSelectionFormat():SelectionFormat
+ {
+ return _focusedCellSelectionFormat ? _focusedCellSelectionFormat : (_textFlow ? _textFlow.configuration.focusedSelectionFormat : null);
+ }
+
+ /**
+ * @copy ISelectionManager#unfocusedCellSelectionFormat
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.edit.SelectionFormat
+ */
+ public function set unfocusedCellSelectionFormat(val:SelectionFormat):void
+ {
+ _unfocusedCellSelectionFormat = val;
+ if (this._selFormatState == SelectionFormatState.UNFOCUSED)
+ refreshSelection();
+ }
+
+ /**
+ * @private - docs on setter
+ */
+ public function get unfocusedCellSelectionFormat():SelectionFormat
+ {
+ return _unfocusedCellSelectionFormat ? _unfocusedCellSelectionFormat : (_textFlow ? _textFlow.configuration.unfocusedSelectionFormat : null);
+ }
+
+ /**
+ * @copy ISelectionManager#inactiveCellSelectionFormat
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.edit.SelectionFormat
+ */
+ public function set inactiveCellSelectionFormat(val:SelectionFormat):void
+ {
+ _inactiveCellSelectionFormat = val;
+ if (this._selFormatState == SelectionFormatState.INACTIVE)
+ refreshSelection();
+ }
+
+ /**
+ * @private - docs on setter
+ */
+ public function get inactiveCellSelectionFormat():SelectionFormat
+ {
+ return _inactiveCellSelectionFormat ? _inactiveCellSelectionFormat : (_textFlow ? _textFlow.configuration.inactiveSelectionFormat : null);
+ }
+
/** @private - returns the selectionFormatState. @see flashx.textLayout.edit.SelectionFormatState */
tlf_internal function get selectionFormatState():String
{ return _selFormatState; }
@@ -584,11 +1041,17 @@ package flashx.textLayout.edit
*/
public function selectAll() : void
{
- selectRange(0, int.MAX_VALUE);
+ if(subManager)
+ subManager.selectAll();
+ else
+ {
+ var lastSelectablePos:int = (_textFlow.textLength > 0) ? _textFlow.textLength - 1 : 0;
+ selectRange(0, lastSelectablePos);
+ }
}
/**
- * @copy ISelectionManager#selectRange
+ * @copy ISelectionManager#selectRange
*
* @includeExample examples\SelectionManager_selectRange.as -noswf
*
@@ -601,22 +1064,76 @@ package flashx.textLayout.edit
public function selectRange(anchorPosition:int, activePosition:int) : void
{
flushPendingOperations();
+
+ if(subManager)
+ subManager.selectRange(-1,-1);
// anchor and active can be in any order
// TODO: range check and clamp anchor,active
if (anchorPosition != anchorMark.position || activePosition != activeMark.position)
{
clearSelectionShapes();
+ clearCellSelections();
+ _cellRange = null;
- internalSetSelection(_textFlow, anchorPosition, activePosition);
+ internalSetSelection(_textFlow, anchorPosition, activePosition, _pointFormat);
// selection changed
- selectionChanged();
+ selectionChanged();
allowOperationMerge = false;
}
}
-
+
+ /**
+ * @copy ISelectionManager#selectFirstPosition
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.compose.IFlowComposer
+ */
+ public function selectFirstPosition():void
+ {
+ selectRange(0, 0);
+ }
+
+ /**
+ * @copy ISelectionManager#selectLastPosition
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.compose.IFlowComposer
+ */
+ public function selectLastPosition():void
+ {
+ selectRange(int.MAX_VALUE, int.MAX_VALUE);
+ }
+
+ /**
+ * @copy ISelectionManager#deselect
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.compose.IFlowComposer
+ */
+ public function deselect():void
+ {
+ if (hasAnySelection())
+ {
+ clearSelectionShapes();
+ clearCellSelections();
+ addSelectionShapes();
+ }
+ selectRange(-1,-1);
+ _cellRange = null;
+ }
+
private function internalSetSelection(root:TextFlow,anchorPosition:int,activePosition:int,format:ITextLayoutFormat = null) : void
{
_textFlow = root;
@@ -627,6 +1144,8 @@ package flashx.textLayout.edit
anchorPosition = -1;
activePosition = -1;
}
+ else if(subManager)
+ subManager = null;
var lastSelectablePos:int = (_textFlow.textLength > 0) ? _textFlow.textLength - 1 : 0;
@@ -645,7 +1164,8 @@ package flashx.textLayout.edit
// trace("Selection ", anchorMark, "to", activeMark.position);
}
- /** Clear any active selections.
+ /**
+ * Clear any active selections.
*/
private function clear(): void
{
@@ -659,7 +1179,32 @@ package flashx.textLayout.edit
allowOperationMerge = false;
}
}
-
+ /**
+ * Clear any cell selections
+ * */
+ private function clearCellSelections():void
+ {
+ var blocks:Vector.<TextFlowTableBlock>;
+ var block:TextFlowTableBlock;
+ var controller:ContainerController;
+
+ if (_cellRange) {
+ blocks = _cellRange.table.getTableBlocksInRange(_cellRange.anchorCoordinates, _cellRange.activeCoordinates);
+
+ for each (block in blocks) {
+ if (controller != block.controller) {
+ block.controller.clearSelectionShapes();
+ }
+
+ controller = block.controller;
+ }
+
+ }
+ if(block)
+ block.controller.clearSelectionShapes();
+
+ //_cellRange = null;
+ }
private function addSelectionShapes():void
{
if (_textFlow.flowComposer)
@@ -677,7 +1222,7 @@ package flashx.textLayout.edit
{
_textFlow.flowComposer.getControllerAt(containerIter++).addSelectionShapes(currentSelectionFormat, absoluteStart, absoluteEnd);
}
- }
+ }
}
}
@@ -693,22 +1238,39 @@ package flashx.textLayout.edit
}
}
}
-
- /**
- * @copy ISelectionManager#refreshSelection()
- *
- * @playerversion Flash 10
- * @playerversion AIR 1.5
- * @langversion 3.0
- */
- public function refreshSelection(): void
- {
- if (hasSelection())
- {
- clearSelectionShapes();
- addSelectionShapes();
- }
- }
+
+ /**
+ * @copy ISelectionManager#refreshSelection()
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function refreshSelection(): void
+ {
+ if (hasAnySelection())
+ {
+ clearSelectionShapes();
+ clearCellSelections();
+ addSelectionShapes();
+ }
+ }
+
+ /**
+ * @copy ISelectionManager#clearSelection()
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function clearSelection(): void
+ {
+ if (hasAnySelection())
+ {
+ clearSelectionShapes();
+ clearCellSelections();
+ }
+ }
/** Verifies that the selection is in a legal state. @private */
CONFIG::debug public function debugCheckSelectionManager():int
@@ -745,7 +1307,12 @@ package flashx.textLayout.edit
_pointFormat = null;
if (doDispatchEvent && _textFlow)
- textFlow.dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, hasSelection() ? getSelectionState() : null));
+ {
+ if(textFlow.parentElement && textFlow.parentElement.getTextFlow())
+ textFlow.parentElement.getTextFlow().dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, hasSelection() ? getSelectionState() : null));
+ else
+ textFlow.dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, hasSelection() ? getSelectionState() : null));
+ }
}
// TODO: this routine could be much more efficient - instead of iterating over all lines in the TextFlow it should iterate over
@@ -771,11 +1338,14 @@ package flashx.textLayout.edit
//get the nearest column so we can ignore lines which aren't in the column we're looking for.
//if we don't do this, we won't be able to select across column boundaries.
var nearestColIdx:int = locateNearestColumn(controller, localX, localY, textFlow.computedFormat.blockProgression,textFlow.computedFormat.direction);
+
+ var prevLineBounds:Rectangle = null;
+ var previousLineIndex:int = -1;
+
+ /*
//For the table feature, we are trying to make sure if the current point is in the table and which cell it is in
- var nearestCell:TableDataCellElement = locateNearestCell(controller, localX, localY, textFlow.computedFormat.blockProgression,textFlow.computedFormat.direction);
+ var nearestCell:TableCellElement = locateNearestCell(controller, localX, localY, textFlow.computedFormat.blockProgression,textFlow.computedFormat.direction);
- var prevLineBounds:Rectangle = null;
- var previousLineIndex:int = -1;
if(nearestCell)
{
@@ -790,7 +1360,7 @@ package flashx.textLayout.edit
return cellPara.getAbsoluteStart() + cellPara.textLength - 1;
}
}
-
+ */
var lastLineIndexInColumn:int = -1;
// Matching TextFlowLine and TextLine - they are not necessarily valid
@@ -845,6 +1415,7 @@ package flashx.textLayout.edit
//current line,. Otherwise, if the click's perpendicular coordinate is below the mid point between the current
//line or below it, then we want to use the line below (ie the previous line, but logically the one after the current)
var inPrevLine:Boolean = midPerpCoor != -1 && (isTTB ? perpCoor < midPerpCoor : perpCoor > midPerpCoor);
+ /*
if(rtline.paragraph.isInTable())
{
//if rtline is the last line of the cell and the isPrevLine is true, find the cell of the column in next row
@@ -852,10 +1423,10 @@ package flashx.textLayout.edit
if ( inPrevLine && testIndex != lastLineIndexInColumn )
{
var rtPara:ParagraphElement = rtline.paragraph;
- var rtCell:TableDataCellElement = rtPara.getTableDataCellElement();
+ var rtCell:TableCellElement = rtPara.getParentCellElement();
//get the last element of the cell
var lastElement:FlowElement = rtCell.getLastLeaf();
- var rtLastTbLine:TextFlowLine = lastElement.getParagraph().getTextBlock().lastLine.userData;
+ var rtLastTbLine:TextFlowLine = lastElement ? lastElement.getParagraph().getTextBlock().lastLine.userData : null;
if( rtline == rtLastTbLine )
{
//temproray codes, need to be updated when the column apis are ready
@@ -864,7 +1435,7 @@ package flashx.textLayout.edit
var nextRow:TableRowElement = rtRow.getNextSibling() as TableRowElement;
if ( nextRow && rtCell )
{
- var nextCell:TableDataCellElement = nextRow.getChildAt(rtCell.colIndex) as TableDataCellElement;
+ var nextCell:TableCellElement = nextRow.getChildAt(rtCell.colIndex) as TableCellElement;
lineIndex = textFlow.flowComposer.findLineIndexAtPosition(nextCell.getFirstLeaf().getParagraph().getAbsoluteStart());
}
}
@@ -875,6 +1446,7 @@ package flashx.textLayout.edit
lineIndex = testIndex;
}
else
+ */
lineIndex = inPrevLine && testIndex != lastLineIndexInColumn ? testIndex+1 : testIndex;
break;
}
@@ -895,79 +1467,87 @@ package flashx.textLayout.edit
//Get a valid textLine -- check to make sure line is valid, regenerate if necessary, make sure it has correct container relative coordinates
var textFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(lineIndex);
- var textLine:TextLine = textFlowLine.getTextLine(true);
-
- // adjust localX,localY to be relative to the textLine.
- // Can't use localToGlobal/globalToLocal because textLine may not be on the display list due to virtualization
- // we may need to bring this back if textline's can be rotated or placed by any mechanism other than a translation
- // but then we'll need to provisionally place a virtualized TextLine in its parent container
- localX -= textLine.x;
- localY -= textLine.y;
- /* var localPoint:Point = DisplayObject(controller.container).localToGlobal(new Point(localX,localY));
- localPoint = textLine.globalToLocal(localPoint);
- localX = localPoint.x;
- localY = localPoint.y; */
-
-
- var startOnNextLineIfNecessary:Boolean = false;
-
- var lastAtom:int = -1;
- if (isDirectionRTL) {
- lastAtom = textLine.atomCount - 1;
- } else {
- if ((textFlowLine.absoluteStart + textFlowLine.textLength) >= textFlowLine.paragraph.getAbsoluteStart() + textFlowLine.paragraph.textLength) {
- if (textLine.atomCount > 1) lastAtom = textLine.atomCount - 2;
- } else {
- var lastLinePosInPar:int = textFlowLine.absoluteStart + textFlowLine.textLength - 1;
- var lastChar:String = textLine.textBlock.content.rawText.charAt(lastLinePosInPar);
- if (lastChar == " ") {
- if (textLine.atomCount > 1) lastAtom = textLine.atomCount - 2;
- } else {
- startOnNextLineIfNecessary = true;
- if (textLine.atomCount > 0) lastAtom = textLine.atomCount - 1;
- }
- }
- }
- var lastAtomRect:Rectangle = (lastAtom > 0) ? textLine.getAtomBounds(lastAtom) : new Rectangle(0, 0, 0, 0);
-
- if (!isTTB)
- {
- if (localX < 0)
- localX = 0;
- else if (localX > (lastAtomRect.x + lastAtomRect.width))
- {
- if (startOnNextLineIfNecessary)
- return textFlowLine.absoluteStart + textFlowLine.textLength - 1;
- if (lastAtomRect.x + lastAtomRect.width > 0)
- localX = lastAtomRect.x + lastAtomRect.width;
- }
- }
- else
- {
- if (localY < 0)
- localY = 0;
- else if (localY > (lastAtomRect.y + lastAtomRect.height))
- {
- if (startOnNextLineIfNecessary)
- return textFlowLine.absoluteStart + textFlowLine.textLength - 1;
- if (lastAtomRect.y + lastAtomRect.height > 0)
- localY = lastAtomRect.y + lastAtomRect.height;
- }
- }
-
- result = computeSelectionIndexInLine(textFlow, textLine, localX, localY);
+ if(textFlowLine is TextFlowTableBlock)
+ {
+ result = TextFlowTableBlock(textFlowLine).absoluteStart;
+ }
+ else
+ {
+ var textLine:TextLine = textFlowLine.getTextLine(true);
+
+ // adjust localX,localY to be relative to the textLine.
+ // Can't use localToGlobal/globalToLocal because textLine may not be on the display list due to virtualization
+ // we may need to bring this back if textline's can be rotated or placed by any mechanism other than a translation
+ // but then we'll need to provisionally place a virtualized TextLine in its parent container
+ localX -= textLine.x;
+ localY -= textLine.y;
+ /* var localPoint:Point = DisplayObject(controller.container).localToGlobal(new Point(localX,localY));
+ localPoint = textLine.globalToLocal(localPoint);
+ localX = localPoint.x;
+ localY = localPoint.y; */
+
+
+ var startOnNextLineIfNecessary:Boolean = false;
+
+ var lastAtom:int = -1;
+ if (isDirectionRTL) {
+ lastAtom = textLine.atomCount - 1;
+ } else {
+ if ((textFlowLine.absoluteStart + textFlowLine.textLength) >= textFlowLine.paragraph.getAbsoluteStart() + textFlowLine.paragraph.textLength) {
+ if (textLine.atomCount > 1) lastAtom = textLine.atomCount - 2;
+ } else {
+ var lastLinePosInPar:int = textFlowLine.absoluteStart + textFlowLine.textLength - 1;
+ var lastChar:String = textLine.textBlock.content.rawText.charAt(lastLinePosInPar);
+ if (lastChar == " ") {
+ if (textLine.atomCount > 1) lastAtom = textLine.atomCount - 2;
+ } else {
+ startOnNextLineIfNecessary = true;
+ if (textLine.atomCount > 0) lastAtom = textLine.atomCount - 1;
+ }
+ }
+ }
+ var lastAtomRect:Rectangle = (lastAtom > 0) ? textLine.getAtomBounds(lastAtom) : new Rectangle(0, 0, 0, 0);
+
+ if (!isTTB)
+ {
+ if (localX < 0)
+ localX = 0;
+ else if (localX > (lastAtomRect.x + lastAtomRect.width))
+ {
+ if (startOnNextLineIfNecessary)
+ return textFlowLine.absoluteStart + textFlowLine.textLength - 1;
+ if (lastAtomRect.x + lastAtomRect.width > 0)
+ localX = lastAtomRect.x + lastAtomRect.width;
+ }
+ }
+ else
+ {
+ if (localY < 0)
+ localY = 0;
+ else if (localY > (lastAtomRect.y + lastAtomRect.height))
+ {
+ if (startOnNextLineIfNecessary)
+ return textFlowLine.absoluteStart + textFlowLine.textLength - 1;
+ if (lastAtomRect.y + lastAtomRect.height > 0)
+ localY = lastAtomRect.y + lastAtomRect.height;
+ }
+ }
+
+ result = computeSelectionIndexInLine(textFlow, textLine, localX, localY);
+ }
+
// trace("computeSelectionIndexInContainer:(",origX,origY,")",textFlow.flowComposer.getControllerIndex(controller).toString(),lineIndex.toString(),result.toString());
return result != -1 ? result : firstCharVisible + length;
}
-
- static private function locateNearestCell(container:ContainerController, localX:Number, localY:Number, wm:String, direction:String):TableDataCellElement
+ /*
+ static private function locateNearestCell(container:ContainerController, localX:Number, localY:Number, wm:String, direction:String):TableCellElement
{
var cellIdx:int = 0;
//if we only have 1 column, no need to perform calculation...
var columnState:ColumnState = container.columnState;
var isFound:Boolean = false;
- var curCell:TableDataCellElement = null;
+ var curCell:TableCellElement = null;
//we need to compare the current column to the nextColmn
while(cellIdx < columnState.cellCount - 1)
@@ -984,7 +1564,7 @@ package flashx.textLayout.edit
}
return isFound? curCell : null;
}
-
+ */
static private function locateNearestColumn(container:ContainerController, localX:Number, localY:Number, wm:String, direction:String):int
{
var colIdx:int = 0;
@@ -1141,9 +1721,8 @@ package flashx.textLayout.edit
else // Left to right case, right is "end" unicode
paraSelectionIdx = leanRight ? textLine.getAtomTextBlockEndIndex(elemIdx) : textLine.getAtomTextBlockBeginIndex(elemIdx);
- //we again need to do some fixup here. Unfortunately, we don't have the index into the paragraph until
-
- return rtline.paragraph.getAbsoluteStart() + paraSelectionIdx;
+ //we again need to do some fixup here. Unfortunately, we don't have the index into the paragraph until
+ return rtline.paragraph.getTextBlockAbsoluteStart(textLine.textBlock) + paraSelectionIdx;
}
static private function checkForDisplayed(container:DisplayObject):Boolean
@@ -1164,6 +1743,142 @@ package flashx.textLayout.edit
return false; // not on the stage
}
+ /** @private - find a controller and adjusts the x and y values of localPoint if necessary */
+ private static function findController(textFlow:TextFlow, target:Object, currentTarget:Object, localPoint:Point):ContainerController
+ {
+ var localX:Number = localPoint.x;
+ var localY:Number = localPoint.y;
+ var controller:ContainerController;
+ var containerPoint:Point; // scratch
+
+ var globalPoint:Point = DisplayObject(target).localToGlobal(new Point(localX, localY));
+
+ for (var idx:int = 0; idx < textFlow.flowComposer.numControllers; idx++)
+ {
+ var testController:ContainerController = textFlow.flowComposer.getControllerAt(idx);
+ if (testController.container == target || testController.container == currentTarget)
+ {
+ controller = testController;
+ break;
+ }
+ }
+ if (controller)
+ {
+ if (target != controller.container)
+ {
+ containerPoint = DisplayObject(controller.container).globalToLocal(globalPoint);
+ localPoint.x = containerPoint.x;
+ localPoint.y = containerPoint.y;
+ }
+ return controller;
+ }
+
+ //the point is someplace else on stage. Map the target
+ //to the textFlow.container.
+ CONFIG::debug { assert(textFlow.flowComposer && textFlow.flowComposer.numControllers,"findController: invalid textFlow"); }
+
+
+
+ // result of the search
+ var controllerCandidate:ContainerController = null;
+ var candidateLocalX:Number;
+ var candidateLocalY:Number;
+ var relDistance:Number = Number.MAX_VALUE;
+
+ for (var containerIndex:int = 0; containerIndex < textFlow.flowComposer.numControllers; containerIndex++)
+ {
+ var curContainerController:ContainerController = textFlow.flowComposer.getControllerAt(containerIndex);
+
+ // displayed??
+ if (!checkForDisplayed(curContainerController.container as DisplayObject))
+ continue;
+
+ // handle measured containers??
+ var bounds:Rectangle = curContainerController.getContentBounds();
+ var containerWidth:Number = isNaN(curContainerController.compositionWidth) ? curContainerController.getTotalPaddingLeft()+bounds.width : curContainerController.compositionWidth;
+ var containerHeight:Number = isNaN(curContainerController.compositionHeight) ? curContainerController.getTotalPaddingTop()+bounds.height : curContainerController.compositionHeight;
+
+ containerPoint = DisplayObject(curContainerController.container).globalToLocal(globalPoint);
+
+ // remove scrollRect effects for the distance test but add it back in for the result
+ var adjustX:Number = 0;
+ var adjustY:Number = 0;
+
+ if (curContainerController.hasScrollRect)
+ {
+ containerPoint.x -= (adjustX = curContainerController.container.scrollRect.x);
+ containerPoint.y -= (adjustY = curContainerController.container.scrollRect.y);
+ }
+
+ if ((containerPoint.x >= 0) && (containerPoint.x <= containerWidth) &&
+ (containerPoint.y >= 0) && (containerPoint.y <= containerHeight))
+ {
+ controllerCandidate = curContainerController;
+ candidateLocalX = containerPoint.x+adjustX;
+ candidateLocalY = containerPoint.y+adjustY;
+ break;
+ }
+
+ // figure minimum distance of containerPoint to curContainerController - 8 cases
+ var relDistanceX:Number = 0;
+ var relDistanceY:Number = 0;
+
+ if (containerPoint.x < 0)
+ {
+ relDistanceX = containerPoint.x;
+ if (containerPoint.y < 0)
+ relDistanceY = containerPoint.y;
+ else if (containerPoint.y > containerHeight)
+ relDistanceY = containerPoint.y-containerHeight;
+ }
+ else if (containerPoint.x > containerWidth)
+ {
+ relDistanceX = containerPoint.x-containerWidth;
+ if (containerPoint.y < 0)
+ relDistanceY = containerPoint.y;
+ else if (containerPoint.y > containerHeight)
+ relDistanceY = containerPoint.y-containerHeight;
+ }
+ else if (containerPoint.y < 0)
+ relDistanceY = -containerPoint.y;
+ else
+ relDistanceY = containerPoint.y-containerHeight;
+ var tempDist:Number = relDistanceX*relDistanceX + relDistanceY*relDistanceY; // could do sqrt but why bother - there is no Math.hypot function
+ if (tempDist <= relDistance)
+ {
+ relDistance = tempDist;
+ controllerCandidate = curContainerController;
+ candidateLocalX = containerPoint.x+adjustX;
+ candidateLocalY = containerPoint.y+adjustY;
+ }
+ }
+ localPoint.x = candidateLocalX;
+ localPoint.y = candidateLocalY;
+ return controllerCandidate;
+
+ }
+ /** @private - given a target and location compute the CellCoordinates */
+ static tlf_internal function computeCellCoordinates(textFlow:TextFlow, target:Object, currentTarget:Object, localX:Number, localY:Number):CellCoordinates
+ {
+ var rslt:CellCoordinates;
+ var containerPoint:Point; // scratch
+
+
+ if (target is TextLine)
+ return null;
+ if(target is CellContainer)
+ {
+ var cell:TableCellElement = (target as CellContainer).element;
+ return new CellCoordinates(cell.rowIndex, cell.colIndex, cell.getTable());
+ }
+ var localPoint:Point = new Point(localX, localY);
+ var controller:ContainerController = findController(textFlow, target, currentTarget, localPoint);
+ if(!controller)
+ return null;
+
+ return controller.findCellAtPosition(localPoint);
+ }
+
/** @private - given a target and location compute the selectionIndex */
static tlf_internal function computeSelectionIndex(textFlow:TextFlow, target:Object, currentTarget:Object, localX:Number,localY:Number):int
{
@@ -1196,112 +1911,9 @@ package flashx.textLayout.edit
rslt = computeSelectionIndexInLine(textFlow, TextLine(target), localX, localY);
else
{
- var controller:ContainerController;
- for (var idx:int = 0; idx < textFlow.flowComposer.numControllers; idx++)
- {
- var testController:ContainerController = textFlow.flowComposer.getControllerAt(idx);
- if (testController.container == target || testController.container == currentTarget)
- {
- controller = testController;
- break;
- }
- }
- if (controller)
- {
- if (target != controller.container)
- {
- containerPoint = DisplayObject(target).localToGlobal(new Point(localX, localY));
- containerPoint = DisplayObject(controller.container).globalToLocal(containerPoint);
- localX = containerPoint.x;
- localY = containerPoint.y;
- }
- rslt = computeSelectionIndexInContainer(textFlow, controller, localX, localY);
- }
- else
- {
- //the point is someplace else on stage. Map the target
- //to the textFlow.container.
- CONFIG::debug { assert(textFlow.flowComposer && textFlow.flowComposer.numControllers,"computeSelectionIndex: invalid textFlow"); }
-
-
- // result of the search
- var controllerCandidate:ContainerController = null;
- var candidateLocalX:Number;
- var candidateLocalY:Number;
- var relDistance:Number = Number.MAX_VALUE;
-
- for (var containerIndex:int = 0; containerIndex < textFlow.flowComposer.numControllers; containerIndex++)
- {
- var curContainerController:ContainerController = textFlow.flowComposer.getControllerAt(containerIndex);
-
- // displayed??
- if (!checkForDisplayed(curContainerController.container as DisplayObject))
- continue;
-
- // handle measured containers??
- var bounds:Rectangle = curContainerController.getContentBounds();
- var containerWidth:Number = isNaN(curContainerController.compositionWidth) ? curContainerController.getTotalPaddingLeft()+bounds.width : curContainerController.compositionWidth;
- var containerHeight:Number = isNaN(curContainerController.compositionHeight) ? curContainerController.getTotalPaddingTop()+bounds.height : curContainerController.compositionHeight;
-
- containerPoint = DisplayObject(target).localToGlobal(new Point(localX, localY));
- containerPoint = DisplayObject(curContainerController.container).globalToLocal(containerPoint);
-
- // remove scrollRect effects for the distance test but add it back in for the result
- var adjustX:Number = 0;
- var adjustY:Number = 0;
-
- if (curContainerController.hasScrollRect)
- {
- containerPoint.x -= (adjustX = curContainerController.container.scrollRect.x);
- containerPoint.y -= (adjustY = curContainerController.container.scrollRect.y);
- }
-
- if ((containerPoint.x >= 0) && (containerPoint.x <= containerWidth) &&
- (containerPoint.y >= 0) && (containerPoint.y <= containerHeight))
- {
- controllerCandidate = curContainerController;
- candidateLocalX = containerPoint.x+adjustX;
- candidateLocalY = containerPoint.y+adjustY;
- break;
- }
-
- // figure minimum distance of containerPoint to curContainerController - 8 cases
- var relDistanceX:Number = 0;
- var relDistanceY:Number = 0;
-
- if (containerPoint.x < 0)
- {
- relDistanceX = containerPoint.x;
- if (containerPoint.y < 0)
- relDistanceY = containerPoint.y;
- else if (containerPoint.y > containerHeight)
- relDistanceY = containerPoint.y-containerHeight;
- }
- else if (containerPoint.x > containerWidth)
- {
- relDistanceX = containerPoint.x-containerWidth;
- if (containerPoint.y < 0)
- relDistanceY = containerPoint.y;
- else if (containerPoint.y > containerHeight)
- relDistanceY = containerPoint.y-containerHeight;
- }
- else if (containerPoint.y < 0)
- relDistanceY = -containerPoint.y;
- else
- relDistanceY = containerPoint.y-containerHeight;
- var tempDist:Number = relDistanceX*relDistanceX + relDistanceY*relDistanceY; // could do sqrt but why bother - there is no Math.hypot function
- if (tempDist <= relDistance)
- {
- relDistance = tempDist;
- controllerCandidate = curContainerController;
- candidateLocalX = containerPoint.x+adjustX;
- candidateLocalY = containerPoint.y+adjustY;
- }
- }
-
-
- rslt = controllerCandidate ? computeSelectionIndexInContainer(textFlow, controllerCandidate, candidateLocalX, candidateLocalY) : -1;
- }
+ var localPoint:Point = new Point(localX,localY);
+ var controller:ContainerController = findController(textFlow, target, currentTarget, localPoint);
+ rslt = controller ? computeSelectionIndexInContainer(textFlow, controller, localPoint.x, localPoint.y) : -1;
}
if (rslt >= textFlow.textLength)
@@ -1339,7 +1951,50 @@ package flashx.textLayout.edit
*/
public function mouseDownHandler(event:MouseEvent):void
{
- handleMouseEventForSelection(event, event.shiftKey);
+ if(subManager)
+ subManager.selectRange(-1,-1);
+
+ var cell:TableCellElement = _textFlow.parentElement as TableCellElement;
+ var coords:CellCoordinates;
+ if(!cell)
+ coords = computeCellCoordinates(textFlow,event.target,event.currentTarget,event.localX, event.localY);
+ if(cell || coords)
+ {
+ if(coords)
+ cell = currentTable.findCell(coords);
+
+ superManager = cell.getTextFlow().interactionManager;
+ if(event.shiftKey && cell.getTable() == superManager.currentTable)
+ {
+ // expand cell selection if applicable
+ coords = new CellCoordinates(cell.rowIndex,cell.colIndex);
+ if(
+ !CellCoordinates.areEqual(coords,superManager.anchorCellPosition) ||
+ superManager.activeCellPosition.isValid()
+ ){
+ superManager.selectCellRange(superManager.anchorCellPosition,coords);
+ superManager.subManager = null;
+ allowOperationMerge = false;
+ event.stopPropagation();
+ return;
+ }
+ }
+ if(superManager == this)
+ {
+ if(cell.textFlow.interactionManager)
+ {
+ cell.textFlow.interactionManager.mouseDownHandler(event);
+ }
+ return;
+ }
+ superManager.currentTable = cell.getTable();
+ superManager.deselect();
+ //superManager.setSelectionState(new SelectionState(superManager.textFlow,-1,-1) );
+ superManager.anchorCellPosition.column = cell.colIndex;
+ superManager.anchorCellPosition.row = cell.rowIndex;
+ superManager.subManager = this;
+ }
+ handleMouseEventForSelection(event, event.shiftKey, cell != null);
}
/**
@@ -1348,17 +2003,56 @@ package flashx.textLayout.edit
* @playerversion AIR 1.5
* @langversion 3.0
*/
- public function mouseMoveHandler(event:MouseEvent):void
- {
+ public function mouseMoveHandler(event:MouseEvent):void {
var wmode:String = textFlow.computedFormat.blockProgression;
- if (wmode != BlockProgression.RL)
- setMouseCursor(MouseCursor.IBEAM);
+
+ if (wmode != BlockProgression.RL) {
+ setMouseCursor(MouseCursor.IBEAM);
+ }
+
+
if (event.buttonDown)
- handleMouseEventForSelection(event, true);
+ {
+ var cell:TableCellElement = _textFlow.parentElement as TableCellElement;
+
+ // if the event is owned by a cell, we need to check if the mouse is now above another cell to select a cell range.
+ if (cell) {
+
+ do {
+ var cellCoords:CellCoordinates = new CellCoordinates(cell.rowIndex, cell.colIndex, cell.getTable());
+ var coords:CellCoordinates = computeCellCoordinates(cell.getTextFlow(), event.target, event.currentTarget, event.localX, event.localY);
+ if(!coords)
+ break;
+ if(CellCoordinates.areEqual(cellCoords, coords) &&
+ (!superManager.activeCellPosition.isValid() || CellCoordinates.areEqual(coords, superManager.activeCellPosition))
+ )
+ break;
+ if(coords.table != cellCoords.table)
+ break;
+
+ superManager = cell.getTextFlow().interactionManager;
+ if(
+ !CellCoordinates.areEqual(coords, superManager.activeCellPosition)
+ ){
+ allowOperationMerge = false;
+ superManager.selectCellRange(superManager.anchorCellPosition, coords);
+ event.stopPropagation();
+ return;
+ }
+
+
+ }while(0);
+ }
+ if(superManager && superManager.getCellRange())
+ return;
+
+ handleMouseEventForSelection(event, true, _textFlow.parentElement != null);
+
+ }
}
/** @private */
- tlf_internal function handleMouseEventForSelection(event:MouseEvent, allowExtend:Boolean):void
+ tlf_internal function handleMouseEventForSelection(event:MouseEvent, allowExtend:Boolean,stopPropogate:Boolean=false):void
{
var startSelectionActive:Boolean = hasSelection();
@@ -1371,6 +2065,8 @@ package flashx.textLayout.edit
addSelectionShapes();
}
allowOperationMerge = false;
+ if(stopPropogate)
+ event.stopPropagation();
}
/**
@@ -1479,10 +2175,60 @@ package flashx.textLayout.edit
{
_mouseOverSelectionArea = true;
var wmode:String = textFlow.computedFormat.blockProgression;
- if (wmode != BlockProgression.RL)
- setMouseCursor(MouseCursor.IBEAM);
- else
- setMouseCursor(MouseCursor.AUTO);
+
+ if (wmode != BlockProgression.RL) {
+ var cell:TableCellElement = _textFlow.parentElement as TableCellElement;
+
+ // set the cursor if around the edge of the table
+ if (cell) {
+ var leftEdge:int = 5;
+ var topEdge:int = 5;
+ var globalPoint:Point = new Point(event.stageX, event.stageY);
+ var cellContainer:CellContainer = event.currentTarget as CellContainer;
+ var point:Point;
+
+ if (cellContainer) {
+ var cellContainerPoint:Point = cellContainer.localToGlobal(new Point);
+ point = globalPoint.subtract(cellContainerPoint);
+ }
+ if(useTableSelectionCursors)
+ {
+ // set cursor for row, table or column
+ if (cell.colIndex==0 && point.x<leftEdge && point.y>topEdge)
+ {
+ event.stopPropagation();
+ event.stopImmediatePropagation();
+ setMouseCursor(SelectTableRow);
+ }
+ else if (cell.rowIndex==0 && cell.colIndex==0 &&
+ point.x<leftEdge && point.y<topEdge)
+ {
+ event.stopPropagation();
+ event.stopImmediatePropagation();
+ setMouseCursor(SelectTable);
+ }
+ else if (cell.rowIndex==0 && point.x>leftEdge && point.y<topEdge)
+ {
+ event.stopPropagation();
+ event.stopImmediatePropagation();
+ setMouseCursor(SelectTableColumn);
+ }
+ else {
+ setMouseCursor(MouseCursor.IBEAM);
+ }
+
+ }
+ else {
+ setMouseCursor(MouseCursor.IBEAM);
+ }
+ }
+ else {
+ setMouseCursor(MouseCursor.IBEAM);
+ }
+ }
+ else {
+ setMouseCursor(MouseCursor.AUTO);
+ }
}
/**
@@ -1873,6 +2619,9 @@ package flashx.textLayout.edit
}
else if (event.keyCode == Keyboard.ESCAPE)
handleKeyEvent(event);
+ if(_textFlow.parentElement)
+ event.stopPropagation();
+
}
/**
@@ -2098,9 +2847,26 @@ package flashx.textLayout.edit
{
var idx:int = marks.indexOf(mark);
if (idx != -1)
- marks.splice(idx,idx+1);
+ marks.splice(idx,1);
}
-
+
+ private var cellMarks:Array = [];
+
+ /** @private */
+ tlf_internal function createCellMark():CellCoordinates
+ {
+ var mark:CellCoordinates = new CellCoordinates(-1,-1);
+ cellMarks.push(mark);
+ return mark;
+ }
+ /** @private */
+ tlf_internal function removeCellMark(mark:CellCoordinates):void
+ {
+ var idx:int = cellMarks.indexOf(mark);
+ if (idx != -1)
+ marks.splice(idx,1);
+ }
+
/**
* @copy ISelectionManager#notifyInsertOrDelete()
*
@@ -2126,5 +2892,138 @@ package flashx.textLayout.edit
}
}
}
+
+ /**
+ * The ISelectionManager object used to for cell selections nested within the TextFlow managed by this ISelectionManager.
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+ public function get subManager():ISelectionManager
+ {
+ return _subManager;
+ }
+ public function set subManager(value:ISelectionManager):void
+ {
+ if(_subManager)
+ _subManager.selectRange(-1,-1);
+ _subManager = value;
+ }
+ /**
+ * The ISelectionManager object used to manage the parent TextFlow of this ISelectionManager (i.e. for cell ISelectionManagers).
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+
+ public function get superManager():ISelectionManager
+ {
+ return _superManager;
+ }
+
+ public function set superManager(value:ISelectionManager):void
+ {
+ _superManager = value;
+ }
+
+ /** Anchor point of the current cell selection, as coordinates within the table. */
+ public function get anchorCellPosition():CellCoordinates
+ {
+ return _anchorCellPosition;
+ }
+ public function set anchorCellPosition(value:CellCoordinates):void
+ {
+ _anchorCellPosition = value;
+ }
+
+ /** Active end of the current cell selection, as coordinates within the table. */
+ public function get activeCellPosition():CellCoordinates
+ {
+ return _activeCellPosition;
+ }
+ public function set activeCellPosition(value:CellCoordinates):void
+ {
+ _activeCellPosition = value;
+ }
+
+ public var selectTableCursorPoints:Vector.<Number> = new <Number>[1,3, 11,3, 11,0, 12,0, 16,4, 12,8, 11,8, 11,5, 1,5, 1,3];
+ public var selectTableCursorDrawCommands:Vector.<int> = new <int>[1,2,2,2,2,2,2,2,2,2];
+
+
+ /**
+ * Create a select table cursor
+ */
+ public function createSelectTableCursor():MouseCursorData {
+ var cursorData:Vector.<BitmapData> = new Vector.<BitmapData>();
+ var cursorShape:Shape = new Shape();
+ cursorShape.graphics.beginFill(0x0, 1);
+ cursorShape.graphics.lineStyle(0, 0xFFFFFF, 1, true);
+ cursorShape.graphics.drawPath( selectTableCursorDrawCommands, selectTableCursorPoints);
+ cursorShape.graphics.endFill();
+ var transformer:Matrix = new Matrix();
+ var cursorFrame:BitmapData = new BitmapData(32, 32, true, 0);
+ var angle:int = 8;
+ var rotation:Number = 0.785398163;
+ transformer.translate(-angle,-angle);
+ transformer.rotate(rotation);
+ transformer.translate(angle, angle);
+ cursorFrame.draw(cursorShape, transformer);
+ cursorData.push(cursorFrame);
+ var mouseCursorData:MouseCursorData = new MouseCursorData();
+ mouseCursorData.data = cursorData;
+ mouseCursorData.hotSpot = new Point(16, 10);
+ mouseCursorData.frameRate = 1;
+ return mouseCursorData;
+ }
+
+ /**
+ * Create a select row cursor
+ */
+ public function createSelectTableRowCursor():MouseCursorData {
+ var cursorData:Vector.<BitmapData> = new Vector.<BitmapData>();
+ var cursorShape:Shape = new Shape();
+ cursorShape.graphics.beginFill(0x0, 1);
+ cursorShape.graphics.lineStyle(0, 0xFFFFFF, 1, true);
+ cursorShape.graphics.drawPath(selectTableCursorDrawCommands, selectTableCursorPoints);
+ cursorShape.graphics.endFill();
+ var transformer:Matrix = new Matrix();
+ var cursorFrame:BitmapData = new BitmapData(32, 32, true, 0);
+ cursorFrame.draw(cursorShape, transformer);
+ cursorData.push(cursorFrame);
+ var mouseCursorData:MouseCursorData = new MouseCursorData();
+ mouseCursorData.data = cursorData;
+ mouseCursorData.hotSpot = new Point(16, 4);
+ mouseCursorData.frameRate = 1;
+ return mouseCursorData;
+ }
+
+ /**
+ * Create a select table column cursor
+ */
+ public function createSelectTableColumnCursor():MouseCursorData {
+ var cursorData:Vector.<BitmapData> = new Vector.<BitmapData>();
+ var cursorShape:Shape = new Shape();
+ cursorShape.graphics.beginFill(0x0, 1 );
+ cursorShape.graphics.lineStyle(0, 0xFFFFFF, 1, true );
+ cursorShape.graphics.drawPath(selectTableCursorDrawCommands, selectTableCursorPoints);
+ cursorShape.graphics.endFill();
+ var transformer:Matrix = new Matrix();
+ var cursorFrame:BitmapData = new BitmapData(32, 32, true, 0);
+ var angle:int = 16;
+ var rotation:Number = 0.785398163;
+ transformer.translate(-angle,-angle);
+ transformer.rotate(rotation * 2);
+ transformer.translate(angle, angle);
+ cursorFrame.draw(cursorShape, transformer);
+ cursorData.push(cursorFrame);
+ var mouseCursorData:MouseCursorData = new MouseCursorData();
+ mouseCursorData.data = cursorData;
+ mouseCursorData.hotSpot = new Point(28, 16);
+ mouseCursorData.frameRate = 1;
+ return mouseCursorData;
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/edit/SelectionState.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/edit/SelectionState.as b/textLayout/src/flashx/textLayout/edit/SelectionState.as
index 4d500e4..379f023 100644
--- a/textLayout/src/flashx/textLayout/edit/SelectionState.as
+++ b/textLayout/src/flashx/textLayout/edit/SelectionState.as
@@ -27,6 +27,8 @@ package flashx.textLayout.edit
use namespace tlf_internal;
import flashx.textLayout.tlf_internal;
+ import flashx.textLayout.elements.CellRange;
+
use namespace tlf_internal;
/**
* The SelectionState class represents a selection in a text flow.
@@ -49,6 +51,8 @@ package flashx.textLayout.edit
/** Format that are associated with the caret position & will be applied to inserted text */
private var _pointFormat:ITextLayoutFormat;
+ private var _cellRange:CellRange;
+
private var _selectionManagerOperationState:Boolean;
/**
@@ -72,11 +76,12 @@ package flashx.textLayout.edit
* @playerversion AIR 1.5
* @langversion 3.0
*/
- public function SelectionState(root:TextFlow,anchorPosition:int,activePosition:int,format:ITextLayoutFormat = null)
+ public function SelectionState(root:TextFlow,anchorPosition:int,activePosition:int,format:ITextLayoutFormat = null,cellRange:CellRange = null)
{
super(root, anchorPosition, activePosition);
if (format)
_pointFormat = format;
+ _cellRange = cellRange;
}
/**
@@ -126,5 +131,20 @@ package flashx.textLayout.edit
/** @private */
tlf_internal function clone():SelectionState
{ return new SelectionState(textFlow,anchorPosition,activePosition,pointFormat); }
+
+ /** Range of table cells in selection (null if no cells selected)*/
+ public function get cellRange():CellRange
+ {
+ return _cellRange;
+ }
+
+ /**
+ * @private
+ */
+ public function set cellRange(value:CellRange):void
+ {
+ _cellRange = value;
+ }
+
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/edit/TextFlowEdit.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/edit/TextFlowEdit.as b/textLayout/src/flashx/textLayout/edit/TextFlowEdit.as
index 347aa53..235cd08 100644
--- a/textLayout/src/flashx/textLayout/edit/TextFlowEdit.as
+++ b/textLayout/src/flashx/textLayout/edit/TextFlowEdit.as
@@ -1114,10 +1114,14 @@ package flashx.textLayout.edit
/** if parent is a singleton element, deletes it, then repeats deletion of singletons up the parent chain. Used after paragraph merge. */
tlf_internal static function removeEmptyParentChain(parent:FlowGroupElement):IMemento
{
+ if(parent is ParagraphElement)
+ ParagraphElement(parent).removeEmptyTerminator();
var mementoList:MementoList = new MementoList(parent.getTextFlow());
while(parent && (parent.numChildren == 0))
{
var grandParent:FlowGroupElement = parent.parent;
+ if(grandParent is ParagraphElement)
+ ParagraphElement(grandParent).removeEmptyTerminator();
if(grandParent)
{
var parentIdx:int = grandParent.getChildIndex(parent);
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/elements/BackgroundManager.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/elements/BackgroundManager.as b/textLayout/src/flashx/textLayout/elements/BackgroundManager.as
index adee363..b29accf 100644
--- a/textLayout/src/flashx/textLayout/elements/BackgroundManager.as
+++ b/textLayout/src/flashx/textLayout/elements/BackgroundManager.as
@@ -32,6 +32,7 @@ package flashx.textLayout.elements
import flashx.textLayout.compose.ParcelList;
import flashx.textLayout.compose.StandardFlowComposer;
import flashx.textLayout.compose.TextFlowLine;
+ import flashx.textLayout.compose.TextFlowTableBlock;
import flashx.textLayout.container.ContainerController;
import flashx.textLayout.container.TextContainerManager;
import flashx.textLayout.debug.assert;
@@ -45,7 +46,6 @@ package flashx.textLayout.elements
use namespace tlf_internal;
- [ExcludeClass]
/** @private Manages bounds calculation and rendering of backgroundColor character format. */
public class BackgroundManager
{
@@ -109,6 +109,34 @@ package flashx.textLayout.elements
}
}
+ public static function collectTableBlock(_textFlow:TextFlow,block:TextFlowTableBlock,controller:ContainerController):void
+ {
+ // add block rect for each cell in table block
+
+ var bb:BackgroundManager;
+ var r:Rectangle;
+ var composer:IFlowComposer;
+
+ var cells:Vector.<TableCellElement> = block.getTableCells();
+ for each(var cell:TableCellElement in cells){
+ if(BackgroundManager.hasBorderOrBackground(cell))
+ {
+ if(!_textFlow.backgroundManager)
+ _textFlow.getBackgroundManager();
+ bb = _textFlow.backgroundManager;
+
+ bb.addBlockElement(cell);
+
+ var row:TableRowElement = cell.getRow();
+ r = new Rectangle(cell.x, cell.y + block.y, cell.width, row.composedHeight);
+ bb.addBlockRect(cell, r, controller);
+
+ }
+ }
+ block.y;
+
+ }
+
public static function collectBlock(_textFlow:TextFlow, elem:FlowGroupElement, _parcelList:ParcelList = null, tableComposeNotFromBeginning:Boolean = false, tableOutOfView:Boolean = false):void
{
var bb:BackgroundManager;
@@ -118,61 +146,8 @@ package flashx.textLayout.elements
if(elem)
{
- //The height of TableDataCellElement can only be identified after all the cells in the row are composed.
- //So, pick it out of the common process
- if(elem is TableRowElement)
- {
- var tabRow:TableRowElement = elem as TableRowElement;
- //for table cells
- var cell:TableDataCellElement;
- var cellParcel:Parcel;
- for(var cIdx:Number = 0; cIdx < elem.numChildren; cIdx++)
- {
- cell = elem.getChildAt(cIdx) as TableDataCellElement;
- if(BackgroundManager.hasBorderOrBackground(cell) || BackgroundManager.hasBorderOrBackground(elem))
- {
- //mark the paragraph that has border or background
- if(!_textFlow.backgroundManager)
- _textFlow.getBackgroundManager();
- bb = _textFlow.backgroundManager;
-
- //BackgroundManager should not be null here
- CONFIG::debug { assert(_textFlow.backgroundManager != null ,"BackgroundManager should not be null"); }
-
- bb.addBlockElement(cell);
-
- cellParcel = _parcelList.getParcelAt(cell.parcelIndex);
- if(cellParcel)
- {
- r = new Rectangle(cell.x, cell.y, cell.width, tabRow.height);
- bb.addBlockRect(cell, r, cellParcel.controller);
- }
- }
- }
-
- //for table rows
- /*if(BackgroundManager.hasBorderOrBackground(elem))
- {
- //mark the paragraph that has border or background
- if(!_textFlow.backgroundManager)
- _textFlow.getBackgroundManager();
- bb = _textFlow.backgroundManager;
-
- //BackgroundManager should not be null here
- CONFIG::debug { assert(_textFlow.backgroundManager != null ,"BackgroundManager should not be null"); }
-
- bb.addBlockElement(elem);
-
- var parentTable:TableElement = elem.parent as TableElement;
- var rowParcel:Parcel = _parcelList.getParcelAt(tabRow.parcelIndex);
- if(parentTable && rowParcel){
- r = new Rectangle(parentTable.x + rowParcel.x, tabRow.y + rowParcel.y, parentTable.computedWidth, tabRow.height);
- bb.addBlockRect(elem, r, rowParcel.controller);
- }
- }*/
- }
- //for the other elements
- else if(BackgroundManager.hasBorderOrBackground(elem))
+
+ if(BackgroundManager.hasBorderOrBackground(elem))
{
//mark the paragraph that has border or background
if(!_textFlow.backgroundManager)
@@ -189,61 +164,9 @@ package flashx.textLayout.elements
{
if(elem is TableElement)
{
+ // Do we need to do anything for table elements? Not sure...
var tab:TableElement = elem as TableElement;
- var parcel:Parcel;
- if(tab.numAcrossParcels == 0)
- {
- r = new Rectangle();
- parcel = _parcelList.getParcelAt(tab.originParcelIndex);
- if(parcel)
- {
- if(tableComposeNotFromBeginning)
- {
- r.x = parcel.x;
- r.y = parcel.y;
- }
- else
- {
- r.x = tab.x;
- r.y = tab.y;
- }
- r.width = tab.computedWidth;
- r.height = tab.height;
- bb.addBlockRect(elem, r, parcel.controller);
- }
- }else
- {
- for(var tIdx:Number = 0; tIdx <= tab.numAcrossParcels; tIdx++)
- {
- r = new Rectangle();
- parcel = _parcelList.getParcelAt(tab.originParcelIndex + tIdx);
- if(parcel)
- {
- if(tIdx == 0 && !tableComposeNotFromBeginning)
- {
- r.x = tab.x;
- r.y = tab.y;
- r.width = tab.computedWidth;
- r.height = tab.heightArray[tIdx];
- bb.addBlockRect(elem, r, parcel.controller, BackgroundManager.BOTTOM_EXCLUDED);
- }else if (tIdx == tab.numAcrossParcels && !tableOutOfView)
- {
- r.x = parcel.x + tab.computedFormat.marginLeft;
- r.y = parcel.y;
- r.width = tab.computedWidth;
- r.height = tab.totalRowDepth;
- bb.addBlockRect(elem, r, parcel.controller, BackgroundManager.TOP_EXCLUDED);
- }else
- {
- r.x = parcel.x + tab.computedFormat.marginLeft;
- r.y = parcel.y;
- r.width = tab.computedWidth;
- r.height = tab.heightArray[tIdx];
- bb.addBlockRect(elem, r, parcel.controller, BackgroundManager.TOP_AND_BOTTOM_EXCLUDED);
- }
- }
- }
- }
+
}
else //for elements like ParagraphElement, DivElement, ListItemElement, ListElement, TextFlow
{
@@ -461,8 +384,9 @@ package flashx.textLayout.elements
//draw background
if(style.backgroundColor != BackgroundColor.TRANSPARENT)
{
- g.lineStyle(0, style.backgroundColor, style.backgroundAlpha, true);
- g.beginFill(style.backgroundColor);
+ // The value 0 indicates hairline thickness;
+ g.lineStyle(NaN, style.backgroundColor, style.backgroundAlpha, true);
+ g.beginFill(style.backgroundColor, style.backgroundAlpha);
g.drawRect(rec.x, rec.y, rec.width, rec.height);
g.endFill();
}
@@ -577,8 +501,9 @@ package flashx.textLayout.elements
//draw background
if(style.backgroundColor != BackgroundColor.TRANSPARENT)
{
- g.lineStyle(0, style.backgroundColor, style.backgroundAlpha, true);
- g.beginFill(style.backgroundColor);
+ // The value 0 indicates hairline thickness; NaN removes line
+ g.lineStyle(NaN, style.backgroundColor, style.backgroundAlpha, true);
+ g.beginFill(style.backgroundColor, style.backgroundAlpha);
g.drawRect(rec.x, rec.y, rec.width, rec.height);
g.endFill();
}
@@ -618,7 +543,11 @@ package flashx.textLayout.elements
//draw background for span
for(var childIdx:int = 0; childIdx<controller.textLines.length; ++childIdx)
{
- var tl:TextLine = controller.textLines[childIdx];
+ var line:* = controller.textLines[childIdx];
+ // skip TextFlowTableBlocks
+ if(!(line is TextLine))
+ continue;
+ var tl:TextLine = line;
var entry:Array = _lineDict[tl];
if (entry)
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/elements/CellContainer.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/elements/CellContainer.as b/textLayout/src/flashx/textLayout/elements/CellContainer.as
index 336da5a..256c495 100644
--- a/textLayout/src/flashx/textLayout/elements/CellContainer.as
+++ b/textLayout/src/flashx/textLayout/elements/CellContainer.as
@@ -20,13 +20,37 @@ package flashx.textLayout.elements
{
import flash.display.Sprite;
- public class CellContainer extends Sprite
+ //import mx.core.IIMESupport;
+
+ public class CellContainer extends Sprite// implements IIMESupport
{
- public var userData:Object=null;
+ private var _imeMode:String;
+ private var _enableIME:Boolean;
+ public var element:TableCellElement;
+
+ public function CellContainer(imeEnabled:Boolean = true)
+ {
+ _enableIME = imeEnabled;
+ }
+
+ public function get enableIME():Boolean
+ {
+ return false;
+ }
+
+ public function set enableIME(value:Boolean):void
+ {
+ _enableIME = value;
+ }
+
+ public function get imeMode():String
+ {
+ return _imeMode;
+ }
- public function CellContainer()
+ public function set imeMode(value:String):void
{
- super();
+ _imeMode = value;
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/elements/FlowElement.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/elements/FlowElement.as b/textLayout/src/flashx/textLayout/elements/FlowElement.as
index 6ef5053..12ba288 100644
--- a/textLayout/src/flashx/textLayout/elements/FlowElement.as
+++ b/textLayout/src/flashx/textLayout/elements/FlowElement.as
@@ -805,6 +805,14 @@ package flashx.textLayout.elements
{ setStyle(styleProp,undefined); }
/**
+ * Called when an element is removed. Used for container elements to run any clean up code.
+ **/
+ tlf_internal function removed():void
+ {
+ // override in sub classes
+ }
+
+ /**
* Called whenever the model is modified. Updates the TextFlow and notifies the selection manager - if it is set.
* This method has to be called while the element is still in the flow
* @param changeType - type of change
@@ -1024,6 +1032,24 @@ package flashx.textLayout.elements
}
+ public function isInTable():Boolean
+ {
+ var tf:TextFlow = getTextFlow();
+ return tf && tf.parentElement && tf.parentElement is TableCellElement;
+ }
+
+ public function getParentCellElement():TableCellElement
+ {
+ var tf:TextFlow = getTextFlow();
+
+ if(!tf)
+ return null;
+ if(tf.parentElement && tf.parentElement is TableCellElement)
+ return tf.parentElement as TableCellElement;
+ return null;
+ }
+
+
/**
* Returns the FlowElement object that contains this FlowElement object, if this element is contained within
* an element of a particular type.
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/elements/FlowGroupElement.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/elements/FlowGroupElement.as b/textLayout/src/flashx/textLayout/elements/FlowGroupElement.as
index b02a22d..62567dd 100644
--- a/textLayout/src/flashx/textLayout/elements/FlowGroupElement.as
+++ b/textLayout/src/flashx/textLayout/elements/FlowGroupElement.as
@@ -582,7 +582,7 @@ package flashx.textLayout.elements
}
/** @private */
- tlf_internal function createContentAsGroup():GroupElement
+ tlf_internal function createContentAsGroup(pos:int=0):GroupElement
{
CONFIG::debug { assert(false,"invalid call to createContentAsGroup"); }
return null;
@@ -626,7 +626,7 @@ package flashx.textLayout.elements
*/
tlf_internal function canOwnFlowElement(elem:FlowElement):Boolean
{
- return !(elem is TextFlow) && !(elem is FlowLeafElement) && !(elem is SubParagraphGroupElementBase) && !(elem is ListItemElement);
+ return !(elem is TextFlow) && !(elem is FlowLeafElement) && !(elem is SubParagraphGroupElementBase) && !(elem is ListItemElement) && !(elem is TableElement);
}
/** @private */
@@ -687,6 +687,7 @@ package flashx.textLayout.elements
{
child = this.getChildAt(beginChildIndex);
this.modelChanged(ModelChange.ELEMENT_REMOVAL, child, child.parentRelativeStart, child.textLength);
+ child.removed();
len += child.textLength;
child.setParentAndRelativeStart(null,0);
@@ -770,8 +771,10 @@ package flashx.textLayout.elements
relStartIdx = beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart;
}
}
- if (!canOwnFlowElement(newChild))
- throw ArgumentError(GlobalSettings.resourceStringFunction("invalidChildType"));
+
+ if (!canOwnFlowElement(newChild)) {
+ throw ArgumentError(GlobalSettings.resourceStringFunction("invalidChildType") + ". " + defaultTypeName + " cannot own " + newChild.defaultTypeName);
+ }
// manage as an array or a single child
if (childrenToAdd == 0)
@@ -988,6 +991,7 @@ package flashx.textLayout.elements
parent.replaceChildren(myidx+1,myidx+1,newSibling);
}
+ newSibling.normalizeRange(0,newSibling.textLength);
return newSibling;
}
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/33df98ab/textLayout/src/flashx/textLayout/elements/FlowLeafElement.as
----------------------------------------------------------------------
diff --git a/textLayout/src/flashx/textLayout/elements/FlowLeafElement.as b/textLayout/src/flashx/textLayout/elements/FlowLeafElement.as
index 22bfe40..894a362 100644
--- a/textLayout/src/flashx/textLayout/elements/FlowLeafElement.as
+++ b/textLayout/src/flashx/textLayout/elements/FlowLeafElement.as
@@ -337,6 +337,8 @@ package flashx.textLayout.elements
{
if (!_blockElement)
createContentElement();
+ if(!_blockElement)
+ return null;
var ef:ElementFormat = _blockElement.elementFormat;
if (!ef)
return null;