topical media & game development
student-ar-fl-controls-DataGrid.ax
student-ar-fl-controls-DataGrid.ax
[swf]
flex
// Copyright 2007. Adobe Systems Incorporated. All Rights Reserved.
package fl.controls {
import fl.controls.dataGridClasses.@fileColumn;
import fl.controls.dataGridClasses.HeaderRenderer;
import fl.controls.listClasses.CellRenderer;
import fl.controls.listClasses.ICellRenderer;
import fl.controls.listClasses.ListData;
import fl.controls.ScrollPolicy;
import fl.controls.SelectableList;
import fl.controls.TextInput;
import fl.core.UIComponent;
import fl.core.InvalidationType;
import fl.data.DataProvider;
import fl.events.ScrollEvent;
import fl.events.ListEvent;
import fl.events.@fileEvent;
import fl.events.@fileEventReason;
import fl.events.DataChangeType;
import fl.events.DataChangeEvent;
import fl.managers.IFocusManager;
import fl.managers.IFocusManagerComponent;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.InteractiveObject;
import flash.display.DisplayObjectContainer
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.FocusEvent;
import flash.ui.Keyboard;
import flash.ui.Mouse;
import flash.display.DisplayObject;
import flash.utils.Dictionary;
import flash.utils.describeType;
import flash.geom.Point;
import flash.system.IME;
Dispatched after the user clicks a header cell.
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.headerRelease.1.as -noswf
@eventType fl.events.@fileEvent.HEADER_RELEASE
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="headerRelease", type="fl.events.@fileEvent")]
Dispatched after a user expands a column horizontally.
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.columnStretch.1.as -noswf
@eventType fl.events.@fileEvent.COLUMN_STRETCH
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="columnStretch", type="fl.events.@fileEvent")]
Dispatched after a user prepares to edit an item, for example,
by releasing the mouse button over the item.
@eventType fl.events.@fileEvent.ITEM_EDIT_BEGINNING
see: #event:itemEditBegin
see: #event:itemEditEnd
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="itemEditBeginning", type="fl.events.@fileEvent")]
Dispatched after the <code>editedItemPosition</code> property is set
and the item can be edited.
@eventType fl.events.@fileEvent.ITEM_EDIT_BEGIN
see: #event:itemEditBeginning
see: #event:itemEditEnd
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="itemEditBegin", type="fl.events.@fileEvent")]
Dispatched when an item editing session ends for any reason.
@eventType fl.events.@fileEvent.ITEM_EDIT_END
see: #event:itemEditBegin
see: #event:itemEditBeginning
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="itemEditEnd", type="fl.events.@fileEvent")]
Dispatched after an item receives focus.
@eventType fl.events.@fileEvent.ITEM_FOCUS_IN
see: #event:itemFocusOut
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="itemFocusIn", type="fl.events.@fileEvent")]
Dispatched after an item loses focus.
@eventType fl.events.@fileEvent.ITEM_FOCUS_OUT
see: #event:itemFocusIn
@langversion 3.0
@playerversion Flash 9.0.28.0
[Event(name="itemFocusOut", type="fl.events.@fileEvent")]
//--------------------------------------
// Styles
//--------------------------------------
The name of the class that provides the cursor that is used when
the mouse is between two column headers and the <code>resizableColumns</code>
property is set to <code>true</code>.
@default @file_columnStretchCursorSkin
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="columnStretchCursorSkin", type="Class")]
The name of the class that provides the divider that appears
between columns.
@default @file_columnDividerSkin
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="columnDividerSkin", type="Class")]
The name of the class that provides the background for each column header.
@default HeaderRenderer_upSkin
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerUpSkin", type="Class")]
The name of the class that provides the background for each column header
when the mouse is over it.
@default HeaderRenderer_overSkin
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerOverSkin", type="Class")]
The name of the class that provides the background for each column header
when the mouse is down.
@default HeaderRenderer_downSkin
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerDownSkin", type="Class")]
The name of the class that provides the background for each column header
when the component is disabled.
@default HeaderRenderer_disabledSkin
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerDisabledSkin", type="Class")]
The name of the class that provides the sort arrow when the sorted
column is in descending order.
@default HeaderSortArrow_descIcon
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerSortArrowDescSkin", type="Class")]
The name of the class that provides the sort arrow when the sorted
column is in ascending order.
@default HeaderSortArrow_ascIcon
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerSortArrowAscSkin", type="Class")]
The format to be applied to the text contained in each column header.
@default null
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerTextFormat", type="flash.text.TextFormat")]
The format to be applied to the text contained in each column header
when the component is disabled.
@default null
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerDisabledTextFormat", type="flash.text.TextFormat")]
The padding that separates the column header border from the column header
text, in pixels.
@default 5
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerTextPadding", type="Number", format="Length")]
The name of the class that provides each column header.
@default fl.controls.dataGridClasses.HeaderRenderer
@langversion 3.0
@playerversion Flash 9.0.28.0
[Style(name="headerRenderer", type="Class")]
[InspectableList("allowMultipleSelection","editable","headerHeight","horizontalLineScrollSize","horizontalPageScrollSize","horizontalScrollPolicy","resizableColumns","rowHeight","showHeaders","sortableColumns","verticalLineScrollSize","verticalPageScrollSize","verticalScrollPolicy")]
//--------------------------------------
// Class description
//--------------------------------------
The @ax-student-ar-fl-controls-DataGrid class is a list-based component that provides a grid of
rows and columns. You can specify an optional header row at the top
of the component that shows all the property names. Each row consists
of one or more columns, each of which represents a property that belongs
to the specified data object. The @ax-student-ar-fl-controls-DataGrid component is used to view data;
it is not intended to be used as a layout tool like an HTML table.
<p>A @ax-student-ar-fl-controls-DataGrid component is well suited for the display of objects that contain
multiple properties. The data that a @ax-student-ar-fl-controls-DataGrid component displays can
be contained in a DataProvider object or as an array of objects. The columns of a @ax-student-ar-fl-controls-DataGrid
component can be represented by a list of @fileColumn objects,
each of which contains information that is specific to the column.</p>
<p>The @ax-student-ar-fl-controls-DataGrid component provides the following features:</p>
<ul>
<li>Columns of different widths or identical fixed widths</li>
<li>Columns that the user can resize at run time</li>
<li>Columns that the user can reorder at run time by using ActionScript</li>
<li>Optional customizable column headers</li>
<li>Support for custom item renderers to display data other than text
in any column</li>
<li>Support for sorting data by clicking on the column that contains it</li>
</ul>
<p>The @ax-student-ar-fl-controls-DataGrid component is composed of subcomponents including ScrollBar,
HeaderRenderer, CellRenderer, @fileCellEditor, and ColumnDivider components, all of which
can be skinned during authoring or at run time.</p>
<p>The @ax-student-ar-fl-controls-DataGrid component uses the following classes that can be found in the dataGridClasses package:</p>
<ul>
<li>@fileColumn: Describes a column in a @ax-student-ar-fl-controls-DataGrid component. Contains the indexes,
widths, and other properties of the column. Does not contain cell data.</li>
<li>HeaderRenderer: Displays the column header for the current @ax-student-ar-fl-controls-DataGrid column. Contains
the label and other properties of the column header.</li>
<li>@fileCellEditor: Manages the editing of the data for each cell.</li>
</ul>
@includeExample examples/@fileExample.as
see: fl.controls.dataGridClasses.@fileCellEditor @fileCellEditor
see: fl.controls.dataGridClasses.@fileColumn @fileColumn
see: fl.controls.dataGridClasses.HeaderRenderer HeaderRenderer
see: fl.controls.listClasses.CellRenderer CellRenderer
see: fl.events.@fileEvent @fileEvent
@langversion 3.0
@playerversion Flash 9.0.28.0
public class @ax-student-ar-fl-controls-DataGrid extends SelectableList implements IFocusManagerComponent {
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _rowHeight:Number = 20;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _headerHeight:Number = 25;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _showHeaders:Boolean = true;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _columns:Array;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _minColumnWidth:Number;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var header:Sprite;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var headerMask:Sprite;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var headerSortArrow:Sprite;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _cellRenderer:Object;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _headerRenderer:Object;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _labelFunction:Function;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var visibleColumns:Array;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var displayableColumns:Array;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var columnsInvalid:Boolean = true;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var minColumnWidthInvalid:Boolean = false;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var activeCellRenderersMap:Dictionary;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var availableCellRenderersMap:Dictionary;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var dragHandlesMap:Dictionary;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var columnStretchIndex:Number = -1;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var columnStretchStartX:Number;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var columnStretchStartWidth:Number;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var columnStretchCursor:Sprite;
@private (protected)
The index of the column being sorted.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _sortIndex:int = -1;
@private (protected)
The index of the last column being sorted on.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var lastSortIndex:int = -1;
@private (protected)
The direction of the current sort.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _sortDescending:Boolean = false;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var _editedItemPosition:Object;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var editedItemPositionChanged:Boolean = false;
@private (protected)
<code>undefined</code> means we've processed it, <code>null</code> means don't put up an editor
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var proposedEditedItemPosition:*;
@private (protected)
Last known position of item editor instance
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var actualRowIndex:int;
@private (protected)
Last known position of item editor instance
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var actualColIndex:int;
@private (protected)
Whether the mouse button is pressed.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var isPressed:Boolean = false;
@private (protected)
True if we want to block editing on mouseUp.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var losingFocus:Boolean = false;
@private (protected)
Stores the user set headerheight (we modify header height when dg is resized down)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var maxHeaderHeight:Number = 25;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected var currentHoveredRow:int = -1;
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
private static var defaultStyles:Object = {
headerUpSkin: "HeaderRenderer_upSkin",
headerDownSkin: "HeaderRenderer_downSkin",
headerOverSkin: "HeaderRenderer_overSkin",
headerDisabledSkin: "HeaderRenderer_disabledSkin",
headerSortArrowDescSkin:"HeaderSortArrow_descIcon",
headerSortArrowAscSkin:"HeaderSortArrow_ascIcon",
columnStretchCursorSkin:"ColumnStretch_cursor",
columnDividerSkin:null,
headerTextFormat:null,
headerDisabledTextFormat:null,
headerTextPadding:5,
headerRenderer:HeaderRenderer,
focusRectSkin:null,
focusRectPadding:null,
skin:"@file_skin"
};
@copy fl.core.UIComponent#getStyleDefinition()
@includeExample ../core/examples/UIComponent.getStyleDefinition.1.as -noswf
see: fl.core.UIComponent#getStyle() UIComponent.getStyle()
see: fl.core.UIComponent#setStyle() UIComponent.setStyle()
see: fl.managers.StyleManager StyleManager
@langversion 3.0
@playerversion Flash 9.0.28.0
public static function getStyleDefinition():Object {
return mergeStyles(defaultStyles, SelectableList.getStyleDefinition(), ScrollBar.getStyleDefinition());
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected static const HEADER_STYLES:Object = {
disabledSkin:"headerDisabledSkin",
downSkin:"headerDownSkin",
overSkin:"headerOverSkin",
upSkin:"headerUpSkin",
textFormat: "headerTextFormat",
disabledTextFormat: "headerDisabledTextFormat",
textPadding: "headerTextPadding"
};
@private
Creates the Accessibility class.
This method is called from UIComponent.
@langversion 3.0
@playerversion Flash 9.0.28.0
public static var createAccessibilityImplementation:Function;
Creates a new @ax-student-ar-fl-controls-DataGrid component instance.
@langversion 3.0
@playerversion Flash 9.0.28.0
public function @ax-student-ar-fl-controls-DataGrid() {
super();
if (_columns == null) { _columns = []; }
_horizontalScrollPolicy = ScrollPolicy.OFF;
activeCellRenderersMap = new Dictionary(true);
availableCellRenderersMap = new Dictionary(true);
addEventListener(@fileEvent.ITEM_EDIT_BEGINNING, itemEditorItemEditBeginningHandler, false, -50);
addEventListener(@fileEvent.ITEM_EDIT_BEGIN, itemEditorItemEditBeginHandler, false, -50);
addEventListener(@fileEvent.ITEM_EDIT_END, itemEditorItemEditEndHandler, false, -50);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function set dataProvider(dataSource:DataProvider):void {
super.dataProvider = dataSource;
// if not already created, create columns from dataprovider
if (_columns == null) { _columns = []; }
if (_columns.length == 0) { createColumnsFromDataProvider(); }
// remove all existing cellrenderers
removeCellRenderers();
}
[Inspectable(defaultValue=true, verbose=1)]
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function set enabled(value:Boolean):void {
super.enabled = value;
header.mouseChildren = _enabled;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function setSize(w:Number, h:Number):void {
super.setSize(w, h);
columnsInvalid = true;
}
[Inspectable(defaultValue="off",enumeration="on,off,auto")]
Gets or sets a Boolean value that indicates whether the
horizontal scroll bar is always on. The following list describes
the valid values:
<ul>
<li><code>ScrollPolicy.ON</code>: The scroll bar is always on.</li>
<li><code>ScrollPolicy.OFF</code>: The scroll bar is always off.</li>
<li><code>ScrollPolicy.AUTO</code>: The state of the scroll bar changes
based on the parameters that are passed to the <code>setScrollBarProperties()</code>
method.</li>
</ul>
<p><strong>Note:</strong> If the combined width of the visible columns in the @ax-student-ar-fl-controls-DataGrid
component is smaller than the available width of the @ax-student-ar-fl-controls-DataGrid component, the columns may not expand to fill
the available space of the @ax-student-ar-fl-controls-DataGrid component, depending on the value of the
<code>horizontalScrollPolicy</code> property. The following list describes
these values and their effects:</p>
<ul>
<li><code>ScrollPolicy.ON</code>: The horizontal scroll bar is disabled. The columns do not expand
to fill the available space of the @ax-student-ar-fl-controls-DataGrid component.</li>
<li><code>ScrollPolicy.AUTO</code>: The horizontal scroll bar is not visible. The columns do not expand
to fill the available space of the @ax-student-ar-fl-controls-DataGrid component.</li>
</ul>
@default ScrollPolicy.OFF
see: fl.containers.BaseScrollPane#verticalScrollPolicy BaseScrollPane.verticalScrollPolicy
see: ScrollPolicy
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.horizontalScrollPolicy.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function get horizontalScrollPolicy():String {
return _horizontalScrollPolicy;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function set horizontalScrollPolicy(policy:String):void {
super.horizontalScrollPolicy = policy;
columnsInvalid = true;
}
Gets or sets an array of @fileColumn objects, one for each column that can be displayed.
If not explicitly set, the @ax-student-ar-fl-controls-DataGrid component examines the first item in the
data provider, locates its properties, and then displays those properties
in alphabetic order.
<p>You can make changes to the columns and to their order in this @fileColumn
array. After the changes are made, however, you must explicitly assign the
changed array to the <code>columns</code> property. If an explicit assignment
is not made, the set of columns that was used before will continue to be used.</p>
@default []
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.columns.1.as -noswf
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.columns.2.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get columns():Array {
return _columns.slice(0);
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set columns(value:Array):void {
// remove all existing cellrenderers
removeCellRenderers();
// add columns
_columns = [];
for (var i:uint = 0; i < value.length; i++) {
addColumn(value[i]);
}
}
Gets or sets the minimum width of a @ax-student-ar-fl-controls-DataGrid column, in pixels.
If this value is set to <code>NaN</code>, the minimum column
width can be individually set for each column of the @ax-student-ar-fl-controls-DataGrid component.
@default NaN
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.minColumnWidth.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get minColumnWidth():Number {
return _minColumnWidth;
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set minColumnWidth(value:Number):void {
_minColumnWidth = value;
columnsInvalid = true;
minColumnWidthInvalid = true;
invalidate(InvalidationType.SIZE);
}
Gets or sets a function that determines which fields of each
item to use for the label text.
@default null
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.labelFunction.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get labelFunction():Function {
return _labelFunction;
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set labelFunction(value:Function):void {
if (_labelFunction == value) { return; }
_labelFunction = value;
invalidate(InvalidationType.DATA);
}
Gets or sets the number of rows that are at least partially visible in the
list.
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.rowCount.1.as -noswf
see: SelectableList#length SelectableList.length
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function get rowCount():uint {
// This is low right now (ie. doesn't count two half items as a whole):
return Math.ceil(calculateAvailableHeight() / rowHeight);
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set rowCount(value:uint):void {
var pad:Number = Number(getStyleValue("contentPadding"));
var scrollBarHeight:Number = (_horizontalScrollPolicy == ScrollPolicy.ON || (_horizontalScrollPolicy == ScrollPolicy.AUTO && hScrollBar)) ? 15 : 0;
height = rowHeight * value + 2 * pad + scrollBarHeight + (showHeaders ? headerHeight : 0);
}
[Inspectable(defaultValue=20)]
Gets or sets the height of each row in the @ax-student-ar-fl-controls-DataGrid component, in pixels.
@default 20
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.rowHeight.1.as -noswf
see: #headerHeight
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get rowHeight():Number {
return _rowHeight;
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set rowHeight(value:Number):void {
_rowHeight = Math.max(0, value);
invalidate(InvalidationType.SIZE);
}
[Inspectable(defaultValue=25)]
Gets or sets the height of the @ax-student-ar-fl-controls-DataGrid header, in pixels.
@default 25
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.headerHeight.1.as -noswf
see: #rowHeight
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get headerHeight():Number {
return _headerHeight;
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set headerHeight(value:Number):void {
maxHeaderHeight = value;
_headerHeight = Math.max(0, value);
invalidate(InvalidationType.SIZE);
}
[Inspectable(defaultValue=true)]
Gets or sets a Boolean value that indicates whether the @ax-student-ar-fl-controls-DataGrid component shows column headers.
A value of <code>true</code> indicates that the @ax-student-ar-fl-controls-DataGrid component shows column headers; a value
of <code>false</code> indicates that it does not.
@default true
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.showHeaders.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get showHeaders():Boolean {
return _showHeaders;
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set showHeaders(value:Boolean):void {
_showHeaders = value;
invalidate(InvalidationType.SIZE);
}
Gets the index of the column to be sorted.
@default -1
see: #sortDescending
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get sortIndex():int {
return _sortIndex;
}
Gets the order in which a column is sorted when
the user clicks its header. A value of <code>true</code>
indicates that the column is sorted in descending order; a
value of <code>false</code> indicates that the column is
sorted in ascending order.
<p>The <code>sortDescending</code> property does not affect
how the sort method completes the sort operation. By default,
the sort operation involves a case-sensitive string sort.
To change this behavior, modify the <code>sortOptions</code>
and <code>sortCompareFunction</code> properties of the @fileColumn
class.</p>
<p><strong>Note:</strong> If you query this property from an event
listener for the <code>headerRelease</code> event, the property value
identifies the sort order for the previous sort operation. This
is because the next sort has not yet occurred.</p>
@default false
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.sortDescending.1.as -noswf
see: fl.controls.dataGridClasses.@fileColumn#sortOptions @fileColumn.sortOptions
see: fl.controls.dataGridClasses.@fileColumn#sortCompareFunction @fileColumn.sortCompareFunction
see: Array#sort() Array.sort()
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get sortDescending():Boolean {
return _sortDescending;
}
@copy fl.controls.TextArea#imeMode
see: flash.system.IMEConversionMode IMEConversionMode
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get imeMode():String {
return _imeMode;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set imeMode(value:String):void {
_imeMode = value;
}
[Inspectable(defaultValue=false)]
Indicates whether or not the user can edit items in the data provider.
A value of <code>true</code> indicates that the user can edit items in the
data provider; a value of <code>false</code> indicates that the user cannot.
<p>If this value is <code>true</code>, the item renderers in the component
are editable. The user can click on an item renderer to open an editor.</p>
<p>You can turn off editing for individual columns of the @ax-student-ar-fl-controls-DataGrid component
by using the <code>@fileColumn.editable</code> property, or by handling
the <code>itemEditBeginning</code> and <code>itemEditBegin</code> events.</p>
@default false
see: #event:itemEditBegin
see: #event:itemEditBeginning
see: fl.controls.dataGridClasses.@fileColumn#editable @fileColumn.editable
@langversion 3.0
@playerversion Flash 9.0.28.0
public var editable:Boolean = false;
[Inspectable(defaultValue=true)]
Indicates whether the user can change the size of the
columns. A value of <code>true</code> indicates that the user can
change the column size; a value of <code>false</code> indicates that
column size is fixed.
<p>If this value is <code>true</code>, the user can stretch or shrink
the columns of the @ax-student-ar-fl-controls-DataGrid component by dragging the grid lines between
the header cells. Additionally, if this value is <code>true</code>,
the user can change the size of the columns unless the <code>resizeable</code>
properties of individual columns are set to <code>false</code>.</p>
@default true
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.resizableColumns.1.as -noswf
see: fl.controls.dataGridClasses.@fileColumn#resizable @fileColumn.resizable
@langversion 3.0
@playerversion Flash 9.0.28.0
public var resizableColumns:Boolean = true;
[Inspectable(defaultValue=true)]
Indicates whether the user can sort the items in the data provider
by clicking on a column header cell. If this value is <code>true</code>,
the user can sort the data provider items by clicking on a column header cell;
if this value is <code>false</code>, the user cannot.
<p>If this value is <code>true</code>, to prevent an individual column
from responding to a user mouse click on a header cell, set the
<code>sortable</code> property of that column to <code>false</code>.</p>
<p>The sort field of a column is either the <code>dataField</code> or
<code>sortCompareFunction</code> property of the @fileColumn component.
If the user clicks a column more than one time, the sort operation
alternates between ascending and descending order.</p>
<p>If both this property and the <code>sortable</code> property of a
column are set to <code>true</code>, the @ax-student-ar-fl-controls-DataGrid component dispatches
a <code>headerRelease</code> event after the user releases the mouse
button of the column header cell. If a call is not made to the <code>preventDefault()</code>
method from a handler method of the <code>headerRelease</code> event,
the @ax-student-ar-fl-controls-DataGrid component performs a sort based on the values of the <code>dataField</code>
or <code>sortCompareFunction</code> properties.</p>
@default true
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.sortableColumns.1.as -noswf
see: fl.controls.dataGridClasses.@fileColumn#sortable @fileColumn.sortable
@langversion 3.0
@playerversion Flash 9.0.28.0
public var sortableColumns:Boolean = true;
A reference to the currently active instance of the item editor,
if one exists.
<p>To access the item editor instance and the new item value when an
item is being edited, use the <code>itemEditorInstance</code>
property. The <code>itemEditorInstance</code> property is not valid
until after the event listener for the <code>itemEditBegin</code>
event executes. For this reason, the <code>itemEditorInstance</code> property
is typically accessed from the event listener for the <code>itemEditEnd</code>
event.</p>
<p>The <code>@fileColumn.itemEditor</code> property defines the
class of the item editor, and therefore, the data type of the
item editor instance.</p>
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.itemEditorInstance.1.as -noswf
see: #event:itemEditBegin
see: #event:itemEditEnd
see: fl.controls.dataGridClasses.@fileColumn#itemEditor @fileColumn.itemEditor
@langversion 3.0
@playerversion Flash 9.0.28.0
public var itemEditorInstance:Object;
Gets a reference to the item renderer in the @ax-student-ar-fl-controls-DataGrid component whose item is currently being
edited. If no item is being edited, this property contains a value of <code>null</code>.
<p>You can obtain the current value of the item that is being edited by using the
<code>editedItemRenderer.data</code> property from an event listener for the
<code>itemEditBegin</code> event or the <code>itemEditEnd</code> event.</p>
<p>This is a read-only property. To set a custom item editor, use the <code>itemEditor</code>
property of the class that represents the relevant column.</p>
see: fl.controls.dataGridClasses.@fileColumn#itemEditor @fileColumn.itemEditor
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.editedItemPosition.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get editedItemRenderer():ICellRenderer {
if (!itemEditorInstance) { return null; }
return getCellRendererAt(actualRowIndex, actualColIndex);
}
Gets or sets the column and row index of the item renderer for
the data provider item that is being edited. If no item is being
edited, this property is <code>null</code>.
<p>This object has two fields:</p>
<ul>
<li><code>columnIndex</code>: The zero-based column index of the current item</li>
<li><code>rowIndex</code>: The zero-based row index of the current item</li>
</ul>
<p>For example: <code>{ columnIndex:2, rowIndex:3 }</code></p>
<p>Setting this property scrolls the item into view and dispatches the
<code>itemEditBegin</code> event to open an item editor on the specified
item renderer.</p>
@default null
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.editedItemPosition.1.as -noswf
see: #event:itemEditBegin
@langversion 3.0
@playerversion Flash 9.0.28.0
public function get editedItemPosition():Object {
if (_editedItemPosition) {
return {
rowIndex: _editedItemPosition.rowIndex,
columnIndex: _editedItemPosition.columnIndex
};
} else {
return _editedItemPosition;
}
}
@private (setter)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function set editedItemPosition(value:Object):void {
var newValue:Object = {
rowIndex: value.rowIndex,
columnIndex: value.columnIndex
};
setEditedItemPosition(newValue);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function calculateAvailableHeight():Number {
var pad:Number = Number(getStyleValue("contentPadding"));
var scrollBarHeight:Number = (_horizontalScrollPolicy == ScrollPolicy.ON || (_horizontalScrollPolicy == ScrollPolicy.AUTO && _maxHorizontalScrollPosition > 0)) ? 15 : 0;
return height - pad * 2 - scrollBarHeight - (showHeaders ? headerHeight : 0);
}
Adds a column to the end of the <code>columns</code> array.
parameter: column A String or a @fileColumn object.
returns: The @fileColumn object that was added.
see: #addColumnAt()
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.addColumn.2.as -noswf
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.addColumn.3.as -noswf
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.addColumn.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function addColumn(column:*):@fileColumn {
return addColumnAt(column, _columns.length);
}
Inserts a column at the specified index in the <code>columns</code> array.
parameter: column The string or @fileColumn object that represents the column to be inserted.
parameter: index The array index that identifies the location at which the column is to be inserted.
returns: The @fileColumn object that was inserted into the array of columns.
see: #addColumn()
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.addColumn.1.as -noswf
@langversion 3.0
@playerversion Flash 9.0.28.0
public function addColumnAt(column:*, index:uint):@fileColumn {
var dataGridColumn:@fileColumn;
if (index < _columns.length) {
// insert placeholder for new column
_columns.splice(index, 0, "");
// adjust colNums
for(var i:uint = index + 1; i < _columns.length; i++) {
dataGridColumn = _columns[i] as @fileColumn;
dataGridColumn.colNum = i;
}
}
var col:* = column;
if(!(col is @fileColumn)) {
if (col is String) {
col = new @fileColumn(col);
} else {
col = new @fileColumn();
}
}
dataGridColumn = col as @fileColumn;
dataGridColumn.owner = this;
dataGridColumn.colNum = index;
_columns[index] = dataGridColumn;
invalidate(InvalidationType.SIZE);
columnsInvalid = true;
return dataGridColumn;
}
Removes the column that is located at the specified index of the <code>columns</code> array.
parameter: index The index of the column to be removed.
returns: The @fileColumn object that was removed. This method returns null
if a column is not found at the specified index.
see: #removeAllColumns()
@langversion 3.0
@playerversion Flash 9.0.28.0
public function removeColumnAt(index:uint):@fileColumn {
var col:@fileColumn = _columns[index] as @fileColumn;
if(col != null) {
removeCellRenderersByColumn(col);
_columns.splice(index, 1);
for(var i:uint = index; i < _columns.length; i++) {
col = _columns[i] as @fileColumn;
if(col) {
col.colNum = i;
}
}
invalidate(InvalidationType.SIZE);
columnsInvalid = true;
}
return col;
}
Removes all columns from the @ax-student-ar-fl-controls-DataGrid component.
see: #removeColumnAt()
@langversion 3.0
@playerversion Flash 9.0.28.0
public function removeAllColumns():void {
if(_columns.length > 0) {
removeCellRenderers();
_columns = [];
invalidate(InvalidationType.SIZE);
columnsInvalid = true;
}
}
Retrieves the column that is located at the specified index of the <code>columns</code> array.
parameter: index The index of the column to be retrieved, or null
if a column is not found.
returns: The @fileColumn object that was found at the specified index.
see: #getColumnIndex()
@langversion 3.0
@playerversion Flash 9.0.28.0
public function getColumnAt(index:uint):@fileColumn {
return _columns[index] as @fileColumn;
}
Retrieves the index of the column of the specified name,
or -1 if no match is found.
parameter: name The data field of the column to be located.
returns: The index of the location at which the column of the
specified name is found.
see: #getColumnAt()
@langversion 3.0
@playerversion Flash 9.0.28.0
public function getColumnIndex(name:String):int {
for (var i:uint = 0; i < _columns.length; i++) {
var column:@fileColumn = _columns[i] as @fileColumn;
if(column.dataField == name) {
return i;
}
}
return -1;
}
Retrieves the number of columns in the @ax-student-ar-fl-controls-DataGrid component.
returns: The number of columns contained in the @ax-student-ar-fl-controls-DataGrid component.
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.columns.2.as -noswf
@includeExample examples/@ax-student-ar-fl-controls-DataGrid.columns.3.as -noswf
see: #rowCount
@langversion 3.0
@playerversion Flash 9.0.28.0
public function getColumnCount():uint {
return _columns.length;
}
Resets the widths of the visible columns to the same size.
@langversion 3.0
@playerversion Flash 9.0.28.0
public function spaceColumnsEqually():void {
drawNow(); // Force a redraw in case this is called before validation.
if(displayableColumns.length > 0) {
var newWidth:Number = availableWidth / displayableColumns.length;
for (var i:int = 0; i < displayableColumns.length; i++) {
var displayableColumn:@fileColumn = displayableColumns[i] as @fileColumn;
displayableColumn.width = newWidth;
}
invalidate(InvalidationType.SIZE);
columnsInvalid = true;
}
}
Edits a given field or property in the @ax-student-ar-fl-controls-DataGrid component.
parameter: index The index of the data provider item to be edited.
parameter: dataField The name of the field or property in the data provider item to be edited.
parameter: data The new data value.
@throws RangeError The specified index is less than 0 or greater than or equal to the
length of the data provider.
@langversion 3.0
@playerversion Flash 9.0.28.0
public function editField(index:uint, dataField:String, data:Object):void {
var item:Object = getItemAt(index);
item[dataField] = data;
replaceItemAt(item, index);
}
The @ax-student-ar-fl-controls-DataGrid component has multiple cells for any given item, so the <code>itemToCellRenderer</code>
method always returns <code>null</code>.
parameter: item The item in the data provider.
returns: null
.
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function itemToCellRenderer(item:Object):ICellRenderer {
return null;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function configUI():void {
useFixedHorizontalScrolling = false;
super.configUI();
headerMask = new Sprite();
var g:Graphics = headerMask.graphics;
g.beginFill(0, 0.3);
g.drawRect(0, 0, 100, 100);
g.endFill();
headerMask.visible = false;
addChild(headerMask);
header = new Sprite();
addChild(header);
header.mask = headerMask;
_horizontalScrollPolicy = ScrollPolicy.OFF;
_verticalScrollPolicy = ScrollPolicy.AUTO;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function draw():void {
var contentHeightChanged:Boolean = (contentHeight != rowHeight * length);
contentHeight = rowHeight * length;
if (isInvalid(InvalidationType.STYLES)) {
setStyles();
drawBackground();
// drawLayout is expensive, so only do it if padding has changed:
if (contentPadding != getStyleValue("contentPadding")) {
invalidate(InvalidationType.SIZE, false);
}
// redrawing all the cell renderers is even more expensive, so we really only want to do it if necessary:
if (_cellRenderer != getStyleValue("cellRenderer") || _headerRenderer != getStyleValue("headerRenderer")) {
// remove all the existing renderers:
_invalidateList();
_cellRenderer = getStyleValue("cellRenderer");
_headerRenderer = getStyleValue("headerRenderer");
}
}
if (isInvalid(InvalidationType.SIZE)) {
columnsInvalid = true;
}
if (isInvalid(InvalidationType.SIZE, InvalidationType.STATE) || contentHeightChanged) {
drawLayout();
drawDisabledOverlay();
}
if (isInvalid(InvalidationType.RENDERER_STYLES)) {
updateRendererStyles();
}
if (isInvalid(InvalidationType.STYLES,InvalidationType.SIZE,InvalidationType.DATA,InvalidationType.SCROLL,InvalidationType.SELECTED)) {
drawList();
}
updateChildren();
// not calling super.draw, because we're handling everything here. Instead we'll just call validate();
validate();
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function drawLayout():void {
vOffset = showHeaders ? headerHeight : 0;
super.drawLayout();
// if header is present, adjust masks
contentScrollRect = listHolder.scrollRect;
if(showHeaders) {
headerHeight = maxHeaderHeight;
if(Math.floor(availableHeight - headerHeight) <= 0) {
_headerHeight = availableHeight;
}
list.y = headerHeight;
// adjust the content mask to take header into account
contentScrollRect = listHolder.scrollRect;
contentScrollRect.y = contentPadding + headerHeight;
contentScrollRect.height = availableHeight-headerHeight;
listHolder.y = contentPadding + headerHeight;
// position and size the header mask
headerMask.x = contentPadding;
headerMask.y = contentPadding;
headerMask.width = availableWidth;
headerMask.height = headerHeight;
} else {
contentScrollRect.y = contentPadding;
listHolder.y = 0;
}
listHolder.scrollRect = contentScrollRect
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function drawList():void {
if(showHeaders) {
header.visible = true;
header.x = contentPadding - _horizontalScrollPosition;
header.y = contentPadding;
listHolder.y = contentPadding + headerHeight;
// adjust vertical scroller parameters to take header into account
var availHeight:Number = Math.floor(availableHeight - headerHeight);
_verticalScrollBar.setScrollProperties(availHeight, 0, contentHeight - availHeight, _verticalScrollBar.pageScrollSize);
} else {
header.visible = false;
listHolder.y = contentPadding;
}
listHolder.x = contentPadding;
contentScrollRect = listHolder.scrollRect;
contentScrollRect.x = _horizontalScrollPosition;
contentScrollRect.y = vOffset + Math.floor(_verticalScrollPosition) % rowHeight;
listHolder.scrollRect = contentScrollRect;
listHolder.cacheAsBitmap = useBitmapScrolling;
// figure out which rows we have to render:
var rowStartIndex:uint = Math.min(Math.max(length - 1, 0), Math.floor(_verticalScrollPosition / rowHeight));
var rowEndIndex:uint = Math.min(Math.max(length - 1, 0), rowStartIndex + rowCount + 1);
var x:Number;
var lastColWidth:Number;
var i:uint;
var item:Object;
var renderer:ICellRenderer;
var activeRenderers:Array;
var col:@fileColumn;
var listHovered:Boolean = list.hitTestPoint(stage.mouseX, stage.mouseY);
calculateColumnSizes();
// create a dictionary for looking up the new "displayed" items:
var itemHash:Dictionary = renderedItems = new Dictionary(true);
if(length > 0) {
for (i = rowStartIndex; i <= rowEndIndex; i++) {
itemHash[_dataProvider.getItemAt(i)] = true;
}
}
// calculate x coordinate of first visible column
x = 0;
var firstVisibleColumn:@fileColumn = visibleColumns[0] as @fileColumn;
for(i = 0; i < displayableColumns.length; i++) {
var displayableColumn:@fileColumn = displayableColumns[i] as @fileColumn;
if(displayableColumn != firstVisibleColumn) {
x += displayableColumn.width;
} else {
break;
}
}
while(header.numChildren > 0) { header.removeChildAt(0); }
dragHandlesMap = new Dictionary(true);
var rendererSprite:Sprite;
var rendererUIC:UIComponent;
var visibleColumnsIndices:Array = [];
var visibleColumnsLen:uint = visibleColumns.length;
for (var ci:uint = 0; ci < visibleColumnsLen; ci++)
{
col = visibleColumns[ci] as @fileColumn;
visibleColumnsIndices.push(col.colNum);
if(showHeaders) {
var headerRendererSkin:Object = (col.headerRenderer != null) ? col.headerRenderer : _headerRenderer;
var headerRenderer:HeaderRenderer = getDisplayObjectInstance(headerRendererSkin) as HeaderRenderer;
if (headerRenderer != null) {
headerRenderer.addEventListener(MouseEvent.CLICK, handleHeaderRendererClick, false, 0, true);
headerRenderer.x = x;
headerRenderer.y = 0;
headerRenderer.setSize(col.width, headerHeight);
headerRenderer.column = col.colNum;
headerRenderer.label = col.headerText;
header.addChildAt(headerRenderer, ci);
// set styles
copyStylesToChild(headerRenderer, HEADER_STYLES);
// set sort arrow
if((sortIndex == -1 && lastSortIndex == -1) || (col.colNum != sortIndex)) {
headerRenderer.setStyle("icon", null);
} else {
headerRenderer.setStyle("icon", sortDescending ? getStyleValue("headerSortArrowAscSkin") : getStyleValue("headerSortArrowDescSkin"));
}
// add resize drag handles
if(ci < visibleColumnsLen - 1 && resizableColumns && col.resizable) {
var dragHandle:Sprite = new Sprite();
var g:Graphics = dragHandle.graphics;
g.beginFill(0, 0);
g.drawRect(0, 0, 3, headerHeight);
g.endFill();
dragHandle.x = x + col.width - 2;
dragHandle.y = 0;
dragHandle.alpha = 0;
dragHandle.addEventListener(MouseEvent.MOUSE_OVER, handleHeaderResizeOver, false, 0, true);
dragHandle.addEventListener(MouseEvent.MOUSE_OUT, handleHeaderResizeOut, false, 0, true);
dragHandle.addEventListener(MouseEvent.MOUSE_DOWN, handleHeaderResizeDown, false, 0, true);
header.addChild(dragHandle);
dragHandlesMap[dragHandle] = col.colNum;
}
if(ci == visibleColumnsLen - 1 && _horizontalScrollPosition == 0 && availableWidth > x + col.width) {
// adjust width of rightmost column in case it doesn't
// fill the available width of the grid
lastColWidth = Math.floor(availableWidth - x);
headerRenderer.setSize(lastColWidth, headerHeight);
} else {
lastColWidth = col.width;
}
// force an immediate draw (because render event will not be called on the renderer):
headerRenderer.drawNow();
}
}
var colCellRenderer:Object = (col.cellRenderer != null) ? col.cellRenderer : _cellRenderer;
var availableRenderers:Array = availableCellRenderersMap[col];
activeRenderers = activeCellRenderersMap[col];
if(activeRenderers == null) {
activeCellRenderersMap[col] = activeRenderers = [];
}
if(availableRenderers == null) {
availableCellRenderersMap[col] = availableRenderers = [];
}
// find cell renderers that are still active, and make those that aren't active available:
var itemToRendererHash:Dictionary = new Dictionary(true);
while (activeRenderers.length > 0) {
renderer = activeRenderers.pop();
item = renderer.data;
if (itemHash[item] == null || invalidItems[item] == true) {
availableRenderers.push(renderer);
} else {
itemToRendererHash[item] = renderer;
// prevent problems with duplicate objects:
invalidItems[item] = true;
}
list.removeChild(renderer as DisplayObject);
}
// draw cell renderers:
if(length > 0) {
for (i = rowStartIndex; i <= rowEndIndex; i++) {
var reused:Boolean = false;
item = _dataProvider.getItemAt(i);
if (itemToRendererHash[item] != null) {
// existing renderer for this item we can reuse:
reused = true;
renderer = itemToRendererHash[item];
delete(itemToRendererHash[item]);
} else if (availableRenderers.length > 0) {
// recycle an old renderer:
renderer = availableRenderers.pop() as ICellRenderer;
} else {
// out of renderers, create a new one:
renderer = getDisplayObjectInstance(colCellRenderer) as ICellRenderer;
rendererSprite = renderer as Sprite;
if (rendererSprite != null) {
rendererSprite.addEventListener(MouseEvent.CLICK,handleCellRendererClick,false,0,true);
rendererSprite.addEventListener(MouseEvent.ROLL_OVER,handleCellRendererMouseEvent,false,0,true);
rendererSprite.addEventListener(MouseEvent.ROLL_OUT,handleCellRendererMouseEvent,false,0,true);
rendererSprite.addEventListener(Event.CHANGE,handleCellRendererChange,false,0,true);
rendererSprite.doubleClickEnabled = true;
rendererSprite.addEventListener(MouseEvent.DOUBLE_CLICK,handleCellRendererDoubleClick,false,0,true);
if (rendererSprite["setStyle"] != null) {
for (var n:String in rendererStyles) {
rendererSprite["setStyle"](n, rendererStyles[n]);
}
}
}
}
list.addChild(renderer as Sprite);
activeRenderers.push(renderer);
renderer.x = x;
renderer.y = rowHeight * (i - rowStartIndex);
renderer.setSize((ci == visibleColumnsLen - 1) ? lastColWidth : col.width, rowHeight);
if (!reused) {
renderer.data = item;
}
renderer.listData = new ListData(columnItemToLabel(col.colNum, item), null, this, i, i, ci);
if(listHovered && isHovered(renderer)) {
renderer.setMouseState("over");
currentHoveredRow = i;
} else {
renderer.setMouseState("up");
}
renderer.selected = (_selectedIndices.indexOf(i) != -1);
// force an immediate draw (because render event will not be called on the renderer):
if (renderer is UIComponent) {
rendererUIC = renderer as UIComponent;
rendererUIC.drawNow();
}
}
}
x += col.width;
}
// remove renderers for columns that are no longer visible
for (i = 0; i < _columns.length; i++) {
if(visibleColumnsIndices.indexOf(i) == -1) {
removeCellRenderersByColumn(_columns[i] as @fileColumn);
}
}
if (editedItemPositionChanged) {
editedItemPositionChanged = false;
commitEditedItemPosition(proposedEditedItemPosition);
proposedEditedItemPosition = undefined;
}
invalidItems = new Dictionary(true);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function updateRendererStyles():void {
var renderers:Array = [];
for (var n:Object in availableCellRenderersMap) {
renderers = renderers.concat(availableCellRenderersMap[n]);
}
for (n in activeCellRenderersMap) {
renderers = renderers.concat(activeCellRenderersMap[n]);
}
var l:uint = renderers.length;
for (var i:uint=0; i<l; i++) {
if (renderers[i]["setStyle"] == null) { continue; }
for (var m:String in updatedRendererStyles) {
renderers[i].setStyle(m, updatedRendererStyles[m]);
}
renderers[i].drawNow();
}
updatedRendererStyles = {};
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function removeCellRenderers():void {
for (var i:uint = 0; i < _columns.length; i++) {
removeCellRenderersByColumn(_columns[i] as @fileColumn);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function removeCellRenderersByColumn(col:@fileColumn):void {
if(col == null) { return; }
var activeRenderers:Array = activeCellRenderersMap[col];
if(activeRenderers != null) {
while (activeRenderers.length > 0) {
list.removeChild(activeRenderers.pop() as DisplayObject);
}
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function handleCellRendererMouseEvent(event:MouseEvent):void {
var renderer:ICellRenderer = event.target as ICellRenderer;
if(renderer) {
var row:int = renderer.listData.row;
var mouseMode:String;
if(event.type == MouseEvent.ROLL_OVER) {
mouseMode = "over";
} else if(event.type == MouseEvent.ROLL_OUT) {
mouseMode = "up";
}
if(mouseMode) {
for(var i:uint = 0; i < visibleColumns.length; i++) {
var col:@fileColumn = visibleColumns[i] as @fileColumn;
var cellRenderer:ICellRenderer = getCellRendererAt(row, col.colNum);
if(cellRenderer) {
cellRenderer.setMouseState(mouseMode);
}
if(row != currentHoveredRow) {
cellRenderer = getCellRendererAt(currentHoveredRow, col.colNum);
if(cellRenderer) {
cellRenderer.setMouseState("up");
}
}
}
}
}
super.handleCellRendererMouseEvent(event);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function isHovered(renderer:ICellRenderer):Boolean {
var rowStartIndex:uint = Math.min(Math.max(length - 1, 0), Math.floor(_verticalScrollPosition / rowHeight));
var rowYPos:Number = (renderer.listData.row - rowStartIndex) * rowHeight;
var pt:Point = list.globalToLocal(new Point(0, stage.mouseY));
return (pt.y > rowYPos) && (pt.y < rowYPos + rowHeight);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function setHorizontalScrollPosition(scroll:Number, fireEvent:Boolean = false):void {
if (scroll == _horizontalScrollPosition) { return; }
contentScrollRect = listHolder.scrollRect;
contentScrollRect.x = scroll;
listHolder.scrollRect = contentScrollRect;
list.x = 0;
header.x = -scroll;
super.setHorizontalScrollPosition(scroll, true);
invalidate(InvalidationType.SCROLL);
columnsInvalid = true;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function setVerticalScrollPosition(scroll:Number,fireEvent:Boolean=false):void {
if (itemEditorInstance) { endEdit(@fileEventReason.OTHER); }
invalidate(InvalidationType.SCROLL);
super.setVerticalScrollPosition(scroll, true);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function columnItemToLabel(columnIndex:uint, item:Object):String {
var col:@fileColumn = _columns[columnIndex] as @fileColumn;
if(col != null) {
return col.itemToLabel(item);
}
return " ";
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function calculateColumnSizes():void {
var delta:Number;
var n:int;
var i:int;
var totalWidth:Number = 0;
var col:@fileColumn;
if (_columns.length == 0) {
visibleColumns = [];
displayableColumns = [];
return;
}
if (columnsInvalid) {
columnsInvalid = false;
visibleColumns = [];
if (minColumnWidthInvalid) {
n = _columns.length;
for (i = 0; i < n; i++) {
_columns[i].minWidth = minColumnWidth;
}
minColumnWidthInvalid = false;
}
displayableColumns = null;
n = _columns.length;
for (i = 0; i < n; i++) {
if (displayableColumns && _columns[i].visible) {
displayableColumns.push(_columns[i]);
} else if (!displayableColumns && !_columns[i].visible) {
displayableColumns = new Array(i);
for (var k:int = 0; k < i; k++) {
displayableColumns[k] = _columns[k];
}
}
}
// If there are no hidden columns, displayableColumns points to
// _columns (we don't need a duplicate copy of _columns).
if (!displayableColumns) {
displayableColumns = _columns;
}
if (horizontalScrollPolicy == ScrollPolicy.OFF) {
// if no hscroll, then pack all columns in available space
n = displayableColumns.length;
for (i = 0; i < n; i++) {
visibleColumns.push(displayableColumns[i]);
}
} else {
// check which of the displayable columns are actually visible
n = displayableColumns.length;
var xCol:Number = 0;
for (i = 0; i < n; i++) {
col = displayableColumns[i] as @fileColumn;
if(xCol + col.width > _horizontalScrollPosition && xCol < _horizontalScrollPosition + availableWidth) {
visibleColumns.push(col);
}
xCol += col.width;
}
}
}
var lastColumn:@fileColumn;
var newSize:Number;
if (horizontalScrollPolicy == ScrollPolicy.OFF) {
// if no hscroll, then pack all columns in available space
var numResizable:int = 0;
var fixedWidth:Number = 0;
// count how many resizable columns and how wide they are
n = visibleColumns.length;
for (i = 0; i < n; i++) {
col = visibleColumns[i] as @fileColumn;
if (col.resizable) {
if (!isNaN(col.explicitWidth)) {
// explicit width
fixedWidth += col.width;
} else {
// implicitly resizable
numResizable++;
fixedWidth += col.minWidth;
}
} else {
// not resizable
fixedWidth += col.width;
}
totalWidth += col.width;
}
var ratio:Number;
var newTotal:Number = availableWidth;
var minWidth:Number;
if ((availableWidth > fixedWidth) && numResizable) {
// we have flexible columns and room to honor minwidths and non-resizable
// divide and distribute the excess among the resizable
n = visibleColumns.length;
for (i = 0; i < n; i++) {
col = visibleColumns[i] as @fileColumn;
if (col.resizable && isNaN(col.explicitWidth)) {
lastColumn = col;
if (totalWidth > availableWidth) {
ratio = (lastColumn.width - lastColumn.minWidth) / (totalWidth - fixedWidth);
} else {
ratio = lastColumn.width / totalWidth;
}
newSize = lastColumn.width - (totalWidth - availableWidth) * ratio;
minWidth = col.minWidth;
col.setWidth(Math.max(newSize, minWidth));
}
newTotal -= col.width;
}
if (newTotal && lastColumn) {
lastColumn.setWidth(lastColumn.width + newTotal);
}
} else {
// can't honor minwidth and non-resizables so just scale everybody
n = visibleColumns.length;
for (i = 0; i < n; i++) {
lastColumn = visibleColumns[i] as @fileColumn;
ratio = lastColumn.width / totalWidth;
newSize = availableWidth * ratio;
lastColumn.setWidth(newSize);
lastColumn.explicitWidth = NaN;
newTotal -= newSize;
}
if (newTotal && lastColumn) {
lastColumn.setWidth(lastColumn.width + newTotal);
}
}
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function calculateContentWidth():void {
var n:int;
var i:int;
var col:@fileColumn;
if (_columns.length == 0) {
contentWidth = 0;
return;
}
if (minColumnWidthInvalid) {
n = _columns.length;
for (i = 0; i < n; i++) {
col = _columns[i] as @fileColumn;
col.minWidth = minColumnWidth;
}
minColumnWidthInvalid = false;
}
if(horizontalScrollPolicy == ScrollPolicy.OFF) {
contentWidth = availableWidth;
} else {
contentWidth = 0;
n = _columns.length;
for (i = 0; i < n; i++) {
col = _columns[i] as @fileColumn;
if (col.visible) {
contentWidth += col.width;
}
}
if(!isNaN(_horizontalScrollPosition) && _horizontalScrollPosition + availableWidth > contentWidth) {
setHorizontalScrollPosition(contentWidth - availableWidth);
}
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function handleHeaderRendererClick(event:MouseEvent):void {
if (!_enabled) { return; }
var headerRenderer:HeaderRenderer = event.currentTarget as HeaderRenderer;
var columnIndex:uint = headerRenderer.column;
var column:@fileColumn = _columns[columnIndex] as @fileColumn;
if(sortableColumns && column.sortable) {
var lastSortIndexTmp:uint = _sortIndex;
_sortIndex = columnIndex;
// this event is cancellable:
var dataGridEvent:@fileEvent = new @fileEvent(
@fileEvent.HEADER_RELEASE,
false,
true,
columnIndex,
-1,
headerRenderer,
column ? column.dataField : null
);
if (!dispatchEvent(dataGridEvent) || !_selectable) {
_sortIndex = lastSortIndex;
return;
}
lastSortIndex = lastSortIndexTmp;
// sort
sortByColumn(columnIndex);
invalidate(InvalidationType.DATA);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
public function resizeColumn(columnIndex:int, w:Number):void {
if(_columns.length == 0) { return; }
var column:@fileColumn = _columns[columnIndex] as @fileColumn;
if(!column) { return; }
if (!visibleColumns || visibleColumns.length == 0) {
column.setWidth(w);
return;
}
if (w < column.minWidth) {
w = column.minWidth;
}
if (_horizontalScrollPolicy == ScrollPolicy.ON || _horizontalScrollPolicy == ScrollPolicy.AUTO) {
// hScrollBar is present, adjust the column's width
column.setWidth(w);
column.explicitWidth = w;
} else {
var index:int = getVisibleColumnIndex(column);
if(index != -1) {
// we want all cols's new widths to the right of this to be in proportion
// to what they were before the stretch.
// get the original space to the right not taken up by the column
var totalSpace:Number = 0;
var n:int = visibleColumns.length;
var visibleColumn:@fileColumn;
var lastColumn:@fileColumn;
var i:int;
var newWidth:Number;
// non-resizable columns don't count though
for (i = index + 1; i < n; i++) {
visibleColumn = visibleColumns[i] as @fileColumn;
if (visibleColumn && visibleColumn.resizable) {
totalSpace += visibleColumn.width;
}
}
var newTotalSpace:Number = column.width - w + totalSpace;
if (totalSpace) {
column.setWidth(w);
column.explicitWidth = w;
}
var totX:Number = 0;
// resize the columns to the right proportionally to what they were
for (i = index + 1; i < n; i++) {
visibleColumn = visibleColumns[i] as @fileColumn;
if (visibleColumn.resizable) {
newWidth = visibleColumn.width * newTotalSpace / totalSpace;
if (newWidth < visibleColumn.minWidth) {
newWidth = visibleColumn.minWidth;
}
visibleColumn.setWidth(newWidth);
totX += visibleColumn.width;
lastColumn = visibleColumn;
}
}
if (totX > newTotalSpace) {
// if excess then should be taken out only from changing column
// cause others would have already gone to their minimum
newWidth = column.width - totX + newTotalSpace;
if (newWidth < column.minWidth) {
newWidth = column.minWidth;
}
column.setWidth(newWidth);
} else if (lastColumn) {
// if less then should be added in last column
// dont need to check for minWidth as we are adding
lastColumn.setWidth(lastColumn.width - totX + newTotalSpace);
}
} else {
column.setWidth(w);
column.explicitWidth = w;
}
}
columnsInvalid = true;
invalidate(InvalidationType.SIZE);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function sortByColumn(index:int):void {
var col:@fileColumn = columns[index] as @fileColumn;
if (!enabled || !col || !col.sortable) { return };
var desc:Boolean = col.sortDescending;
// prepare sort options
var sortOptions:uint = col.sortOptions;
if(desc) {
sortOptions |= Array.DESCENDING;
} else {
sortOptions &= ~Array.DESCENDING;
}
// do the sort
if(col.sortCompareFunction != null) {
sortItems(col.sortCompareFunction, sortOptions);
} else {
sortItemsOn(col.dataField, sortOptions);
}
// inverse the sort order for next sort
_sortDescending = col.sortDescending = !desc;
// reset the sort order for last sorted column
if(lastSortIndex >= 0 && lastSortIndex != sortIndex) {
col = columns[lastSortIndex] as @fileColumn;
if(col != null) {
col.sortDescending = false;
}
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function createColumnsFromDataProvider():void {
_columns = [];
if(length > 0) {
var item:Object = _dataProvider.getItemAt(0);
for(var dataField:String in item) {
addColumn(dataField);
}
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function getVisibleColumnIndex(column:@fileColumn):int {
for(var i:uint = 0; i < visibleColumns.length; i++) {
if(column == visibleColumns[i]) {
return i;
}
}
return -1;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function handleHeaderResizeOver(event:MouseEvent):void {
if(columnStretchIndex == -1) {
showColumnStretchCursor();
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function handleHeaderResizeOut(event:MouseEvent):void {
if(columnStretchIndex == -1) {
showColumnStretchCursor(false);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function handleHeaderResizeDown(event:MouseEvent):void {
var dragHandle:Sprite = event.currentTarget as Sprite;
var colNum:Number = dragHandlesMap[dragHandle];
var col:@fileColumn = getColumnAt(colNum);
columnStretchIndex = colNum;
columnStretchStartX = event.stageX;
columnStretchStartWidth = col.width;
stage.addEventListener(MouseEvent.MOUSE_MOVE, handleHeaderResizeMove, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_UP, handleHeaderResizeUp, false, 0, true);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function handleHeaderResizeMove(event:MouseEvent):void {
var delta:Number = event.stageX - columnStretchStartX;
var newWidth:Number = columnStretchStartWidth + delta;
resizeColumn(columnStretchIndex, newWidth);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function handleHeaderResizeUp(event:MouseEvent):void {
var dragHandle:Sprite = event.currentTarget as Sprite;
var column:@fileColumn = _columns[columnStretchIndex] as @fileColumn;
var headerRenderer:HeaderRenderer;
for(var i:uint = 0; i < header.numChildren; i++) {
headerRenderer = header.getChildAt(i) as HeaderRenderer;
if(headerRenderer && headerRenderer.column == columnStretchIndex) {
break;
}
}
var dataGridEvent:@fileEvent = new @fileEvent(
@fileEvent.COLUMN_STRETCH,
false,
true,
columnStretchIndex,
-1,
headerRenderer,
column ? column.dataField : null
);
dispatchEvent(dataGridEvent);
columnStretchIndex = -1;
showColumnStretchCursor(false);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleHeaderResizeMove, false);
stage.removeEventListener(MouseEvent.MOUSE_UP, handleHeaderResizeUp, false);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function showColumnStretchCursor(show:Boolean = true):void {
if(columnStretchCursor == null) {
// create custom cursor
columnStretchCursor = getDisplayObjectInstance(getStyleValue("columnStretchCursorSkin")) as Sprite;
columnStretchCursor.mouseEnabled = false;
}
if(show) {
Mouse.hide();
stage.addChild(columnStretchCursor);
stage.addEventListener(MouseEvent.MOUSE_MOVE, positionColumnStretchCursor, false, 0, true);
columnStretchCursor.x = stage.mouseX;
columnStretchCursor.y = stage.mouseY;
} else {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, positionColumnStretchCursor, false);
if(stage.contains(columnStretchCursor)) {
stage.removeChild(columnStretchCursor);
}
Mouse.show();
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function positionColumnStretchCursor(event:MouseEvent):void {
columnStretchCursor.x = event.stageX;
columnStretchCursor.y = event.stageY;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function setEditedItemPosition(coord:Object):void {
editedItemPositionChanged = true;
proposedEditedItemPosition = coord;
if (coord && coord.rowIndex != selectedIndex) { selectedIndex = coord.rowIndex; }
invalidate(InvalidationType.DATA);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function commitEditedItemPosition(coord:Object):void {
if (!enabled || !editable) {
return;
}
// check if there already is an itemEditorInstance for this position
if (itemEditorInstance && coord && itemEditorInstance is IFocusManagerComponent &&
_editedItemPosition.rowIndex == coord.rowIndex &&
_editedItemPosition.columnIndex == coord.columnIndex) {
// just give focus back to the itemEditorInstance
IFocusManagerComponent(itemEditorInstance).setFocus();
return;
}
// dispose of any existing editor, saving away its data first
if (itemEditorInstance) {
var reason:String;
if (!coord) {
reason = @fileEventReason.OTHER;
} else {
if(!editedItemPosition || coord.rowIndex == editedItemPosition.rowIndex) {
reason = @fileEventReason.NEW_COLUMN;
} else {
reason = @fileEventReason.NEW_ROW;
}
}
if (!endEdit(reason) && reason != @fileEventReason.OTHER) {
return;
}
}
// store the value
_editedItemPosition = coord;
// allow setting of undefined to dispose item editor instance
if (!coord) {
return;
}
actualRowIndex = coord.rowIndex;
actualColIndex = coord.columnIndex;
if (displayableColumns.length != _columns.length) {
for (var i:int = 0; i < displayableColumns.length; i++) {
if (displayableColumns[i].colNum >= actualColIndex) {
actualColIndex = displayableColumns[i].colNum;
break;
}
}
if (i == displayableColumns.length) {
actualColIndex = 0;
}
}
// scroll item into view
scrollToPosition(actualRowIndex, actualColIndex);
// get the actual references for the column, row, and item
var renderer:ICellRenderer = getCellRendererAt(actualRowIndex, actualColIndex);
var event:@fileEvent = new @fileEvent(
@fileEvent.ITEM_EDIT_BEGIN,
false,
true,
actualColIndex,
actualRowIndex,
renderer);
dispatchEvent(event);
// user may be trying to change the focused item renderer
if (editedItemPositionChanged) {
editedItemPositionChanged = false;
commitEditedItemPosition(proposedEditedItemPosition);
proposedEditedItemPosition = undefined;
}
if (!itemEditorInstance) {
// assume that editing was cancelled
commitEditedItemPosition(null);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function itemEditorItemEditBeginningHandler(event:@fileEvent):void {
if (!event.isDefaultPrevented()) {
setEditedItemPosition( {columnIndex: event.columnIndex, rowIndex: uint(event.rowIndex) } );
} else if (!itemEditorInstance) {
_editedItemPosition = null;
// return focus to the grid w/o selecting an item
editable = false;
setFocus();
editable = true;
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function itemEditorItemEditBeginHandler(event:@fileEvent):void {
if (stage) {
// weak reference for deactivation
stage.addEventListener(Event.DEACTIVATE, deactivateHandler, false, 0, true);
}
if (!event.isDefaultPrevented()) {
createItemEditor(event.columnIndex, uint(event.rowIndex));
ICellRenderer(itemEditorInstance).listData = ICellRenderer(editedItemRenderer).listData;
ICellRenderer(itemEditorInstance).data = editedItemRenderer.data;
itemEditorInstance.imeMode = (columns[event.columnIndex].imeMode == null) ? _imeMode : columns[event.columnIndex].imeMode;
var fm:IFocusManager = focusManager;
if (itemEditorInstance is IFocusManagerComponent) {
fm.setFocus(InteractiveObject(itemEditorInstance));
}
fm.defaultButtonEnabled = false;
var event:@fileEvent = new @fileEvent(
@fileEvent.ITEM_FOCUS_IN,
false,
false,
_editedItemPosition.columnIndex,
_editedItemPosition.rowIndex,
itemEditorInstance);
dispatchEvent(event);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function itemEditorItemEditEndHandler(event:@fileEvent):void {
if (!event.isDefaultPrevented()) {
var bChanged:Boolean = false;
if (itemEditorInstance && event.reason != @fileEventReason.CANCELLED) {
var newData:Object = itemEditorInstance[_columns[event.columnIndex].editorDataField];
var property:String = _columns[event.columnIndex].dataField;
var data:Object = event.itemRenderer.data;
var typeInfo:String = "";
for each(var variable:XML in describeType(data).variable) {
if (property == variable.@name.toString()) {
typeInfo = variable.@type.toString();
break;
}
}
switch(typeInfo) {
case "String":
if (!(newData is String)) { newData = newData.toString(); }
break;
case "uint":
if (!(newData is uint)) { newData = uint(newData); }
break;
case "int":
if (!(newData is int)) { newData = int(newData); }
break;
case "Number":
if (!(newData is Number)) { newData = Number(newData); }
break;
}
if (data[property] != newData) {
bChanged = true;
data[property] = newData;
}
event.itemRenderer.data = data;
}
} else {
if (event.reason != @fileEventReason.OTHER) {
if (itemEditorInstance && _editedItemPosition) {
// edit session is continued so restore focus and selection
if (selectedIndex != _editedItemPosition.rowIndex) {
selectedIndex = _editedItemPosition.rowIndex;
}
var fm:IFocusManager = focusManager;
if (itemEditorInstance is IFocusManagerComponent) {
fm.setFocus(InteractiveObject(itemEditorInstance));
}
}
}
}
if (event.reason == @fileEventReason.OTHER || !event.isDefaultPrevented()) {
destroyItemEditor();
}
}
@private (protected)
When we get focus, focus an item renderer.
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function focusInHandler(event:FocusEvent):void {
if (event.target != this) {
return;
}
if (losingFocus) {
losingFocus = false;
return;
}
setIMEMode(true);
super.focusInHandler(event);
// don't do this if we're mouse focused
if (editable && !isPressed) {
var foundOne:Boolean = (editedItemPosition != null);
// start somewhere
if (!_editedItemPosition) {
_editedItemPosition = { rowIndex: 0, columnIndex: 0 };
for (; _editedItemPosition.columnIndex < _columns.length; _editedItemPosition.columnIndex++) {
// If the editedItemPosition is valid, focus it, otherwise find one.
var col:@fileColumn = _columns[_editedItemPosition.columnIndex] as @fileColumn;
if (col.editable && col.visible) {
foundOne = true;
break;
}
}
}
if (foundOne) {
setEditedItemPosition(_editedItemPosition);
}
}
if (editable) {
addEventListener(FocusEvent.KEY_FOCUS_CHANGE, keyFocusChangeHandler);
addEventListener(MouseEvent.MOUSE_DOWN, mouseFocusChangeHandler);
}
}
@private (protected)
When we lose focus, close the editor.
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function focusOutHandler(event:FocusEvent):void {
setIMEMode(false);
if (event.target == this) {
super.focusOutHandler(event);
}
// just leave if item editor is losing focus back to grid. Usually happens
// when someone clicks out of the editor onto a new item renderer.
if (event.relatedObject == this && itemRendererContains(itemEditorInstance, DisplayObject(event.target))) {
return;
}
// just leave if the cell renderer is losing focus to nothing while its editor exists.
// this happens when we make the cell renderer invisible as we put up the editor
// if the renderer can have focus.
if (event.relatedObject == null && itemRendererContains(editedItemRenderer, DisplayObject(event.target))) {
return;
}
// just leave if item editor is losing focus to nothing. Usually happens
// when someone clicks out of the textfield
if (event.relatedObject == null && itemRendererContains(itemEditorInstance, DisplayObject(event.target))) {
return;
}
// however, if we're losing focus to anything other than the editor or the grid
// hide the editor;
if (itemEditorInstance && (!event.relatedObject || !itemRendererContains(itemEditorInstance, event.relatedObject))) {
endEdit(@fileEventReason.OTHER);
removeEventListener(FocusEvent.KEY_FOCUS_CHANGE, keyFocusChangeHandler);
removeEventListener(MouseEvent.MOUSE_DOWN, mouseFocusChangeHandler);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function editorMouseDownHandler(event:MouseEvent):void {
if (!itemRendererContains(itemEditorInstance, DisplayObject(event.target))) {
if(event.target is ICellRenderer && contains(DisplayObject(event.target))) {
var cr:ICellRenderer = event.target as ICellRenderer;
var row:uint = cr.listData.row;
if(_editedItemPosition.rowIndex == row) {
endEdit(@fileEventReason.NEW_COLUMN);
} else {
endEdit(@fileEventReason.NEW_ROW);
}
} else {
endEdit(@fileEventReason.OTHER);
}
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function editorKeyDownHandler(event:KeyboardEvent):void {
// ESC just kills the editor, no new data
if (event.keyCode == Keyboard.ESCAPE) {
endEdit(@fileEventReason.CANCELLED);
} else if (event.ctrlKey && event.charCode == 46) {
// Check for Ctrl-.
endEdit(@fileEventReason.CANCELLED);
} else if (event.charCode == Keyboard.ENTER && event.keyCode != 229) {
// Enter edits the item, moves down a row
// The 229 keyCode is for IME compatability. When entering an IME expression,
// the enter key is down, but the keyCode is 229 instead of the enter key code.
if (endEdit(@fileEventReason.NEW_ROW)) {
findNextEnterItemRenderer(event);
}
}
}
@private (protected)
Determines the next item renderer to navigate to using the Tab key.
If the item renderer to be focused falls out of range (the end or beginning
of the grid) then move focus outside the grid.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function findNextItemRenderer(shiftKey:Boolean):Boolean {
if (!_editedItemPosition) {
return false;
}
// some other thing like a collection change has changed the
// position, so bail and wait for commit to reset the editor.
if (proposedEditedItemPosition !== undefined) {
return false;
}
var rowIndex:int = _editedItemPosition.rowIndex;
var colIndex:int = _editedItemPosition.columnIndex;
var found:Boolean = false;
var incr:int = shiftKey ? -1 : 1;
var maxIndex:int = length - 1;
// cycle till we find something worth focusing, or the end of the grid
while (!found) {
// go to next column
colIndex += incr;
if (colIndex < 0 || colIndex >= _columns.length) {
// if we fall off the end of the columns, wrap around
colIndex = (colIndex < 0) ? _columns.length - 1 : 0;
// and increment/decrement the row index
rowIndex += incr;
if (rowIndex < 0 || rowIndex > maxIndex) {
// if we've fallen off the rows, we need to leave the grid. get rid of the editor
setEditedItemPosition(null);
// set focus back to the grid so default handler will move it to the next component
losingFocus = true;
setFocus();
return false;
}
}
// if we find a visible and editable column, move to it
if (_columns[colIndex].editable && _columns[colIndex].visible) {
found = true;
// kill the old edit session
var reason:String;
if(rowIndex == _editedItemPosition.rowIndex) {
reason = @fileEventReason.NEW_COLUMN
} else {
reason = @fileEventReason.NEW_ROW
}
if (!itemEditorInstance || endEdit(reason)) {
// send event to create the new one
var dataGridEvent:@fileEvent = new @fileEvent(
@fileEvent.ITEM_EDIT_BEGINNING,
false,
true,
colIndex,
rowIndex);
dataGridEvent.dataField = _columns[colIndex].dataField;
dispatchEvent(dataGridEvent);
}
}
}
return found;
}
@private (protected)
Find the next item renderer down from the currently edited item renderer, and focus it.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function findNextEnterItemRenderer(event:KeyboardEvent):void {
if (proposedEditedItemPosition !== undefined) {
// some other thing has changed the position, so bail
// and wait for commit to reset the editor.
return;
}
var rowIndex:int = _editedItemPosition.rowIndex;
var colIndex:int = _editedItemPosition.columnIndex;
// modify direction with SHIFT (up or down)
var newIndex:int = _editedItemPosition.rowIndex + (event.shiftKey ? -1 : 1);
// only move if we're within range
if (newIndex >= 0 && newIndex < length) {
rowIndex = newIndex;
}
// send event to create the new one
var dataGridEvent:@fileEvent = new @fileEvent(
@fileEvent.ITEM_EDIT_BEGINNING,
false,
true,
colIndex,
rowIndex);
dataGridEvent.dataField = _columns[colIndex].dataField;
dispatchEvent(dataGridEvent);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function mouseFocusChangeHandler(event:MouseEvent):void {
if (itemEditorInstance &&
!event.isDefaultPrevented() &&
itemRendererContains(itemEditorInstance, DisplayObject(event.target)))
{
event.preventDefault();
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function keyFocusChangeHandler(event:FocusEvent):void {
if (event.keyCode == Keyboard.TAB && !event.isDefaultPrevented() && findNextItemRenderer(event.shiftKey)) {
event.preventDefault();
}
}
@private
Hides the itemEditorInstance.
@langversion 3.0
@playerversion Flash 9.0.28.0
private function itemEditorFocusOutHandler(event:FocusEvent):void {
if (event.relatedObject && contains(event.relatedObject)) {
return;
}
// ignore textfields losing focus on mousedowns
if (!event.relatedObject) {
return;
}
if (itemEditorInstance) {
endEdit(@fileEventReason.OTHER);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function deactivateHandler(event:Event):void {
// if stage losing activation, set focus to DG so when we get it back
// we popup an editor again
if (itemEditorInstance) {
endEdit(@fileEventReason.OTHER);
losingFocus = true;
setFocus();
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function mouseDownHandler(event:MouseEvent):void {
if (!enabled || !selectable) { return; }
isPressed = true;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function mouseUpHandler(event:MouseEvent):void {
if (!enabled || !selectable) { return; }
isPressed = false;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function handleCellRendererClick(event:MouseEvent):void {
super.handleCellRendererClick(event);
var renderer:ICellRenderer = event.currentTarget as ICellRenderer;
if (renderer && renderer.data && renderer != itemEditorInstance /*&& lastItemDown == r*/) {
var col:@fileColumn = _columns[renderer.listData.column] as @fileColumn;
if (editable && col && col.editable /*&& !dontEdit*/) {
var dgEvent:@fileEvent = new @fileEvent(
@fileEvent.ITEM_EDIT_BEGINNING,
false,
true,
renderer.listData.column,
renderer.listData.row,
renderer,
col.dataField);
dispatchEvent(dgEvent);
}
}
}
Uses the editor specified by the <code>itemEditor</code> property to
create an item editor for the item renderer at the column and row index
identified by the <code>editedItemPosition</code> property.
<p>This method sets the editor instance as the <code>itemEditorInstance</code>
property.</p>
<p>You can call this method from the event listener for the <code>itemEditBegin</code>
event. To create an editor from other code, set the <code>editedItemPosition</code>
property to generate the <code>itemEditBegin</code> event.</p>
parameter: colIndex The column index of the item to be edited in the data provider.
parameter: rowIndex The row index of the item to be edited in the data provider.
@langversion 3.0
@playerversion Flash 9.0.28.0
public function createItemEditor(colIndex:uint, rowIndex:uint):void {
if (displayableColumns.length != _columns.length) {
for (var i:int = 0; i < displayableColumns.length; i++) {
if (displayableColumns[i].colNum >= colIndex) {
colIndex = displayableColumns[i].colNum;
break;
}
}
if (i == displayableColumns.length) {
colIndex = 0;
}
}
var col:@fileColumn = _columns[colIndex] as @fileColumn;
var renderer:ICellRenderer = getCellRendererAt(rowIndex, colIndex);
// if this isn't implemented, use an input control as editor
if (!itemEditorInstance) {
itemEditorInstance = getDisplayObjectInstance(col.itemEditor);
itemEditorInstance.tabEnabled = false;
list.addChild(DisplayObject(itemEditorInstance));
}
list.setChildIndex(DisplayObject(itemEditorInstance), list.numChildren - 1);
// give it the right size, look and placement
var rendererSprite:Sprite = renderer as Sprite;
itemEditorInstance.visible = true;
itemEditorInstance.move(rendererSprite.x, rendererSprite.y);
itemEditorInstance.setSize(col.width, rowHeight);
itemEditorInstance.drawNow();
DisplayObject(itemEditorInstance).addEventListener(FocusEvent.FOCUS_OUT, itemEditorFocusOutHandler);
rendererSprite.visible = false;
// listen for keyStrokes on the itemEditorInstance (which lets the grid supervise for ESC/ENTER)
DisplayObject(itemEditorInstance).addEventListener(KeyboardEvent.KEY_DOWN, editorKeyDownHandler);
// we disappear on any mouse down outside the editor
stage.addEventListener(MouseEvent.MOUSE_DOWN, editorMouseDownHandler, true, 0, true);
}
Closes an item editor that is currently open on an item renderer. This method is
typically called from the event listener for the <code>itemEditEnd</code> event,
after a call is made to the <code>preventDefault()</code> method to prevent the
default event listener from executing.
@langversion 3.0
@playerversion Flash 9.0.28.0
public function destroyItemEditor():void {
if (itemEditorInstance) {
DisplayObject(itemEditorInstance).removeEventListener(KeyboardEvent.KEY_DOWN, editorKeyDownHandler);
stage.removeEventListener(MouseEvent.MOUSE_DOWN, editorMouseDownHandler, true);
var event:@fileEvent = new @fileEvent(
@fileEvent.ITEM_FOCUS_OUT,
false,
false,
_editedItemPosition.columnIndex,
_editedItemPosition.rowIndex,
itemEditorInstance);
dispatchEvent(event);
// FocusManager.removeHandler() does not find
// itemEditors in focusableObjects[] array
// and hence does not remove the focusRectangle
if (itemEditorInstance && itemEditorInstance is UIComponent) {
UIComponent(itemEditorInstance).drawFocus(false);
}
// must call removeChild() so FocusManager.lastFocus becomes null
list.removeChild(DisplayObject(itemEditorInstance));
DisplayObject(editedItemRenderer).visible = true;
itemEditorInstance = null;
}
}
@private (protected)
This method is called after the user finishes editing an item.
It dispatches the <code>itemEditEnd</code> event to start the process
of copying the edited data from
the <code>itemEditorInstance</code> to the data provider and hiding the <code>itemEditorInstance</code>.
returns <code>true</code> if nobody called the <code>preventDefault()</code> method.
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function endEdit(reason:String):Boolean {
if (!editedItemRenderer) {
return true;
}
//inEndEdit = true;
var event:@fileEvent = new @fileEvent(
@fileEvent.ITEM_EDIT_END,
false,
true,
editedItemPosition.columnIndex,
editedItemPosition.rowIndex,
editedItemRenderer,
_columns[editedItemPosition.columnIndex].dataField,
reason
);
dispatchEvent(event);
return !event.isDefaultPrevented();
}
Get the instance of a cell renderer at the specified position
in the @ax-student-ar-fl-controls-DataGrid.
<p><strong>Note:</strong> This method returns <code>null</code>
for positions that are not visible (i.e. scrolled out of the
view).</p>
parameter: row A row index.
parameter: column A column index.
returns: The ICellRenderer object at the specified position, or
<code>null</code> if no cell renderer exists at that position.
@langversion 3.0
@playerversion Flash 9.0.28.0
public function getCellRendererAt(row:uint, column:uint):ICellRenderer {
// get the column
var col:@fileColumn = _columns[column] as @fileColumn;
if(col != null) {
// get the active renderers for that column
var activeRenderers:Array = activeCellRenderersMap[col] as Array;
if(activeRenderers != null) {
for(var i:uint = 0; i < activeRenderers.length; i++) {
var renderer:ICellRenderer = activeRenderers[i] as ICellRenderer;
// if the row matches, return the renderer
if(renderer.listData.row == row) {
return renderer;
}
}
}
}
return null;
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function itemRendererContains(renderer:Object, object:DisplayObject):Boolean {
if (!object || !renderer || !(renderer is DisplayObjectContainer)) { return false; }
return DisplayObjectContainer(renderer).contains(object);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function handleDataChange(event:DataChangeEvent):void {
super.handleDataChange(event);
// if not already created, create columns from dataprovider
if (_columns == null) { _columns = []; }
if (_columns.length == 0) { createColumnsFromDataProvider(); }
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function keyDownHandler(event:KeyboardEvent):void {
if (!selectable || itemEditorInstance) { return; }
switch (event.keyCode) {
case Keyboard.UP:
case Keyboard.DOWN:
case Keyboard.END:
case Keyboard.HOME:
case Keyboard.PAGE_UP:
case Keyboard.PAGE_DOWN:
moveSelectionVertically(event.keyCode, event.shiftKey && _allowMultipleSelection, event.ctrlKey && _allowMultipleSelection);
break;
case Keyboard.LEFT:
case Keyboard.RIGHT:
moveSelectionHorizontally(event.keyCode, event.shiftKey && _allowMultipleSelection, event.ctrlKey && _allowMultipleSelection);
break;
case Keyboard.SPACE:
if(caretIndex == -1) {
caretIndex = 0;
}
scrollToIndex(caretIndex);
doKeySelection(caretIndex, event.shiftKey, event.ctrlKey);
break;
default:
break;
}
event.stopPropagation();
}
@private (protected)
Moves the selection in a horizontal direction in response
to the user selecting items using the left-arrow or right-arrow
keys and modifiers such as the Shift and Ctrl keys.
<p>Not implemented in List because the default list
is single column and therefore doesn't scroll horizontally.</p>
parameter: code The key that was pressed (e.g. Keyboard.LEFT)
parameter: shiftKey true
if the shift key was held down when
the keyboard key was pressed.
parameter: ctrlKey true
if the ctrl key was held down when
the keyboard key was pressed.
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function moveSelectionHorizontally(code:uint, shiftKey:Boolean, ctrlKey:Boolean):void {}
@private (protected)
Moves the selection in a vertical direction in response
to the user selecting items using the up-arrow or down-arrow
Keys and modifiers such as the Shift and Ctrl keys.
parameter: code The key that was pressed (e.g. Keyboard.DOWN)
parameter: shiftKey true
if the shift key was held down when
the keyboard key was pressed.
parameter: ctrlKey true
if the ctrl key was held down when
the keyboard key was pressed.
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function moveSelectionVertically(code:uint, shiftKey:Boolean, ctrlKey:Boolean):void {
var pageSize:int = Math.max(Math.floor(calculateAvailableHeight() / rowHeight), 1);
var newCaretIndex:int = -1;
var dir:int = 0;
switch(code) {
case Keyboard.UP:
if (caretIndex > 0) {
newCaretIndex = caretIndex - 1;
}
break;
case Keyboard.DOWN:
if (caretIndex < length - 1) {
newCaretIndex = caretIndex + 1;
}
break;
case Keyboard.PAGE_UP:
if (caretIndex > 0) {
newCaretIndex = Math.max(caretIndex - pageSize, 0);
}
break;
case Keyboard.PAGE_DOWN:
if (caretIndex < length - 1) {
newCaretIndex = Math.min(caretIndex + pageSize, length - 1);
}
break;
case Keyboard.HOME:
if (caretIndex > 0) {
newCaretIndex = 0;
}
break;
case Keyboard.END:
if (caretIndex < length - 1) {
newCaretIndex = length - 1;
}
break;
}
if(newCaretIndex >= 0) {
doKeySelection(newCaretIndex, shiftKey, ctrlKey);
scrollToSelected();
}
}
@copy fl.controls.SelectableList#scrollToIndex()
@langversion 3.0
@playerversion Flash 9.0.28.0
override public function scrollToIndex(newCaretIndex:int):void {
drawNow();
var lastVisibleItemIndex:int = Math.floor((_verticalScrollPosition + availableHeight) / rowHeight) - 1;
var firstVisibleItemIndex:int = Math.ceil(_verticalScrollPosition / rowHeight);
if(newCaretIndex < firstVisibleItemIndex) {
verticalScrollPosition = newCaretIndex * rowHeight;
} else if(newCaretIndex >= lastVisibleItemIndex) {
var scrollBarHeight:Number = (_horizontalScrollPolicy == ScrollPolicy.ON || (_horizontalScrollPolicy == ScrollPolicy.AUTO && hScrollBar)) ? 15 : 0;
verticalScrollPosition = (newCaretIndex + 1) * rowHeight - availableHeight + scrollBarHeight + (showHeaders ? headerHeight : 0);
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function scrollToPosition(rowIndex:int, columnIndex:int):void {
var oldVerticalScrollPos:Number = verticalScrollPosition;
var oldHorizontalScrollPos:Number = horizontalScrollPosition;
// adjust vertical scroll if necessary
scrollToIndex(rowIndex);
// adjust horizontal scroll if necessary
var i:uint;
var x:Number = 0;
var col:@fileColumn = _columns[columnIndex] as @fileColumn;
for(i = 0; i < displayableColumns.length; i++) {
var displayableColumn:@fileColumn = displayableColumns[i] as @fileColumn;
if(displayableColumn != col) {
x += displayableColumn.width;
} else {
break;
}
}
if(horizontalScrollPosition > x) {
horizontalScrollPosition = x;
} else if(horizontalScrollPosition + availableWidth < x + col.width) {
horizontalScrollPosition = -(availableWidth - (x + col.width));
}
if(oldVerticalScrollPos != verticalScrollPosition || oldHorizontalScrollPos != horizontalScrollPosition) {
drawNow();
}
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
protected function doKeySelection(newCaretIndex:int, shiftKey:Boolean, ctrlKey:Boolean):void {
var selChanged:Boolean = false;
if(shiftKey) {
var i:int;
var selIndices:Array = [];
var startIndex:int = lastCaretIndex;
var endIndex:int = newCaretIndex;
if(startIndex == -1) {
startIndex = caretIndex != -1 ? caretIndex : newCaretIndex;
}
if(startIndex > endIndex) {
endIndex = startIndex;
startIndex = newCaretIndex;
}
for(i = startIndex; i <= endIndex; i++) {
selIndices.push(i);
}
selectedIndices = selIndices;
caretIndex = newCaretIndex;
selChanged = true;
} else if(ctrlKey) {
// only moves the caret
caretIndex = newCaretIndex;
} else {
selectedIndex = newCaretIndex;
caretIndex = lastCaretIndex = newCaretIndex;
selChanged = true;
}
if(selChanged) {
dispatchEvent(new Event(Event.CHANGE));
}
invalidate(InvalidationType.DATA);
}
@private (protected)
@langversion 3.0
@playerversion Flash 9.0.28.0
override protected function initializeAccessibility():void {
if (@ax-student-ar-fl-controls-DataGrid.createAccessibilityImplementation != null) {
@ax-student-ar-fl-controls-DataGrid.createAccessibilityImplementation(this);
}
}
}
}
(C) Æliens
27/08/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.