You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by al...@apache.org on 2018/05/21 07:14:00 UTC
[royale-asjs] branch feature/MXRoyale updated: TileLayout.as Added
This is an automated email from the ASF dual-hosted git repository.
alinakazi pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/feature/MXRoyale by this push:
new 9f0b567 TileLayout.as Added
9f0b567 is described below
commit 9f0b5674682ba42d12f0420442e136a5c85d8c56
Author: alinakazi <AL...@GMAIL.COM>
AuthorDate: Mon May 21 00:13:58 2018 -0700
TileLayout.as Added
---
.../src/main/royale/spark/layouts/TileLayout.as | 2513 ++++++++++++++++++++
1 file changed, 2513 insertions(+)
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/TileLayout.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/TileLayout.as
new file mode 100644
index 0000000..a99ed1e
--- /dev/null
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/layouts/TileLayout.as
@@ -0,0 +1,2513 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.layouts
+{
+/* import flash.geom.Point;
+import flash.geom.Rectangle;
+
+import mx.core.ILayoutElement;
+import mx.core.IVisualElement;
+import mx.core.mx_internal;
+import mx.events.PropertyChangeEvent;
+
+import spark.components.supportClasses.GroupBase;
+import spark.core.NavigationUnit;
+import spark.layouts.supportClasses.DropLocation;
+import spark.layouts.supportClasses.LayoutBase;
+
+use namespace mx_internal;*/
+
+/**
+ * The TileLayout class arranges layout elements in columns and rows
+ * of equally-sized cells.
+ * The TileLayout class uses a number of properties that control orientation,
+ * count, size, gap and justification of the columns and the rows
+ * as well as element alignment within the cells.
+ *
+ * <p>Per-element supported constraints are
+ * <code>percentWidth</code> and <code>percentHeight</code>.
+ * Element's minimum and maximum sizes are always be respected and
+ * where possible, an element's size is limited to less then or equal
+ * of the cell size.</p>
+ *
+ * <p>When not explicitly set, the <code>columnWidth</code> property
+ * is calculated as the maximum preferred bounds width of all elements
+ * and the <code>columnHeight</code> property is calculated
+ * as the maximum preferred bounds height of all elements.</p>
+ *
+ * <p>When not explicitly set, the <code>columnCount</code> and
+ * <code>rowCount</code> properties are calculated from
+ * any explicit width and height settings for the layout target,
+ * and <code>columnWidth</code> and <code>columnHeight</code>.
+ * In case none is specified, the <code>columnCount</code> and <code>rowCount</code>
+ * values are picked so that the resulting pixel area is as square as possible.</p>
+ *
+ * <p> The measured size is calculated from the <code>columnCount</code>, <code>rowCount</code>,
+ * <code>columnWidth</code>, <code>rowHeight</code> properties and the gap sizes.</p>
+ *
+ * <p>The default measured size, when no properties were explicitly set, is
+ * as square as possible area and is large enough to fit all elements.</p>
+ *
+ * <p>In other cases the measured size may not be big enough to fit all elements.
+ * For example, when both <code>columnCount</code> and <code>rowCount</code> are explicitly set to values
+ * such that <code>columnCount</code> * <code>rowCount</code> < element count.</p>
+ *
+ * <p>The minimum measured size is calculated the same way as the measured size but
+ * it's guaranteed to encompass enough rows and columns along the minor axis to fit
+ * all elements.</p>
+ *
+ * @mxml
+ * <p>The <code><s:TileLayout></code> tag inherits all of the tag
+ * attributes of its superclass and adds the following tag attributes:</p>
+ *
+ * <pre>
+ * <s:TileLayout
+ * <strong>Properties</strong>
+ * columnAlign="left"
+ * columnWidth="NaN"
+ * horizontalAlign="justify"
+ * horizontalGap="6"
+ * orientation="rows"
+ * requestedColumnCount="-1"
+ * requestedRowCount="-1"
+ * rowAlign="top"
+ * rowCount="-1"
+ * rowHeight="NaN"
+ * verticalAlign="justify"
+ * verticalGap="6"
+ * padding="0"
+ * />
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+public class TileLayout
+{ // extends LayoutBase
+ // include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ public function TileLayout():void
+ {
+ super();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // horizontalGap
+ //----------------------------------
+
+ // private var explicitHorizontalGap:Number = 6;
+ private var _horizontalGap:Number = 6;
+
+ [Bindable("propertyChange")]
+ [Inspectable(category="General")]
+
+ /**
+ * Horizontal space between columns, in pixels.
+ *
+ * @see #verticalGap
+ * @see #columnAlign
+ * @default 6
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ public function get horizontalGap():Number
+ {
+ return _horizontalGap;
+ }
+
+ /**
+ * @private
+ */
+ public function set horizontalGap(value:Number):void
+ {
+ // explicitHorizontalGap = value;
+ if (value == _horizontalGap)
+ return;
+
+ _horizontalGap = value;
+ //invalidateTargetSizeAndDisplayList();
+ }
+
+ //----------------------------------
+ // verticalGap
+ //----------------------------------
+
+ // private var explicitVerticalGap:Number = 6;
+ private var _verticalGap:Number = 6;
+
+ [Bindable("propertyChange")]
+ [Inspectable(category="General")]
+
+ /**
+ * Vertical space between rows, in pixels.
+ *
+ * @see #horizontalGap
+ * @see #rowAlign
+ * @default 6
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ public function get verticalGap():Number
+ {
+ return _verticalGap;
+ }
+
+ /**
+ * @private
+ */
+ public function set verticalGap(value:Number):void
+ {
+ // explicitVerticalGap = value;
+ if (value == _verticalGap)
+ return;
+
+ _verticalGap = value;
+ // invalidateTargetSizeAndDisplayList();
+ }
+
+ //----------------------------------
+ // columnCount
+ //----------------------------------
+
+ /* private var _columnCount:int = -1;
+
+ [Bindable("propertyChange")]
+ [Inspectable(category="General")] */
+
+ /**
+ * Contain the actual column count.
+ *
+ * @see #rowCount
+ * @see #columnAlign
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get columnCount():int
+ {
+ return _columnCount;
+ } */
+
+ //----------------------------------
+ // requestedColumnCount
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the requestedColumnCount property.
+ */
+ /* private var _requestedColumnCount:int = -1;
+
+ [Inspectable(category="General", minValue="-1")] */
+
+ /**
+ * Number of columns to be displayed.
+ *
+ * <p>Set to -1 to allow the TileLayout to determine
+ * the column count automatically.</p>
+ *
+ * <p>If the <code>orientation</code> property is set to <code>TileOrientation.ROWS</code>,
+ * then setting this property has no effect
+ * In this case, the <code>rowCount</code> is explicitly set, and the
+ * container width is explicitly set. </p>
+ *
+ * @see #columnCount
+ * @see #columnAlign
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get requestedColumnCount():int
+ {
+ return _requestedColumnCount;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set requestedColumnCount(value:int):void
+ {
+ if (_requestedColumnCount == value)
+ return;
+
+ _requestedColumnCount = value;
+ _columnCount = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // rowCount
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the rowCount property.
+ */
+ /* private var _rowCount:int = -1;
+
+ [Bindable("propertyChange")]
+ [Inspectable(category="General")] */
+
+ /**
+ * The row count.
+ *
+ * @see #requestedRowCount
+ * @see #columnCount
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get rowCount():int
+ {
+ return _rowCount;
+ } */
+
+ //----------------------------------
+ // requestedRowCount
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the requestedRowCount property.
+ */
+ /* private var _requestedRowCount:int = -1;
+
+ [Inspectable(category="General", minValue="-1")] */
+
+ /**
+ * Number of rows to be displayed.
+ *
+ * <p>Set to -1 to remove explicit override and allow the TileLayout to determine
+ * the row count automatically.</p>
+ *
+ * <p>If the <code>orientation</code> property is set to
+ * <code>TileOrientation.COLUMNS</code>, setting this property has no effect.
+ * in this case, <code>columnCount</code> is explicitly set, and the
+ * container height is explicitly set.</p>
+ *
+ * @see #rowCount
+ * @see #rowAlign
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get requestedRowCount():int
+ {
+ return _requestedRowCount;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set requestedRowCount(value:int):void
+ {
+ if (_requestedRowCount == value)
+ return;
+
+ _requestedRowCount = value;
+ _rowCount = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // columnWidth
+ //----------------------------------
+
+ /* private var explicitColumnWidth:Number = NaN;
+ private var _columnWidth:Number = NaN;
+
+ [Bindable("propertyChange")]
+ [Inspectable(category="General", minValue="0.0")] */
+
+ /**
+ * Contain the actual column width, in pixels.
+ *
+ * <p>If not explicitly set, the column width is
+ * determined from the width of the widest element. </p>
+ *
+ * <p>If the <code>columnAlign</code> property is set
+ * to <code>"justifyUsingWidth"</code>, the column width grows to the
+ * container width to justify the fully-visible columns.</p>
+ *
+ * @see #rowHeight
+ * @see #columnAlign
+ * @default NaN
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get columnWidth():Number
+ {
+ return _columnWidth;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set columnWidth(value:Number):void
+ {
+ explicitColumnWidth = value;
+ if (value == _columnWidth)
+ return;
+
+ _columnWidth = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // rowHeight
+ //----------------------------------
+
+ /* private var explicitRowHeight:Number = NaN;
+ private var _rowHeight:Number = NaN;
+
+ [Bindable("propertyChange")]
+ [Inspectable(category="General", minValue="0.0")] */
+
+ /**
+ * The row height, in pixels.
+ *
+ * <p>If not explicitly set, the row height is
+ * determined from the maximum of elements' height.</p>
+ *
+ * If <code>rowAlign</code> is set to "justifyUsingHeight", the actual row height
+ * increases to justify the fully-visible rows to the container height.
+ *
+ * @see #columnWidth
+ * @see #rowAlign
+ * @default NaN
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get rowHeight():Number
+ {
+ return _rowHeight;
+ }
+ */
+ /**
+ * @private
+ */
+ /* public function set rowHeight(value:Number):void
+ {
+ explicitRowHeight = value;
+ if (value == _rowHeight)
+ return;
+
+ _rowHeight = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // padding
+ //----------------------------------
+
+ /* private var _padding:Number = 0;
+
+ [Inspectable(category="General")] */
+
+ /**
+ * The minimum number of pixels between the container's edges and
+ * the edges of the layout element.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get padding():Number
+ {
+ return _padding;
+ } */
+
+ /**
+ * @private
+ */
+ public/* function set padding(value:Number):void
+ {
+ if (_padding == value)
+ return;
+
+ _padding = value;
+
+ paddingBottom = _padding;
+ paddingLeft = _padding;
+ paddingRight = _padding;
+ paddingTop = _padding;
+
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // paddingLeft
+ //----------------------------------
+
+ /* private var _paddingLeft:Number = 0;
+
+ [Inspectable(category="General")] */
+
+ /**
+ * The minimum number of pixels between the container's left edge and
+ * the left edge of the layout element.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get paddingLeft():Number
+ {
+ return _paddingLeft;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set paddingLeft(value:Number):void
+ {
+ if (_paddingLeft == value)
+ return;
+
+ _paddingLeft = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // paddingRight
+ //----------------------------------
+
+ /* private var _paddingRight:Number = 0;
+
+ [Inspectable(category="General")] */
+
+ /**
+ * The minimum number of pixels between the container's right edge and
+ * the right edge of the layout element.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get paddingRight():Number
+ {
+ return _paddingRight;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set paddingRight(value:Number):void
+ {
+ if (_paddingRight == value)
+ return;
+
+ _paddingRight = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // paddingTop
+ //----------------------------------
+
+ /* private var _paddingTop:Number = 0;
+
+ [Inspectable(category="General")] */
+
+ /**
+ * Number of pixels between the container's top edge
+ * and the top edge of the first layout element.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get paddingTop():Number
+ {
+ return _paddingTop;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set paddingTop(value:Number):void
+ {
+ if (_paddingTop == value)
+ return;
+
+ _paddingTop = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // paddingBottom
+ //----------------------------------
+
+ /* private var _paddingBottom:Number = 0;
+
+ [Inspectable(category="General")] */
+
+ /**
+ * Number of pixels between the container's bottom edge
+ * and the bottom edge of the last layout element.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get paddingBottom():Number
+ {
+ return _paddingBottom;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set paddingBottom(value:Number):void
+ {
+ if (_paddingBottom == value)
+ return;
+
+ _paddingBottom = value;
+ invalidateTargetSizeAndDisplayList();
+ }
+ */
+ //----------------------------------
+ // horizontalAlign
+ //----------------------------------
+
+ private var _horizontalAlign:String = "justify";// HorizontalAlign.JUSTIFY;
+
+ [Inspectable(category="General", enumeration="left,right,center,justify", defaultValue="justify")]
+
+ /**
+ * Specifies how to align the elements within the cells in the horizontal direction.
+ * Supported values are
+ * <code>HorizontalAlign.LEFT</code>,
+ * <code>HorizontalAlign.CENTER</code>,
+ * <code>HorizontalAlign.RIGHT</code>,
+ * <code>HorizontalAlign.JUSTIFY</code>.
+ *
+ * <p>When set to <code>HorizontalAlign.JUSTIFY</code> the width of each
+ * element is set to the <code>columnWidth</code>.</p>
+ *
+ * @default <code>HorizontalAlign.JUSTIFY</code>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ public function get horizontalAlign():String
+ {
+ return _horizontalAlign;
+ }
+
+ /**
+ * @private
+ */
+ public function set horizontalAlign(value:String):void
+ {
+ if (_horizontalAlign == value)
+ return;
+
+ _horizontalAlign = value;
+ // invalidateTargetSizeAndDisplayList();
+ }
+
+ //----------------------------------
+ // verticalAlign
+ //----------------------------------
+
+ private var _verticalAlign:String = "justify"; //VerticalAlign.JUSTIFY;
+
+ [Inspectable(category="General", enumeration="top,bottom,middle,justify", defaultValue="justify")]
+
+ /**
+ * Specifies how to align the elements within the cells in the vertical direction.
+ * Supported values are
+ * <code>VerticalAlign.TOP</code>,
+ * <code>VerticalAlign.MIDDLE</code>,
+ * <code>VerticalAlign.BOTTOM</code>,
+ * <code>VerticalAlign.JUSTIFY</code>.
+ *
+ * <p>When set to <code>VerticalAlign.JUSTIFY</code>, the height of each
+ * element is set to <code>rowHeight</code>.</p>
+ *
+ * @default <code>VerticalAlign.JUSTIFY</code>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ public function get verticalAlign():String
+ {
+ return _verticalAlign;
+ }
+
+ /**
+ * @private
+ */
+ public function set verticalAlign(value:String):void
+ {
+ if (_verticalAlign == value)
+ return;
+
+ _verticalAlign = value;
+ // invalidateTargetSizeAndDisplayList();
+ }
+
+ //----------------------------------
+ // columnAlign
+ //----------------------------------
+
+ /* private var _columnAlign:String = ColumnAlign.LEFT;
+
+ [Inspectable(category="General", enumeration="left,justifyUsingGap,justifyUsingWidth", defaultValue="left")] */
+
+ /**
+ * Specifies how to justify the fully visible columns to the container width.
+ * ActionScript values can be <code>ColumnAlign.LEFT</code>, <code>ColumnAlign.JUSTIFY_USING_GAP</code>
+ * and <code>ColumnAlign.JUSTIFY_USING_WIDTH</code>.
+ * MXML values can be <code>"left"</code>, <code>"justifyUsingGap"</code> and <code>"justifyUsingWidth"</code>.
+ *
+ * <p>When set to <code>ColumnAlign.LEFT</code> it turns column justification off.
+ * There may be partially visible columns or whitespace between the last column and
+ * the right edge of the container. This is the default value.</p>
+ *
+ * <p>When set to <code>ColumnAlign.JUSTIFY_USING_GAP</code> the <code>horizontalGap</code>
+ * actual value increases so that
+ * the last fully visible column right edge aligns with the container's right edge.
+ * In case there is only a single fully visible column, the <code>horizontalGap</code> actual value
+ * increases so that it pushes any partially visible column beyond the right edge
+ * of the container.
+ * Note that explicitly setting the <code>horizontalGap</code> property does not turn off
+ * justification. It only determines the initial gap value.
+ * Justification may increases it.</p>
+ *
+ * <p>When set to <code>ColumnAlign.JUSTIFY_USING_WIDTH</code> the <code>columnWidth</code>
+ * actual value increases so that
+ * the last fully visible column right edge aligns with the container's right edge.
+ * Note that explicitly setting the <code>columnWidth</code> property does not turn off justification.
+ * It only determines the initial column width value.
+ * Justification may increases it.</p>
+ *
+ * @see #horizontalGap
+ * @see #columnWidth
+ * @see #rowAlign
+ * @default ColumnAlign.LEFT
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get columnAlign():String
+ {
+ return _columnAlign;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set columnAlign(value:String):void
+ {
+ if (_columnAlign == value)
+ return;
+
+ _columnAlign = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // rowAlign
+ //----------------------------------
+
+ /* private var _rowAlign:String = RowAlign.TOP;
+
+ [Inspectable(category="General", enumeration="top,justifyUsingGap,justifyUsingHeight", defaultValue="top")]
+ */
+ /**
+ * Specifies how to justify the fully visible rows to the container height.
+ * ActionScript values can be <code>RowAlign.TOP</code>, <code>RowAlign.JUSTIFY_USING_GAP</code>
+ * and <code>RowAlign.JUSTIFY_USING_HEIGHT</code>.
+ * MXML values can be <code>"top"</code>, <code>"justifyUsingGap"</code> and <code>"justifyUsingHeight"</code>.
+ *
+ * <p>When set to <code>RowAlign.TOP</code> it turns column justification off.
+ * There might be partially visible rows or whitespace between the last row and
+ * the bottom edge of the container. This is the default value.</p>
+ *
+ * <p>When set to <code>RowAlign.JUSTIFY_USING_GAP</code> the <code>verticalGap</code>
+ * actual value increases so that
+ * the last fully visible row bottom edge aligns with the container's bottom edge.
+ * In case there is only a single fully visible row, the value of <code>verticalGap</code>
+ * increases so that it pushes any partially visible row beyond the bottom edge
+ * of the container. Note that explicitly setting the <code>verticalGap</code> does not turn off
+ * justification, but just determines the initial gap value.
+ * Justification can then increases it.</p>
+ *
+ * <p>When set to <code>RowAlign.JUSTIFY_USING_HEIGHT</code> the <code>rowHeight</code>
+ * actual value increases so that
+ * the last fully visible row bottom edge aligns with the container's bottom edge. Note that
+ * explicitly setting the <code>rowHeight</code> does not turn off justification, but
+ * determines the initial row height value.
+ * Justification can then increase it.</p>
+ *
+ * @see #verticalGap
+ * @see #rowHeight
+ * @see #columnAlign
+ * @default RowAlign.TOP
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get rowAlign():String
+ {
+ return _rowAlign;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set rowAlign(value:String):void
+ {
+ if (_rowAlign == value)
+ return;
+
+ _rowAlign = value;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // orientation
+ //----------------------------------
+
+ /*private var _orientation:String = TileOrientation.ROWS;
+
+ [Inspectable(category="General", enumeration="rows,columns", defaultValue="rows")]
+ */
+ /**
+ * Specifies whether elements are arranged row by row or
+ * column by column.
+ * ActionScript values can be <code>TileOrientation.ROWS</code> and
+ * <code>TileOrientation.COLUMNS</code>.
+ * MXML values can be <code>"rows"</code> and <code>"columns"</code>.
+ *
+ * @default TileOrientation.ROWS
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* public function get orientation():String
+ {
+ return _orientation;
+ } */
+
+ /**
+ * @private
+ */
+ /* public function set orientation(value:String):void
+ {
+ if (_orientation == value)
+ return;
+
+ _orientation = value;
+ _tileWidthCached = _tileHeightCached = NaN;
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //----------------------------------
+ // useVirtualLayout
+ //----------------------------------
+
+ /**
+ * @private
+ */
+ /* override public function set useVirtualLayout(value:Boolean):void
+ {
+ if (useVirtualLayout == value)
+ return;
+
+ super.useVirtualLayout = value;
+
+ // Reset the state that virtual depends on. If the layout has already
+ // run with useVirtualLayout=false, the visibleStartEndIndex variables
+ // will have been set to 0, dataProvider.length.
+ if (value)
+ {
+ visibleStartIndex = -1;
+ visibleEndIndex = -1;
+ visibleStartX = 0;
+ visibleStartY = 0;
+ }
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ /* override public function clearVirtualLayoutCache():void
+ {
+ _tileWidthCached = _tileHeightCached = NaN;
+ } */
+
+ /**
+ * @private
+ * storage for old property values, in order to dispatch change events.
+ */
+ /* private var oldColumnWidth:Number = NaN;
+ private var oldRowHeight:Number = NaN;
+ private var oldColumnCount:int = -1;
+ private var oldRowCount:int = -1;
+ private var oldHorizontalGap:Number = NaN;
+ private var oldVerticalGap:Number = NaN;
+ */
+ // Cache storage to avoid repeating work from measure() in updateDisplayList().
+ // These are set the first time the value is calculated and are reset at the end
+ // of updateDisplayList().
+ /* private var _tileWidthCached:Number = NaN;
+ private var _tileHeightCached:Number = NaN;
+ private var _numElementsCached:int = -1; */
+
+ /**
+ * @private
+ * The following variables are used by updateDisplayList() and set by
+ * calculateDisplayParameters(). If virtualLayout=true they're based
+ * on the current scrollRect.
+ */
+ /* private var visibleStartIndex:int = -1; // dataProvider/layout element index
+ private var visibleEndIndex:int = -1; // ...
+ private var visibleStartX:Number = 0; // first tile/cell origin
+ private var visibleStartY:Number = 0; // ... */
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Dispatches events if Actual values have changed since the last call.
+ * Checks columnWidth, rowHeight, columnCount, rowCount, horizontalGap, verticalGap.
+ * This method is called from within updateDisplayList()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* private function dispatchEventsForActualValueChanges():void
+ {
+ if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ {
+ if (oldColumnWidth != _columnWidth)
+ dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "columnWidth", oldColumnWidth, _columnWidth));
+ if (oldRowHeight != _rowHeight)
+ dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "rowHeight", oldRowHeight, _rowHeight));
+ if (oldColumnCount != _columnCount)
+ dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "columnCount", oldColumnCount, _columnCount));
+ if (oldRowCount != _rowCount)
+ dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "rowCount", oldRowCount, _rowCount));
+ if (oldHorizontalGap != _horizontalGap)
+ dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "horizontalGap", oldHorizontalGap, _horizontalGap));
+ if (oldVerticalGap != _verticalGap)
+ dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "verticalGap", oldVerticalGap, _verticalGap));
+ }
+
+ oldColumnWidth = _columnWidth;
+ oldRowHeight = _rowHeight;
+ oldColumnCount = _columnCount;
+ oldRowCount = _rowCount;
+ oldHorizontalGap = _horizontalGap;
+ oldVerticalGap = _verticalGap;
+ } */
+
+ /**
+ * This method is called from measure() and updateDisplayList() to calculate the
+ * actual values for columnWidth, rowHeight, columnCount, rowCount, horizontalGap and verticalGap.
+ * The width and height should include padding because the padding is accounted for in
+ * the calculations.
+ *
+ * @param width - the width during measure() is the layout target explicitWidth or NaN
+ * and during updateDisplayList() is the unscaledWidth.
+ * @param height - the height during measure() is the layout target explicitHeight or NaN
+ * and during updateDisplayList() is the unscaledHeight.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* private function updateActualValues(width:Number, height:Number):void
+ {
+ var widthMinusPadding:Number = width - paddingLeft - paddingRight;
+ var heightMinusPadding:Number = height - paddingTop - paddingBottom;
+
+ // First, figure the tile size
+ calculateTileSize();
+
+ // Second, figure out number of rows/columns
+ var elementCount:int = calculateElementCount();
+ calculateColumnAndRowCount(widthMinusPadding, heightMinusPadding, elementCount);
+
+ // Third, adjust the gaps and column and row sizes based on justification settings
+ _horizontalGap = explicitHorizontalGap;
+ _verticalGap = explicitVerticalGap;
+
+ // Justify
+ if (!isNaN(width))
+ {
+ switch (columnAlign)
+ {
+ case ColumnAlign.JUSTIFY_USING_GAP:
+ _horizontalGap = justifyByGapSize(widthMinusPadding, _columnWidth, _horizontalGap, _columnCount);
+ break;
+ case ColumnAlign.JUSTIFY_USING_WIDTH:
+ _columnWidth = justifyByElementSize(widthMinusPadding, _columnWidth, _horizontalGap, _columnCount);
+ break;
+ }
+ }
+
+ if (!isNaN(height))
+ {
+ switch (rowAlign)
+ {
+ case RowAlign.JUSTIFY_USING_GAP:
+ _verticalGap = justifyByGapSize(heightMinusPadding, _rowHeight, _verticalGap, _rowCount);
+ break;
+ case RowAlign.JUSTIFY_USING_HEIGHT:
+ _rowHeight = justifyByElementSize(heightMinusPadding, _rowHeight, _verticalGap, _rowCount);
+ break;
+ }
+ }
+
+ // Last, if we have explicit overrides for both rowCount and columnCount, then
+ // make sure that column/row count along the minor axis reflects the actual count.
+ if (-1 != _requestedColumnCount && -1 != _requestedRowCount)
+ {
+ if (orientation == TileOrientation.ROWS)
+ _rowCount = Math.max(1, Math.ceil(elementCount / Math.max(1, _requestedColumnCount)));
+ else
+ _columnCount = Math.max(1, Math.ceil(elementCount / Math.max(1, _requestedRowCount)));
+ }
+ } */
+
+ /**
+ * @private
+ * Returns true, if the dimensions (colCount1, rowCount1) are more square than (colCount2, rowCount2).
+ * Squareness is the difference between width and height of a tile layout
+ * with the specified number of columns and rows.
+ */
+ /* private function closerToSquare(colCount1:int, rowCount1:int, colCount2:int, rowCount2:int):Boolean
+ {
+ var difference1:Number = Math.abs(colCount1 * (_columnWidth + _horizontalGap) - _horizontalGap -
+ rowCount1 * (_rowHeight + _verticalGap) + _verticalGap);
+ var difference2:Number = Math.abs(colCount2 * (_columnWidth + _horizontalGap) - _horizontalGap -
+ rowCount2 * (_rowHeight + _verticalGap) + _verticalGap);
+
+ return difference1 < difference2 || (difference1 == difference2 && rowCount1 <= rowCount2);
+ } */
+
+ /**
+ * @private
+ * Calculates _columnCount and _rowCount based on width, height,
+ * orientation, _requestedColumnCount, _requestedRowCount, _columnWidth, _rowHeight.
+ * _columnWidth and _rowHeight must be valid before calling.
+ *
+ * The width and height should not include padding.
+ */
+ /* private function calculateColumnAndRowCount(width:Number, height:Number, elementCount:int):void
+ {
+ _columnCount = _rowCount = -1;
+
+ if (-1 != _requestedColumnCount || -1 != _requestedRowCount)
+ {
+ if (-1 != _requestedRowCount)
+ _rowCount = Math.max(1, _requestedRowCount);
+
+ if (-1 != _requestedColumnCount)
+ _columnCount = Math.max(1, _requestedColumnCount);
+ }
+ // Figure out number of columns or rows based on the explicit size along one of the axes
+ else if (!isNaN(width) && (orientation == TileOrientation.ROWS || isNaN(height)))
+ {
+ if (_columnWidth + explicitHorizontalGap > 0)
+ _columnCount = Math.max(1, Math.floor((width + explicitHorizontalGap) / (_columnWidth + explicitHorizontalGap)));
+ else
+ _columnCount = 1;
+ }
+ else if (!isNaN(height) && (orientation == TileOrientation.COLUMNS || isNaN(width)))
+ {
+ if (_rowHeight + explicitVerticalGap > 0)
+ _rowCount = Math.max(1, Math.floor((height + explicitVerticalGap) / (_rowHeight + explicitVerticalGap)));
+ else
+ _rowCount = 1;
+ }
+ else // Figure out the number of columns and rows so that pixels area occupied is as square as possible
+ {
+ // Calculate number of rows and columns so that
+ // pixel area is as square as possible
+ var hGap:Number = explicitHorizontalGap;
+ var vGap:Number = explicitVerticalGap;
+
+ // 1. columnCount * (columnWidth + hGap) - hGap == rowCount * (rowHeight + vGap) - vGap
+ // 1. columnCount * (columnWidth + hGap) == rowCount * (rowHeight + vGap) + hGap - vGap
+ // 1. columnCount == (rowCount * (rowHeight + vGap) + hGap - vGap) / (columnWidth + hGap)
+ // 2. columnCount * rowCount == elementCount
+ // substitute 1. in 2.
+ // rowCount * rowCount + (hGap - vGap) * rowCount - elementCount * (columnWidth + hGap ) == 0
+
+ var a:Number = Math.max(0, (rowHeight + vGap));
+ var b:Number = (hGap - vGap);
+ var c:Number = -elementCount * (_columnWidth + hGap);
+ var d:Number = b * b - 4 * a * c; // Always guaranteed to be greater than zero, since c <= 0
+ d = Math.sqrt(d);
+
+ // We are guaranteed that we have only one positive root, since d >= b:
+ var rowCount:Number = (a != 0) ? (b + d) / (2 * a) : elementCount;
+
+ // To get integer count for the columns/rows we round up and down so
+ // we get four possible solutions. Then we pick the best one.
+ var row1:int = Math.max(1, Math.floor(rowCount));
+ var col1:int = Math.max(1, Math.ceil(elementCount / row1));
+ row1 = Math.max(1, Math.ceil(elementCount / col1));
+
+ var row2:int = Math.max(1, Math.ceil(rowCount));
+ var col2:int = Math.max(1, Math.ceil(elementCount / row2));
+ row2 = Math.max(1, Math.ceil(elementCount / col2));
+
+ var col3:int = Math.max(1, Math.floor(elementCount / rowCount));
+ var row3:int = Math.max(1, Math.ceil(elementCount / col3));
+ col3 = Math.max(1, Math.ceil(elementCount / row3));
+
+ var col4:int = Math.max(1, Math.ceil(elementCount / rowCount));
+ var row4:int = Math.max(1, Math.ceil(elementCount / col4));
+ col4 = Math.max(1, Math.ceil(elementCount / row4));
+
+ if (closerToSquare(col3, row3, col1, row1))
+ {
+ col1 = col3;
+ row1 = row3;
+ }
+
+ if (closerToSquare(col4, row4, col2, row2))
+ {
+ col2 = col4;
+ row2 = row4;
+ }
+
+ if (closerToSquare(col1, row1, col2, row2))
+ {
+ _columnCount = col1;
+ _rowCount = row1;
+ }
+ else
+ {
+ _columnCount = col2;
+ _rowCount = row2;
+ }
+ }
+
+ // In case we determined only columns or rows (from explicit overrides or explicit width/height)
+ // calculate the other from the number of elements
+ if (-1 == _rowCount)
+ _rowCount = Math.max(1, Math.ceil(elementCount / _columnCount));
+ if (-1 == _columnCount)
+ _columnCount = Math.max(1, Math.ceil(elementCount / _rowCount));
+ } */
+
+ /**
+ * @private
+ * Increases the gap so that elements are justified to exactly fit totalSize
+ * leaving no partially visible elements in view.
+ * @return Returs the new gap size.
+ */
+ /* private function justifyByGapSize(totalSize:Number, elementSize:Number,
+ gap:Number, elementCount:int):Number
+ {
+ // If element + gap collapses to zero, then don't adjust the gap.
+ if (elementSize + gap <= 0)
+ return gap;
+
+ // Find the number of fully visible elements
+ var visibleCount:int =
+ Math.min(elementCount, Math.floor((totalSize + gap) / (elementSize + gap)));
+
+ // If there isn't even a singel fully visible element, don't adjust the gap
+ if (visibleCount < 1)
+ return gap;
+
+ // Special case: if there's a singe fully visible element and a partially
+ // visible element, then make the gap big enough to push out the partially
+ // visible element out of view.
+ if (visibleCount == 1)
+ return elementCount > 1 ? Math.max(gap, totalSize - elementSize) : gap;
+
+ // Now calculate the gap such that the fully visible elements and gaps
+ // add up exactly to totalSize:
+ // <==> totalSize == visibleCount * elementSize + (visibleCount - 1) * gap
+ // <==> totalSize - visibleCount * elementSize == (visibleCount - 1) * gap
+ // <==> (totalSize - visibleCount * elementSize) / (visibleCount - 1) == gap
+ return (totalSize - visibleCount * elementSize) / (visibleCount - 1);
+ } */
+
+ /**
+ * @private
+ * Increases the element size so that elements are justified to exactly fit
+ * totalSize leaving no partially visible elements in view.
+ * @return Returns the the new element size.
+ */
+ /* private function justifyByElementSize(totalSize:Number, elementSize:Number,
+ gap:Number, elementCount:int):Number
+ {
+ var elementAndGapSize:Number = elementSize + gap;
+ var visibleCount:int = 0;
+ // Find the number of fully visible elements
+ if (elementAndGapSize == 0)
+ visibleCount = elementCount;
+ else
+ visibleCount = Math.min(elementCount, Math.floor((totalSize + gap) / elementAndGapSize));
+
+ // If there isn't event a single fully visible element, don't adjust
+ if (visibleCount < 1)
+ return elementSize;
+
+ // Now calculate the elementSize such that the fully visible elements and gaps
+ // add up exactly to totalSize:
+ // <==> totalSize == visibleCount * elementSize + (visibleCount - 1) * gap
+ // <==> totalSize - (visibleCount - 1) * gap == visibleCount * elementSize
+ // <==> (totalSize - (visibleCount - 1) * gap) / visibleCount == elementSize
+ return (totalSize - (visibleCount - 1) * gap) / visibleCount;
+ } */
+
+ /**
+ * @private
+ * Update _tileWidth,Height to be the maximum of their current
+ * value and the element's preferred bounds.
+ */
+ /* private function updateVirtualTileSize(elt:ILayoutElement):void
+ {
+ if (!elt || !elt.includeInLayout)
+ return;
+ var w:Number = elt.getPreferredBoundsWidth();
+ var h:Number = elt.getPreferredBoundsHeight();
+ _tileWidthCached = isNaN(_tileWidthCached) ? w : Math.max(w, _tileWidthCached);
+ _tileHeightCached = isNaN(_tileHeightCached) ? h : Math.max(h, _tileHeightCached);
+ } */
+
+ /**
+ * @private
+ */
+ /* private function calculateVirtualTileSize():void
+ {
+ // If both dimensions are explicitly set, we're done
+ _columnWidth = explicitColumnWidth;
+ _rowHeight = explicitRowHeight;
+ if (!isNaN(_columnWidth) && !isNaN(_rowHeight))
+ {
+ _tileWidthCached = _columnWidth;
+ _tileHeightCached = _rowHeight;
+ return;
+ }
+
+ // update _tileWidth,HeightCached based on the typicalElement
+ updateVirtualTileSize(typicalLayoutElement);
+
+ // update _tileWidth,HeightCached based on visible elements
+ if ((visibleStartIndex != -1) && (visibleEndIndex != -1))
+ {
+ for (var index:int = visibleStartIndex; index <= visibleEndIndex; index++)
+ updateVirtualTileSize(target.getVirtualElementAt(index));
+ }
+
+ // Make sure that we always have non-NaN values in the cache, even
+ // when there are no elements.
+ if (isNaN(_tileWidthCached))
+ _tileWidthCached = 0;
+ if (isNaN(_tileHeightCached))
+ _tileHeightCached = 0;
+
+ if (isNaN(_columnWidth))
+ _columnWidth = _tileWidthCached;
+ if (isNaN(_rowHeight))
+ _rowHeight = _tileHeightCached;
+ } */
+
+ /**
+ * @private
+ * Calculates _columnWidth and _rowHeight from maximum of
+ * elements preferred size and any explicit overrides.
+ */
+ /* private function calculateRealTileSize():void
+ {
+ _columnWidth = _tileWidthCached;
+ _rowHeight = _tileHeightCached;
+ if (!isNaN(_columnWidth) && !isNaN(_rowHeight))
+ return;
+
+ // Are both dimensions explicitly set?
+ _columnWidth = _tileWidthCached = explicitColumnWidth;
+ _rowHeight = _tileHeightCached = explicitRowHeight;
+ if (!isNaN(_columnWidth) && !isNaN(_rowHeight))
+ return;
+
+ // Find the maxmimums of element's preferred sizes
+ var columnWidth:Number = 0;
+ var rowHeight:Number = 0;
+
+ var layoutTarget:GroupBase = target;
+ var count:int = layoutTarget.numElements;
+ // Remember the number of includeInLayout elements
+ _numElementsCached = count;
+ for (var i:int = 0; i < count; i++)
+ {
+ var el:ILayoutElement = layoutTarget.getElementAt(i);
+ if (!el || !el.includeInLayout)
+ {
+ _numElementsCached--;
+ continue;
+ }
+
+ if (isNaN(_columnWidth))
+ columnWidth = Math.max(columnWidth, el.getPreferredBoundsWidth());
+ if (isNaN(_rowHeight))
+ rowHeight = Math.max(rowHeight, el.getPreferredBoundsHeight());
+ }
+
+ if (isNaN(_columnWidth))
+ _columnWidth = _tileWidthCached = columnWidth;
+ if (isNaN(_rowHeight))
+ _rowHeight = _tileHeightCached = rowHeight;
+ } */
+
+ /* private function calculateTileSize():void
+ {
+ if (useVirtualLayout)
+ calculateVirtualTileSize();
+ else
+ calculateRealTileSize();
+ } */
+
+ /**
+ * @private
+ * For normal layout return the number of non-null includeInLayout=true
+ * layout elements, for virtual layout just return the number of layout
+ * elements.
+ */
+ /* private function calculateElementCount():int
+ {
+ if (-1 != _numElementsCached)
+ return _numElementsCached;
+
+ var layoutTarget:GroupBase = target;
+ var count:int = layoutTarget.numElements;
+ _numElementsCached = count;
+
+ if (useVirtualLayout)
+ return _numElementsCached;
+
+ for (var i:int = 0; i < count; i++)
+ {
+ var el:ILayoutElement = layoutTarget.getElementAt(i);
+ if (!el || !el.includeInLayout)
+ _numElementsCached--;
+ }
+
+ return _numElementsCached;
+ } */
+
+ /**
+ * @private
+ * This method computes values for visibleStartX,Y, visibleStartIndex, and
+ * visibleEndIndex based on the TileLayout geometry values, like _columnWidth
+ * and _rowHeight, computed by calculateActualValues().
+ *
+ * If useVirtualLayout=false, then visibleStartX,Y=0 and visibleStartIndex=0
+ * and visibleEndIndex=layoutTarget.numElements-1.
+ *
+ * If useVirtualLayout=true and orientation=ROWS then visibleStartIndex is the
+ * layout element index of the item at first visible row relative to the scrollRect,
+ * column 0. Note that we're using column=0 instead of the first visible column
+ * to simplify the iteration logic in updateDisplayList(). This is optimal
+ * for the common case where the entire row is visible. Optimally handling
+ * the case where orientation=ROWS and each row is only partially visible is
+ * doable but adds some complexity to the main loop.
+ *
+ * The logic for useVirtualLayout=true and orientation=COLS is similar.
+ */
+ /* private function calculateDisplayParameters(unscaledWidth:int, unscaledHeight:int):void
+ {
+ updateActualValues(unscaledWidth, unscaledHeight);
+
+ var layoutTarget:GroupBase = target;
+ var eltCount:int = layoutTarget.numElements;
+ visibleStartX = paddingLeft; // initial values for xPos,yPos in updateDisplayList
+ visibleStartY = paddingTop;
+ visibleStartIndex = 0;
+ visibleEndIndex = eltCount - 1;
+
+ if (useVirtualLayout)
+ {
+ var hsp:Number = layoutTarget.horizontalScrollPosition - paddingLeft;
+ var vsp:Number = layoutTarget.verticalScrollPosition - paddingTop;
+ var cwg:Number = _columnWidth + _horizontalGap;
+ var rwg:Number = _rowHeight + _verticalGap;
+
+ var visibleCol0:int = Math.max(0, Math.floor(hsp / cwg));
+ var visibleRow0:int = Math.max(0, Math.floor(vsp / rwg));
+ var visibleCol1:int = Math.min(_columnCount - 1, Math.floor((hsp + unscaledWidth) / cwg));
+ var visibleRow1:int = Math.min(_rowCount - 1, Math.floor((vsp + unscaledHeight) / rwg));
+
+ if (orientation == TileOrientation.ROWS)
+ {
+ visibleStartIndex = (visibleRow0 * _columnCount);
+ visibleEndIndex = Math.min(eltCount - 1, (visibleRow1 * _columnCount) + visibleCol1);
+ visibleStartY = visibleRow0 * rwg + paddingTop;
+ }
+ else
+ {
+ visibleStartIndex = (visibleCol0 * _rowCount);
+ visibleEndIndex = Math.min(eltCount - 1, (visibleCol1 * _rowCount) + visibleRow1);
+ visibleStartX = visibleCol0 * cwg + paddingLeft;
+ }
+ }
+ } */
+
+ /**
+ * @private
+ * This method is called by updateDisplayList() after initial values for
+ * visibleStartIndex, visibleEndIndex have been calculated. We
+ * re-calculateDisplayParameters() to account for the possibility that
+ * larger cells may have been exposed. Since tileWidth,Height can only
+ * increase, the new visibleStart,EndIndex values will be greater than or
+ * equal to the old ones.
+ */
+ /* private function updateVirtualLayout(unscaledWidth:int, unscaledHeight:int):void
+ {
+ var oldVisibleStartIndex:int = visibleStartIndex;
+ var oldVisibleEndIndex:int = visibleEndIndex;
+ calculateDisplayParameters(unscaledWidth, unscaledHeight); // compute new visibleStart,EndIndex values
+
+ // We're responsible for laying out *all* of the elements requested
+ // with getVirtualElementAt(), even if they don't fall within the final
+ // visible range. Hide any extra ones. On the next layout pass, they'll
+ // be added to DataGroup::freeRenderers
+
+ var layoutTarget:GroupBase = target;
+ for (var i:int = oldVisibleStartIndex; i <= oldVisibleEndIndex; i++)
+ {
+ if ((i >= visibleStartIndex) && (i <= visibleEndIndex)) // skip past the visible range
+ {
+ i = visibleEndIndex;
+ continue;
+ }
+ var el:ILayoutElement = layoutTarget.getElementAt(i);
+ if (!el)
+ continue;
+ if (el is IVisualElement)
+ IVisualElement(el).visible = false;
+ }
+ } */
+
+ /**
+ * Sets the size and the position of the specified layout element and cell bounds.
+ * @param element - the element to resize and position.
+ * @param cellX - the x coordinate of the cell.
+ * @param cellY - the y coordinate of the cell.
+ * @param cellWidth - the width of the cell.
+ * @param cellHeight - the height of the cell.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* private function sizeAndPositionElement(element:ILayoutElement,
+ cellX:int,
+ cellY:int,
+ cellWidth:int,
+ cellHeight:int):void
+ {
+ var childWidth:Number = NaN;
+ var childHeight:Number = NaN;
+
+ // Determine size of the element
+ if (horizontalAlign == "justify")
+ childWidth = cellWidth;
+ else if (!isNaN(element.percentWidth))
+ childWidth = Math.round(cellWidth * element.percentWidth * 0.01);
+ else
+ childWidth = element.getPreferredBoundsWidth();
+
+ if (verticalAlign == "justify")
+ childHeight = cellHeight;
+ else if (!isNaN(element.percentHeight))
+ childHeight = Math.round(cellHeight * element.percentHeight * 0.01);
+ else
+ childHeight = element.getPreferredBoundsHeight();
+
+ // Enforce min and max limits
+ var maxChildWidth:Number = Math.min(element.getMaxBoundsWidth(), cellWidth);
+ var maxChildHeight:Number = Math.min(element.getMaxBoundsHeight(), cellHeight);
+ // Make sure we enforce element's minimum last, since it has the highest priority
+ childWidth = Math.max(element.getMinBoundsWidth(), Math.min(maxChildWidth, childWidth));
+ childHeight = Math.max(element.getMinBoundsHeight(), Math.min(maxChildHeight, childHeight));
+
+ // Size the element
+ element.setLayoutBoundsSize(childWidth, childHeight);
+
+ var x:Number = cellX;
+ switch (horizontalAlign)
+ {
+ case "right":
+ x += cellWidth - element.getLayoutBoundsWidth();
+ break;
+ case "center":
+ // Make sure division result is integer - Math.floor() the result.
+ x = cellX + Math.floor((cellWidth - element.getLayoutBoundsWidth()) / 2);
+ break;
+ }
+
+ var y:Number = cellY;
+ switch (verticalAlign)
+ {
+ case "bottom":
+ y += cellHeight - element.getLayoutBoundsHeight();
+ break;
+ case "middle":
+ // Make sure division result is integer - Math.floor() the result.
+ y += Math.floor((cellHeight - element.getLayoutBoundsHeight()) / 2);
+ break;
+ }
+
+ // Position the element
+ element.setLayoutBoundsPosition(x, y);
+ } */
+
+ /**
+ * @private
+ * @return Returns the x coordinate of the left edge for the specified column.
+ */
+ /* final private function leftEdge(columnIndex:int):Number
+ {
+ if (columnIndex < 0)
+ return 0;
+
+ return Math.max(0, columnIndex * (_columnWidth + _horizontalGap)) + paddingLeft;
+ } */
+
+ /**
+ * @private
+ * @return Returns the x coordinate of the right edge for the specified column.
+ */
+ /* final private function rightEdge(columnIndex:int):Number
+ {
+ if (columnIndex < 0)
+ return 0;
+
+ return Math.min(target.contentWidth, columnIndex * (_columnWidth + _horizontalGap) + _columnWidth) + paddingLeft;
+ } */
+
+ /**
+ * @private
+ * @return Returns the y coordinate of the top edge for the specified row.
+ */
+ /* final private function topEdge(rowIndex:int):Number
+ {
+ if (rowIndex < 0)
+ return 0;
+
+ return Math.max(0, rowIndex * (_rowHeight + _verticalGap)) + paddingTop;
+ } */
+
+ /**
+ * @private
+ * @return Returns the y coordinate of the bottom edge for the specified row.
+ */
+ /* final private function bottomEdge(rowIndex:int):Number
+ {
+ if (rowIndex < 0)
+ return 0;
+
+ return Math.min(target.contentHeight, rowIndex * (_rowHeight + _verticalGap) + _rowHeight) + paddingTop;
+ } */
+
+ /**
+ * @private
+ * Convenience function for subclasses that invalidates the
+ * target's size and displayList so that both layout's <code>measure()</code>
+ * and <code>updateDisplayList</code> methods get called.
+ *
+ * <p>Typically a layout invalidates the target's size and display list so that
+ * it gets a chance to recalculate the target's default size and also size and
+ * position the target's elements. For example changing the <code>gap</code>
+ * property on a <code>VerticalLayout</code> will internally call this method
+ * to ensure that the elements are re-arranged with the new setting and the
+ * target's default size is recomputed.</p>
+ */
+ /* private function invalidateTargetSizeAndDisplayList():void
+ {
+ var g:GroupBase = target;
+ if (!g)
+ return;
+
+ g.invalidateSize();
+ g.invalidateDisplayList();
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods from LayoutBase
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ /* override protected function scrollPositionChanged():void
+ {
+ super.scrollPositionChanged();
+
+ var layoutTarget:GroupBase = target;
+ if (!layoutTarget)
+ return;
+
+ if (useVirtualLayout)
+ layoutTarget.invalidateDisplayList();
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function measure():void
+ {
+ // Save and restore these values so they're not modified
+ // as a sideeffect of measure().
+ var savedColumnCount:int = _columnCount;
+ var savedRowCount:int = _rowCount;
+ var savedHorizontalGap:int = _horizontalGap;
+ var savedVerticalGap:int = _verticalGap;
+ var savedColumnWidth:int = _columnWidth;
+ var savedRowHeight:int = _rowHeight;
+
+ var layoutTarget:GroupBase = target;
+ if (!layoutTarget)
+ return;
+
+ updateActualValues(layoutTarget.explicitWidth, layoutTarget.explicitHeight);
+
+ // For measure, any explicit overrides for rowCount and columnCount take precedence
+ var columnCount:int = _requestedColumnCount != -1 ? Math.max(1, _requestedColumnCount) : _columnCount;
+ var rowCount:int = _requestedRowCount != -1 ? Math.max(1, _requestedRowCount) : _rowCount;
+
+ var measuredWidth:Number = 0;
+ var measuredMinWidth:Number = 0;
+ var measuredHeight:Number = 0;
+ var measuredMinHeight:Number = 0;
+
+ if (columnCount > 0)
+ {
+ measuredWidth = Math.ceil(columnCount * (_columnWidth + _horizontalGap) - _horizontalGap)
+ // measured min size is guaranteed to have enough columns to fit all elements
+ measuredMinWidth = Math.ceil(_columnCount * (_columnWidth + _horizontalGap) - _horizontalGap);
+ }
+
+ if (rowCount > 0)
+ {
+ measuredHeight = Math.ceil(rowCount * (_rowHeight + _verticalGap) - _verticalGap);
+ // measured min size is guaranteed to have enough rows to fit all elements
+ measuredMinHeight = Math.ceil(_rowCount * (_rowHeight + _verticalGap) - _verticalGap);
+ }
+ _numElementsCached = -1;
+
+ var hPadding:Number = paddingLeft + paddingRight;
+ var vPadding:Number = paddingTop + paddingBottom;
+
+ layoutTarget.measuredWidth = measuredWidth + hPadding;
+ layoutTarget.measuredMinWidth = measuredMinWidth + hPadding;
+ layoutTarget.measuredHeight = measuredHeight + vPadding;
+ layoutTarget.measuredMinHeight = measuredMinHeight + vPadding;
+
+ _columnCount = savedColumnCount;
+ _rowCount = savedRowCount;
+ _horizontalGap = savedHorizontalGap;
+ _verticalGap = savedVerticalGap;
+ _columnWidth = savedColumnWidth;
+ _rowHeight = savedRowHeight;
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function getNavigationDestinationIndex(currentIndex:int, navigationUnit:uint, arrowKeysWrapFocus:Boolean):int
+ {
+ if (!target || target.numElements < 1)
+ return -1;
+
+ var maxIndex:int = target.numElements - 1;
+
+ // Special case when nothing was previously selected
+ if (currentIndex == -1)
+ {
+ if (navigationUnit == NavigationUnit.UP || navigationUnit == NavigationUnit.LEFT)
+ return arrowKeysWrapFocus ? maxIndex : -1;
+
+ if (navigationUnit == NavigationUnit.DOWN || navigationUnit == NavigationUnit.RIGHT)
+ return 0;
+ }
+
+ // Make sure currentIndex is within range
+ var inRows:Boolean = orientation == TileOrientation.ROWS;
+ currentIndex = Math.max(0, Math.min(maxIndex, currentIndex));
+
+ // Find the current column and row
+ var currentRow:int;
+ var currentColumn:int;
+ if (inRows)
+ {
+ // Is the TileLayout initialized with valid values?
+ if (columnCount == 0 || rowHeight + verticalGap == 0)
+ return currentIndex;
+
+ currentRow = currentIndex / columnCount;
+ currentColumn = currentIndex - currentRow * columnCount;
+ }
+ else
+ {
+ // Is the TileLayout initialized with valid values?
+ if (rowCount == 0 || columnWidth + horizontalGap == 0)
+ return currentIndex;
+
+ currentColumn = currentIndex / rowCount;
+ currentRow = currentIndex - currentColumn * rowCount;
+ }
+
+ var newRow:int = currentRow;
+ var newColumn:int = currentColumn;
+
+ // Handle user input, almost all range checks are
+ // performed after the calculations, at the end of the method.
+ switch (navigationUnit)
+ {
+ case NavigationUnit.LEFT:
+ {
+ // If we are at the first column, can
+ // we go to the previous element (last column, previous row)?
+ if (newColumn == 0 && inRows && newRow > 0)
+ {
+ newRow--;
+ newColumn = columnCount - 1;
+ }
+ else if (arrowKeysWrapFocus && newColumn == 0 && inRows && newRow == 0)
+ {
+ newRow = rowCount - 1;
+ newColumn = columnCount - 1;
+ }
+ else
+ newColumn--;
+ break;
+ }
+
+ case NavigationUnit.RIGHT:
+ {
+ // If we are at the last column, can
+ // we go to the next element (first column, next row)?
+ if (newColumn == columnCount - 1 && inRows && newRow < rowCount - 1)
+ {
+ newColumn = 0;
+ newRow++;
+ }
+ else if (arrowKeysWrapFocus && newColumn == columnCount - 1 && inRows && newRow == rowCount - 1)
+ {
+ newColumn = 0;
+ newRow = 0;
+ }
+ else
+ newColumn++;
+ break;
+ }
+
+ case NavigationUnit.UP:
+ {
+ // If we are at the first row, can we
+ // go to the previous element (previous column, last row)?
+ if (newRow == 0 && !inRows && newColumn > 0)
+ {
+ newColumn--;
+ newRow = rowCount - 1;
+ }
+ else if (arrowKeysWrapFocus && newRow == 0 && !inRows && newColumn == 0)
+ {
+ newColumn = columnCount - 1;
+ newRow = rowCount - 1;
+ }
+ else
+ newRow--;
+ break;
+ }
+
+ case NavigationUnit.DOWN:
+ {
+ // If we are at the last row, can we
+ // go to the next element (next column, first row)?
+ if (newRow == rowCount - 1 && !inRows && newColumn < columnCount - 1)
+ {
+ newColumn++;
+ newRow = 0;
+ }
+ else if (arrowKeysWrapFocus && newRow == rowCount - 1 && !inRows && newColumn == columnCount - 1)
+ {
+ newColumn = 0;
+ newRow = 0;
+ }
+ else
+ newRow++;
+ break;
+ }
+
+ case NavigationUnit.PAGE_UP:
+ case NavigationUnit.PAGE_DOWN:
+ {
+ // Ensure we have a valid scrollRect as we use it for calculations below
+ var scrollRect:Rectangle = getScrollRect();
+ if (!scrollRect)
+ scrollRect = new Rectangle(0, 0, target.contentWidth, target.contentHeight);
+
+ if (inRows)
+ {
+ var firstVisibleRow:int = Math.ceil(scrollRect.top / (rowHeight + verticalGap));
+ var lastVisibleRow:int = Math.floor(scrollRect.bottom / (rowHeight + verticalGap));
+
+ if (navigationUnit == NavigationUnit.PAGE_UP)
+ {
+ // Is the current row visible, somewhere in the middle of the scrollRect?
+ if (firstVisibleRow < currentRow && currentRow <= lastVisibleRow)
+ newRow = firstVisibleRow;
+ else
+ newRow = 2 * firstVisibleRow - lastVisibleRow;
+ }
+ else
+ {
+ // Is the current row visible, somewhere in the middle of the scrollRect?
+ if (firstVisibleRow <= currentRow && currentRow < lastVisibleRow)
+ newRow = lastVisibleRow;
+ else
+ newRow = 2 * lastVisibleRow - firstVisibleRow;
+ }
+ }
+ else
+ {
+ var firstVisibleColumn:int = Math.ceil(scrollRect.left / (columnWidth + horizontalGap));
+ var lastVisibleColumn:int = Math.floor(scrollRect.right / (columnWidth + horizontalGap));
+
+ if (navigationUnit == NavigationUnit.PAGE_UP)
+ {
+ // Is the current column visible, somewhere in the middle of the scrollRect?
+ if (firstVisibleColumn < currentColumn && currentColumn <= lastVisibleColumn)
+ newColumn = firstVisibleColumn;
+ else
+ newColumn = 2 * firstVisibleColumn - lastVisibleColumn;
+ }
+ else
+ {
+ // Is the current column visible, somewhere in the middle of the scrollRect?
+ if (firstVisibleColumn <= currentColumn && currentColumn < lastVisibleColumn)
+ newColumn = lastVisibleColumn;
+ else
+ newColumn = 2 * lastVisibleColumn - firstVisibleColumn;
+ }
+ }
+ break;
+ }
+ default: return super.getNavigationDestinationIndex(currentIndex, navigationUnit, arrowKeysWrapFocus);
+ }
+
+ // Make sure rows and columns are within range
+ newRow = Math.max(0, Math.min(rowCount - 1, newRow));
+ newColumn = Math.max(0, Math.min(columnCount - 1, newColumn));
+
+ // Calculate the new index based on orientation
+ if (inRows)
+ {
+ // Make sure we don't return an index for an empty space in the last row.
+ // newRow is guaranteed to be greater than zero:
+
+ if (newRow == rowCount - 1)
+ {
+ // Step 1: We can end up at the empty space in the last row if we moved right from
+ // the last item.
+ if (currentIndex == maxIndex && newColumn > currentColumn)
+ newColumn = currentColumn;
+
+ // Step 2: We can end up at the empty space in the last row if we moved down from
+ // the previous row.
+ if (newColumn > maxIndex - columnCount * (rowCount - 1))
+ newRow--;
+ }
+
+ return newRow * columnCount + newColumn;
+ }
+ else
+ {
+ // Make sure we don't return an index for an empty space in the last column.
+ // newColumn is guaranteed to be greater than zero:
+
+ if (newColumn == columnCount - 1)
+ {
+ // Step 1: We can end up at the empty space in the last column if we moved down from
+ // the last item.
+ if (currentIndex == maxIndex && newRow > currentRow)
+ newRow = currentRow;
+
+ // Step 2: We can end up at the empty space in the last column if we moved right from
+ // the previous column.
+ if (newRow > maxIndex - rowCount * (columnCount - 1))
+ newColumn--;
+ }
+
+ return newColumn * rowCount + newRow;
+ }
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ var layoutTarget:GroupBase = target;
+ if (!layoutTarget)
+ return;
+
+ calculateDisplayParameters(unscaledWidth, unscaledHeight);
+ if (useVirtualLayout)
+ updateVirtualLayout(unscaledWidth, unscaledHeight); // re-calculateDisplayParameters()
+
+ // Upper right hand corner of first (visibleStartIndex) tile/cell
+ var xPos:Number = visibleStartX; // paddingLeft if useVirtualLayout=false
+ var yPos:Number = visibleStartY; // paddingTop if useVirtualLayout=false
+
+ // Use MajorDelta when moving along the major axis
+ var xMajorDelta:Number;
+ var yMajorDelta:Number;
+
+ // Use MinorDelta when moving along the minor axis
+ var xMinorDelta:Number;
+ var yMinorDelta:Number;
+
+ // Use counter and counterLimit to track when to move along the minor axis
+ var counter:int = 0;
+ var counterLimit:int;
+
+ // Setup counterLimit and deltas based on orientation
+ if (orientation == TileOrientation.ROWS)
+ {
+ counterLimit = _columnCount;
+ xMajorDelta = _columnWidth + _horizontalGap;
+ xMinorDelta = 0;
+ yMajorDelta = 0;
+ yMinorDelta = _rowHeight + _verticalGap;
+ }
+ else
+ {
+ counterLimit = _rowCount;
+ xMajorDelta = 0;
+ xMinorDelta = _columnWidth + _horizontalGap;
+ yMajorDelta = _rowHeight + _verticalGap;
+ yMinorDelta = 0;
+ }
+
+ for (var index:int = visibleStartIndex; index <= visibleEndIndex; index++)
+ {
+ var el:ILayoutElement = null;
+ if (useVirtualLayout)
+ {
+ el = layoutTarget.getVirtualElementAt(index);
+ if (el is IVisualElement) // see updateVirtualLayout
+ IVisualElement(el).visible = true;
+ }
+ else
+ el = layoutTarget.getElementAt(index);
+
+ if (!el || !el.includeInLayout)
+ continue;
+
+ // To calculate the cell extents as integers, first calculate
+ // the extents and then use Math.round()
+ var cellX:int = Math.round(xPos);
+ var cellY:int = Math.round(yPos);
+ var cellWidth:int = Math.round(xPos + _columnWidth) - cellX;
+ var cellHeight:int = Math.round(yPos + _rowHeight) - cellY;
+
+ sizeAndPositionElement(el, cellX, cellY, cellWidth, cellHeight);
+
+ // Move along the major axis
+ xPos += xMajorDelta;
+ yPos += yMajorDelta;
+
+ // Move along the minor axis
+ if (++counter >= counterLimit)
+ {
+ counter = 0;
+ if (orientation == TileOrientation.ROWS)
+ {
+ xPos = paddingLeft;
+ yPos += yMinorDelta;
+ }
+ else
+ {
+ xPos += xMinorDelta;
+ yPos = paddingTop;
+ }
+ }
+ }
+
+ var hPadding:Number = paddingLeft + paddingRight;
+ var vPadding:Number = paddingTop + paddingBottom;
+
+ // Make sure that if the content spans partially over a pixel to the right/bottom,
+ // the content size includes the whole pixel.
+ layoutTarget.setContentSize(Math.ceil(_columnCount * (_columnWidth + _horizontalGap) - _horizontalGap) + hPadding,
+ Math.ceil(_rowCount * (_rowHeight + _verticalGap) - _verticalGap) + vPadding);
+
+ // Reset the cache
+ if (!useVirtualLayout)
+ _tileWidthCached = _tileHeightCached = NaN;
+ _numElementsCached = -1;
+
+ // No getVirtualElementAt() during measure, see calculateVirtualTileSize()
+ if (useVirtualLayout)
+ visibleStartIndex = visibleEndIndex = -1;
+
+ // If actual values have chnaged, notify listeners
+ dispatchEventsForActualValueChanges();
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function getElementBounds(index:int):Rectangle
+ {
+ if (!useVirtualLayout)
+ return super.getElementBounds(index);
+
+ var g:GroupBase = GroupBase(target);
+ if (!g || (index < 0) || (index >= g.numElements))
+ return null;
+
+ var col:int;
+ var row:int;
+ if (orientation == TileOrientation.ROWS)
+ {
+ col = index % _columnCount;
+ row = index / _columnCount;
+ }
+ else
+ {
+ col = index / _rowCount;
+ row = index % _rowCount
+ }
+ return new Rectangle(leftEdge(col), topEdge(row), _columnWidth, _rowHeight);
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function getElementBoundsLeftOfScrollRect(scrollRect:Rectangle):Rectangle
+ {
+ var bounds:Rectangle = new Rectangle();
+ // Find the column that spans or is to the left of the scrollRect left edge.
+ var column:int = Math.floor((scrollRect.left - 1 - paddingLeft) / (_columnWidth + _horizontalGap));
+ bounds.left = leftEdge(column);
+ bounds.right = rightEdge(column);
+ return bounds;
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function getElementBoundsRightOfScrollRect(scrollRect:Rectangle):Rectangle
+ {
+ var bounds:Rectangle = new Rectangle();
+ // Find the column that spans or is to the right of the scrollRect right edge.
+ var column:int = Math.floor(((scrollRect.right + 1 + _horizontalGap) - paddingLeft) / (_columnWidth + _horizontalGap));
+ bounds.left = leftEdge(column);
+ bounds.right = rightEdge(column);
+ return bounds;
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function getElementBoundsAboveScrollRect(scrollRect:Rectangle):Rectangle
+ {
+ var bounds:Rectangle = new Rectangle();
+ // Find the row that spans or is above the scrollRect top edge
+ var row:int = Math.floor((scrollRect.top - 1 - paddingTop) / (_rowHeight + _verticalGap));
+ bounds.top = topEdge(row);
+ bounds.bottom = bottomEdge(row);
+ return bounds;
+ } */
+
+ /**
+ * @private
+ */
+ /* override protected function getElementBoundsBelowScrollRect(scrollRect:Rectangle):Rectangle
+ {
+ var bounds:Rectangle = new Rectangle();
+ // Find the row that spans or is below the scrollRect bottom edge
+ var row:int = Math.floor(((scrollRect.bottom + 1 + _verticalGap) - paddingTop) / (_rowHeight + _verticalGap));
+ bounds.top = topEdge(row);
+ bounds.bottom = bottomEdge(row);
+ return bounds;
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function elementAdded(index:int):void
+ {
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ /**
+ * @private
+ */
+ /* override public function elementRemoved(index:int):void
+ {
+ invalidateTargetSizeAndDisplayList();
+ } */
+
+ //--------------------------------------------------------------------------
+ //
+ // Drop methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Calculates the column and row and returns the corresponding cell index.
+ * Index may be out of range if there's no element for the cell.
+ */
+ /* private function calculateDropCellIndex(x:Number, y:Number):Array
+ {
+ var xStart:Number = x - paddingLeft;
+ var yStart:Number = y - paddingTop;
+ var column:int = Math.floor(xStart / (_columnWidth + _horizontalGap));
+ var row:int = Math.floor(yStart / (_rowHeight + _verticalGap));
+
+ // Check whether x is closer to left column or right column:
+ var midColumnLine:Number;
+ var midRowLine:Number
+
+ var rowOrientation:Boolean = orientation == TileOrientation.ROWS;
+ if (rowOrientation)
+ {
+ // Mid-line is at the middle of the cell
+ midColumnLine = (column + 1) * (_columnWidth + _horizontalGap) - _horizontalGap - _columnWidth / 2;
+
+ // Mid-line is at the middle of the gap between the rows
+ midRowLine = (row + 1) * (_rowHeight + _verticalGap) - _verticalGap / 2;
+ }
+ else
+ {
+ // Mid-line is at the middle of the gap between the columns
+ midColumnLine = (column + 1) * (_columnWidth + _horizontalGap) - _horizontalGap / 2;
+
+ // Mid-line is at the middle of the cell
+ midRowLine = (row + 1) * (_rowHeight + _verticalGap) - _verticalGap - _rowHeight / 2;
+ }
+
+ if (xStart > midColumnLine)
+ column++;
+ if (yStart > midRowLine)
+ row++;
+
+ // Limit row and column, if any one is too far from the drop location
+ // And there is white space
+ if (column > _columnCount || row > _rowCount)
+ {
+ row = _rowCount;
+ column = _columnCount;
+ }
+
+ if (column < 0)
+ column = 0;
+ if (row < 0)
+ row = 0;
+
+ if (rowOrientation)
+ {
+ if (row >= _rowCount)
+ row = _rowCount - 1;
+ }
+ else
+ {
+ if (column >= _columnCount)
+ column = _columnCount - 1;
+ }
+ return [row, column];
+ } */
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* override protected function calculateDropIndex(x:Number, y:Number):int
+ {
+ var result:Array = calculateDropCellIndex(x, y);
+ var row:int = result[0];
+ var column:int = result[1];
+ var index:int;
+
+ if (orientation == TileOrientation.ROWS)
+ index = row * _columnCount + column;
+ else
+ index = column * _rowCount + row;
+
+ var count:int = calculateElementCount();
+ _numElementsCached = -1; // Reset the cache
+
+ if (index > count)
+ index = count;
+ return index;
+ } */
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @productversion Royale 0.9.4
+ */
+ /* override protected function calculateDropIndicatorBounds(dropLocation:DropLocation):Rectangle
+ {
+ var result:Array = calculateDropCellIndex(dropLocation.dropPoint.x, dropLocation.dropPoint.y);
+ var row:int = result[0];
+ var column:int = result[1];
+
+ var rowOrientation:Boolean = orientation == TileOrientation.ROWS;
+ var count:int = calculateElementCount();
+ _numElementsCached = -1; // Reset the cache
+
+ if (rowOrientation)
+ {
+ // The last row may be only partially full,
+ // don't drop beyond the last column.
+ if (row * _columnCount + column > count)
+ column = count - (_rowCount - 1) * _columnCount;
+ }
+ else
+ {
+ // The last column may be only partially full,
+ // don't drop beyond the last row.
+ if (column * _rowCount + row > count)
+ row = count - (_columnCount - 1) * _rowCount;
+ }
+
+ var x:Number;
+ var y:Number;
+ var dropIndicatorElement:IVisualElement;
+ var emptySpace:Number; // empty space between the elements
+
+ // Start with the dropIndicator dimensions, in case it's not
+ // an IVisualElement
+ var width:Number = dropIndicator.width;
+ var height:Number = dropIndicator.height;
+
+ if (rowOrientation)
+ {
+ emptySpace = (0 < _horizontalGap ) ? _horizontalGap : 0;
+ var emptySpaceLeft:Number = column * (_columnWidth + _horizontalGap) - emptySpace;
+
+ // Special case - if we have negative gap and we're the last column,
+ // adjust the emptySpaceLeft
+ if (_horizontalGap < 0 && (column == _columnCount || count == dropLocation.dropIndex))
+ emptySpaceLeft -= _horizontalGap;
+
+ width = emptySpace;
+ height = _rowHeight;
+ // Special case - if we have negative gap and we're not the last
+ // row, adjust the height
+ if (_verticalGap < 0 && row < _rowCount - 1)
+ height += _verticalGap + 1;
+
+ if (dropIndicator is IVisualElement)
+ {
+ dropIndicatorElement = IVisualElement(dropIndicator);
+ width = Math.max(Math.min(width,
+ dropIndicatorElement.getMaxBoundsWidth(false)),
+ dropIndicatorElement.getMinBoundsWidth(false));
+ }
+
+ x = emptySpaceLeft + Math.round((emptySpace - width) / 2) + paddingLeft;
+ // Allow 1 pixel overlap with container border
+ x = Math.max(-1, Math.min(target.contentWidth - width + 1, x));
+
+ y = row * (_rowHeight + _verticalGap) + paddingTop;
+ }
+ else
+ {
+ emptySpace = (0 < _verticalGap ) ? _verticalGap : 0;
+ var emptySpaceTop:Number = row * (_rowHeight + _verticalGap) - emptySpace;
+
+ // Special case - if we have negative gap and we're the last column,
+ // adjust the emptySpaceLeft
+ if (_verticalGap < 0 && (row == _rowCount || count == dropLocation.dropIndex))
+ emptySpaceTop -= _verticalGap;
+
+ width = _columnWidth;
+ height = emptySpace;
+ // Special case - if we have negative gap and we're not the last
+ // column, adjust the width
+ if (_horizontalGap < 0 && column < _columnCount - 1)
+ width += _horizontalGap + 1;
+
+ if (dropIndicator is IVisualElement)
+ {
+ dropIndicatorElement = IVisualElement(dropIndicator);
+ height = Math.max(Math.min(emptySpace,
+ dropIndicatorElement.getMaxBoundsWidth(false)),
+ dropIndicatorElement.getMinBoundsWidth(false));
+ }
+
+ x = column * (_columnWidth + _horizontalGap) + paddingLeft;
+
+ y = emptySpaceTop + Math.round((emptySpace - height) / 2) + paddingTop;
+ // Allow 1 pixel overlap with container border
+ y = Math.max(-1, Math.min(target.contentHeight - height + 1, y));
+ }
+
+ return new Rectangle(x, y, width, height);
+ } */
+
+ /**
+ * @private
+ * Helper function to return the row and column of the cell
+ * containing the x/y point. The associated index may be out
+ * of range if there's no element for the cell.
+ */
+ /* private function calculateCellIndex(x:Number, y:Number):Array
+ {
+ var xStart:Number = x - paddingLeft;
+ var yStart:Number = y - paddingTop;
+ var column:int = Math.floor(xStart / (_columnWidth + _horizontalGap));
+ var row:int = Math.floor(yStart / (_rowHeight + _verticalGap));
+
+ // Make sure column and row numbers are valid
+ if (column < 0)
+ column = 0;
+ if (column >= _columnCount)
+ column = _columnCount - 1;
+ if (row < 0)
+ row = 0;
+ if (row >= _rowCount)
+ row = _rowCount - 1;
+
+ return [row, column];
+ } */
+
+
+ /**
+ * @private
+ * Identifies the element which has its "compare point" located closest
+ * to the specified position.
+ */
+ /* override mx_internal function getElementNearestScrollPosition(
+ position:Point,
+ elementComparePoint:String = "center"):int
+ {
+ // Determine which cell contains the point
+ var result:Array = calculateCellIndex(position.x, position.y);
+ var row:int = result[0];
+ var column:int = result[1];
+
+ var maxRow:int = _rowCount-1;
+ var maxColumn:int = _columnCount-1;
+
+ // create a rectangle of the element bounds
+ var bounds:Rectangle =
+ new Rectangle(leftEdge(column), topEdge(row), _columnWidth + _horizontalGap, _rowHeight + _verticalGap);
+
+ const TOP_LEFT:int = 0;
+ const TOP_RIGHT:int = 1;
+ const BOTTOM_LEFT:int = 2;
+ const BOTTOM_RIGHT:int = 3;
+
+ // Determine the quadrant of the element/cell which contains the position point.
+ var quadrant:int = TOP_LEFT;
+ if (position.x > bounds.left + bounds.width/2)
+ quadrant += TOP_RIGHT;
+ if (position.y > bounds.top + bounds.height/2)
+ quadrant += BOTTOM_LEFT;
+
+ var index:int;
+ if (orientation == TileOrientation.ROWS)
+ index = row * _columnCount + column;
+ else
+ index = column * _rowCount + row;
+
+ var g:GroupBase = GroupBase(target);
+ if (index >= g.numElements)
+ {
+ // TODO (eday): two-dimensional item snapping will require more sophisticated cell detection
+ // if the position is beyond the content. For now (while we only support one-dimensional
+ // snapping), using the last element will work fine.
+ return g.numElements - 1;
+ }
+
+ // Depending on which point of the element is to be compared with, and on which
+ // quadrant of the element contains the position, we may adjust row/column to
+ // points to an adjacent cell.
+ switch (elementComparePoint)
+ {
+ case "topLeft":
+ if (quadrant == TOP_RIGHT && column < maxColumn)
+ column++;
+ else if (quadrant == BOTTOM_LEFT && row < maxRow)
+ row++;
+ else if (quadrant == BOTTOM_RIGHT && row < maxRow && column < maxColumn)
+ {
+ row++;
+ column++;
+ }
+ break;
+ case "topRight":
+ if (quadrant == TOP_LEFT && column > 0)
+ column--;
+ else if (quadrant == BOTTOM_LEFT && column > 0 && row < maxRow)
+ {
+ column--;
+ row++;
+ }
+ else if (quadrant == BOTTOM_RIGHT && row < maxRow)
+ row++;
+ break;
+ case "bottomLeft":
+ if (quadrant == TOP_LEFT && row > 0)
+ row--;
+ else if (quadrant == TOP_RIGHT && row > 0 && column < maxColumn)
+ {
+ row--;
+ column++;
+ }
+ else if (quadrant == BOTTOM_RIGHT && column < maxColumn)
+ column++;
+ break;
+ case "bottomRight":
+ if (quadrant == TOP_LEFT && column > 0 && row > 0)
+ {
+ column--;
+ row--;
+ }
+ else if (quadrant == TOP_RIGHT && row > 0)
+ row--;
+ else if (quadrant == BOTTOM_LEFT && column > 0)
+ column--
+ break;
+ case "center":
+ // for center snapping, "index" is already always the cell with
+ // its center closest to the specified position
+ break;
+ }
+
+ var newIndex:int;
+ if (orientation == TileOrientation.ROWS)
+ newIndex = row * _columnCount + column;
+ else
+ newIndex = column * _rowCount + row;
+ if (newIndex < g.numElements)
+ index = newIndex;
+
+ return index;
+ } */
+
+}
+}
--
To stop receiving notification emails like this one, please contact
alinakazi@apache.org.