Return-Path: X-Original-To: apmail-incubator-flex-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-flex-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id AE2A6D7EE for ; Fri, 21 Dec 2012 18:06:01 +0000 (UTC) Received: (qmail 37116 invoked by uid 500); 21 Dec 2012 18:06:01 -0000 Delivered-To: apmail-incubator-flex-commits-archive@incubator.apache.org Received: (qmail 37098 invoked by uid 500); 21 Dec 2012 18:06:01 -0000 Mailing-List: contact flex-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: flex-dev@incubator.apache.org Delivered-To: mailing list flex-commits@incubator.apache.org Received: (qmail 37091 invoked by uid 99); 21 Dec 2012 18:06:01 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 21 Dec 2012 18:06:01 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 21 Dec 2012 18:05:47 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 3FB5E2388A4A; Fri, 21 Dec 2012 18:05:25 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1425063 [4/13] - in /incubator/flex/sdk/branches/develop: frameworks/ frameworks/projects/spark/ frameworks/projects/spark/src/ frameworks/projects/spark/src/spark/collections/ frameworks/projects/spark/src/spark/components/ frameworks/pro... Date: Fri, 21 Dec 2012 18:05:22 -0000 To: flex-commits@incubator.apache.org From: cframpton@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121221180525.3FB5E2388A4A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/GridColumnHeaderGroup.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/GridColumnHeaderGroup.as?rev=1425063&r1=1425062&r2=1425063&view=diff ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/GridColumnHeaderGroup.as (original) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/GridColumnHeaderGroup.as Fri Dec 21 18:05:20 2012 @@ -29,9 +29,16 @@ import mx.collections.IList; import mx.core.IFactory; import mx.core.mx_internal; import mx.events.PropertyChangeEvent; +import mx.managers.ILayoutManagerClient; +import spark.components.gridClasses.CellPosition; import spark.components.gridClasses.GridColumn; -import spark.components.gridClasses.GridColumnHeaderGroupLayout; +import spark.components.gridClasses.GridColumnHeaderView; +import spark.components.gridClasses.GridDimensionsView; +import spark.components.gridClasses.GridHeaderLayout; +import spark.components.gridClasses.GridHeaderViewLayout; +import spark.components.gridClasses.GridLayout; +import spark.components.gridClasses.GridView; import spark.components.gridClasses.IDataGridElement; import spark.components.gridClasses.IGridItemRenderer; import spark.events.GridEvent; @@ -303,7 +310,9 @@ use namespace mx_internal; * dataGrid="null" * downColumnIndex="-1" * headerRenderer="null" - * hoverColumnIndex="-1" + * hoverColumnIndex="-1" + * selectedColumnIndex="-1" + * highlightSelectedColumn="false" * visibleSortIndicatorIndices="empty Vector.<int>" * * Styles @@ -340,8 +349,8 @@ use namespace mx_internal; public class GridColumnHeaderGroup extends Group implements IDataGridElement { include "../core/Version.as"; - - /** + + /** * Constructor. * * @langversion 3.0 @@ -353,8 +362,7 @@ public class GridColumnHeaderGroup exten { super(); - layout = new GridColumnHeaderGroupLayout(); - layout.clipAndEnableScrolling = true; + layout = new GridHeaderLayout(); // Event handlers that dispatch GridEvents @@ -425,6 +433,7 @@ public class GridColumnHeaderGroup exten //---------------------------------- private var _dataGrid:DataGrid = null; + private var lockedColumnCountChanged:Boolean = false; [Bindable("dataGridChanged")] @@ -453,17 +462,26 @@ public class GridColumnHeaderGroup exten { if (_dataGrid == value) return; - + if (_dataGrid && _dataGrid.grid) - _dataGrid.grid.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, grid_changeEventHandler); + { + _dataGrid.grid.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, grid_propertyChangeHandler); + _dataGrid.grid.removeEventListener("columnsChanged", grid_propertyChangeHandler); + _dataGrid.grid.removeEventListener("lockedColumnCountChanged", grid_propertyChangeHandler); + } _dataGrid = value; if (_dataGrid && _dataGrid.grid) - _dataGrid.grid.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, grid_changeEventHandler); + { + _dataGrid.grid.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, grid_propertyChangeHandler); + _dataGrid.grid.addEventListener("columnsChanged", grid_propertyChangeHandler); + _dataGrid.grid.addEventListener("lockedColumnCountChanged", grid_propertyChangeHandler); + } layout.clearVirtualLayoutCache(); - invalidateSize(); + + invalidateSize(); invalidateDisplayList(); dispatchChangeEvent("dataGridChanged"); @@ -472,12 +490,19 @@ public class GridColumnHeaderGroup exten /** * @private */ - private function grid_changeEventHandler(event:PropertyChangeEvent):void + private function grid_propertyChangeHandler(event:Event):void { - if (event.property == "horizontalScrollPosition") - horizontalScrollPosition = Number(event.newValue); + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + if (!ghl) + return; + + const pce:PropertyChangeEvent = event as PropertyChangeEvent; + if (pce && (pce.property == "horizontalScrollPosition")) + ghl.centerGridColumnHeaderView.horizontalScrollPosition = Number(pce.newValue); + else if ((event.type == "columnsChanged") || (event.type == "lockedColumnCountChanged")) + invalidateProperties(); } - + //---------------------------------- // downColumnIndex //---------------------------------- @@ -539,7 +564,7 @@ public class GridColumnHeaderGroup exten */ public function get headerRenderer():IFactory { - return _headerRenderer; + return _headerRenderer; // TODO: find a way to make it possible to specify this with DataGrid... } /** @@ -558,7 +583,7 @@ public class GridColumnHeaderGroup exten dispatchChangeEvent("headerRendererChanged"); } - + //---------------------------------- // hoverColumnIndex //---------------------------------- @@ -601,6 +626,103 @@ public class GridColumnHeaderGroup exten } //---------------------------------- + // selectedColumnIndex + //---------------------------------- + + private var _selectedColumnIndex:int = -1; + + [Bindable("selectedColumnIndexChanged")] + + /** + * Specifies the column index of the header renderer currently selected by the user. + * The selected property of the header renderer for selectedColumnIndex will be true + * and false for all other header renderers. + * + *

Setting selectedColumnIndex to -1, the default, means that no column is selected and + * selected property for all header renderers will be false.

+ + * + * @default -1 + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 2.0 + * @productversion Flex 4.5 + */ + public function get selectedColumnIndex():int + { + return _selectedColumnIndex; + } + + /** + * @private + */ + public function set selectedColumnIndex(value:int):void + { + if (_selectedColumnIndex == value) + return; + + _selectedColumnIndex = value; + invalidateDisplayList(); + dispatchChangeEvent("selectedColumnIndexChanged"); + } + + //---------------------------------- + // highlightSelectedColumn + //---------------------------------- + + private var _highlightSelectedColumn:Boolean = false; + + [Bindable("highlightSelectedColumnChanged")] + + /** + * The DefaultGridHeaderRenderer only highlights the selected column when selectedColumnIndex is + * valid and highlightSelectedColumn is true. If this property is set to true and + * the selectedColumnIndex is -1, then the selectedColumnIndex is set to the hoverColumnIndex, + * and if that's -1, then the first visible column. + * + * @default false + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 2.0 + * @productversion Flex 4.5 + */ + public function get highlightSelectedColumn():Boolean + { + return _highlightSelectedColumn; + } + + /** + * @private + */ + public function set highlightSelectedColumn(value:Boolean):void + { + if (_highlightSelectedColumn == value) + return; + + // If this property's value is being changed to true, make sure that the + // initial value of selectedColumnIndex corresponds to a visible column. + // Tabbing to the DataGrid header shouldn't cause the DataGrid to scroll. + + if (value) + { + if ((selectedColumnIndex == -1) && (hoverColumnIndex != 1)) + selectedColumnIndex = hoverColumnIndex; + + if (dataGrid.grid && !dataGrid.grid.isCellVisible(-1, selectedColumnIndex)) + { + const visibleColumnIndices:Vector. = dataGrid.grid.getVisibleColumnIndices(); + selectedColumnIndex = (visibleColumnIndices.length > 0) ? visibleColumnIndices[0] : -1; + } + } + + _highlightSelectedColumn = value; + invalidateDisplayList(); + dispatchChangeEvent("highlightSelectedColumnChanged"); + } + + //---------------------------------- // visibleSortIndicatorIndices //---------------------------------- @@ -635,6 +757,7 @@ public class GridColumnHeaderGroup exten _visibleSortIndicatorIndices = valueCopy; invalidateDisplayList(); + dispatchChangeEvent("visibleSortIndicatorIndicesChanged"); } @@ -665,8 +788,47 @@ public class GridColumnHeaderGroup exten // Methods // //-------------------------------------------------------------------------- - - /** + + private function createGridColumnHeaderView():Group + { + const view:GridColumnHeaderView = new GridColumnHeaderView(); + view.gridColumnHeaderGroup = this; + addElement(view); + + return view; + } + + /** + * Create and/or configure the GridColumnHeaderViews. We're assuming that the + * DataGrid's GridViews have already been created. + */ + public function configureGridColumnHeaderViews():void + { + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + if (!ghl) + return; + + if (ghl.centerGridColumnHeaderView == null) + ghl.centerGridColumnHeaderView = createGridColumnHeaderView(); + + if (dataGrid.lockedColumnCount > 0) + { + ghl.leftGridColumnHeaderView = createGridColumnHeaderView(); + } + else if (ghl.leftGridColumnHeaderView) + { + removeElement(ghl.leftGridColumnHeaderView); + ghl.leftGridColumnHeaderView = null; + } + + const gridLayout:GridLayout = dataGrid.grid.layout as GridLayout; + + GridHeaderViewLayout(ghl.centerGridColumnHeaderView.layout).gridView = gridLayout.centerGridView; + if (ghl.leftGridColumnHeaderView) + GridHeaderViewLayout(ghl.leftGridColumnHeaderView.layout).gridView = gridLayout.leftGridView; + } + + /** * Returns the column index corresponding to the specified coordinates, * or -1 if the coordinates are out of bounds. The coordinates are * resolved with respect to the GridColumnHeaderGroup layout target. @@ -688,7 +850,9 @@ public class GridColumnHeaderGroup exten */ public function getHeaderIndexAt(x:Number, y:Number):int { - return GridColumnHeaderGroupLayout(layout).getHeaderIndexAt(x, y); + // TODO: fix this: x coordinate has to be adjusted + const view:Group = getColumnHeaderViewAtX(x); + return GridHeaderViewLayout(view.layout).getHeaderIndexAt(x, y); } /** @@ -723,7 +887,9 @@ public class GridColumnHeaderGroup exten */ public function getSeparatorIndexAt(x:Number, y:Number):int { - return GridColumnHeaderGroupLayout(layout).getSeparatorIndexAt(x, y); + // TODO: fix this: x coordinate has to be adjusted + const view:Group = getColumnHeaderViewAtX(x); + return GridHeaderViewLayout(view.layout).getSeparatorIndexAt(x, y); } /** @@ -750,7 +916,9 @@ public class GridColumnHeaderGroup exten */ public function getHeaderRendererAt(columnIndex:int):IGridItemRenderer { - return GridColumnHeaderGroupLayout(layout).getHeaderRendererAt(columnIndex); + // TODO: fix this: do the work here, rather than the layout + const view:Group = getColumnHeaderViewAtIndex(columnIndex); + return GridHeaderViewLayout(view.layout).getHeaderRendererAt(columnIndex); } /** @@ -771,9 +939,47 @@ public class GridColumnHeaderGroup exten */ public function getHeaderBounds(columnIndex:int):Rectangle { - return GridColumnHeaderGroupLayout(layout).getHeaderBounds(columnIndex); - } - + // TODO: fix this: do the work here, rather than the layout + const view:Group = getColumnHeaderViewAtIndex(columnIndex); + return GridHeaderViewLayout(view.layout).getHeaderBounds(columnIndex); + } + + /** + * @private + */ + override public function invalidateSize():void + { + super.invalidateSize(); + + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + if (!ghl) + return; + + if (ghl.leftGridColumnHeaderView) + ghl.leftGridColumnHeaderView.invalidateSize(); + + if (ghl.centerGridColumnHeaderView) + ghl.centerGridColumnHeaderView.invalidateSize(); + } + + /** + * @private + */ + override public function invalidateDisplayList():void + { + super.invalidateDisplayList(); + + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + if (!ghl) + return; + + if (ghl.leftGridColumnHeaderView) + ghl.leftGridColumnHeaderView.invalidateDisplayList(); + + if (ghl.centerGridColumnHeaderView) + ghl.centerGridColumnHeaderView.invalidateDisplayList(); + } + //-------------------------------------------------------------------------- // // GridEvent dispatching @@ -788,6 +994,49 @@ public class GridColumnHeaderGroup exten private var pressColumnIndex:int = -1; // column button press occurred on private var pressSeparatorIndex:int = -1; // separator button press occurred on + /** + * @private + * Return the GridView whose bounds contain the MouseEvent, or null. Note that the + * comparison is based strictly on the event's location and the GridViews' bounds. + * The event's target can be anything. + */ + private function mouseEventHeaderView(event:MouseEvent):GridColumnHeaderView + { + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + + const centerGridColumnHeaderView:GridColumnHeaderView = GridColumnHeaderView(ghl.centerGridColumnHeaderView) + if (centerGridColumnHeaderView && centerGridColumnHeaderView.containsMouseEvent(event)) + return centerGridColumnHeaderView; + + const leftGridColumnHeaderView:GridColumnHeaderView = GridColumnHeaderView(ghl.leftGridColumnHeaderView); + if (leftGridColumnHeaderView && leftGridColumnHeaderView.containsMouseEvent(event)) + return leftGridColumnHeaderView; + + return null; + } + + // TODO: apologize for stashing the separatorIndex in headerCP.rowIndex + private function eventToHeaderLocations(event:MouseEvent, headerCP:CellPosition, headerXY:Point):Boolean + { + const view:Group = mouseEventHeaderView(event); + if (!view) + return false; + + const stageXY:Point = new Point(event.stageX, event.stageY); + const viewXY:Point = view.globalToLocal(stageXY); + const viewLayout:GridHeaderViewLayout = view.layout as GridHeaderViewLayout; + const gdv:GridDimensionsView = viewLayout.gridView.gridViewLayout.gridDimensionsView; + const separatorIndex:int = viewLayout.getSeparatorIndexAt(viewXY.x, 0); + + headerCP.rowIndex = (separatorIndex != -1) ? separatorIndex + gdv.viewColumnIndex : -1; + headerCP.columnIndex = (separatorIndex == -1) ? viewLayout.getHeaderIndexAt(viewXY.x, 0) + gdv.viewColumnIndex : -1; + + headerXY.x = viewXY.x + gdv.viewOriginX; + headerXY.y = viewXY.y; + + return true; + } + /** * @private * @@ -813,11 +1062,13 @@ public class GridColumnHeaderGroup exten */ protected function gchg_mouseDownDragUpHandler(event:MouseEvent):void { - const eventStageXY:Point = new Point(event.stageX, event.stageY); - const eventHeaderGroupXY:Point = globalToLocal(eventStageXY); - const eventSeparatorIndex:int = getSeparatorIndexAt(eventHeaderGroupXY.x, 0); - const eventColumnIndex:int = - (eventSeparatorIndex == -1) ? getHeaderIndexAt(eventHeaderGroupXY.x, 0) : -1; + const eventHeaderCP:CellPosition = new CellPosition(); + const eventHeaderXY:Point = new Point(); + if (!eventToHeaderLocations(event, eventHeaderCP, eventHeaderXY)) + return; + + const eventSeparatorIndex:int = eventHeaderCP.rowIndex; + const eventColumnIndex:int = (eventSeparatorIndex == -1) ? eventHeaderCP.columnIndex : -1; var gridEventType:String; switch(event.type) @@ -855,8 +1106,8 @@ public class GridColumnHeaderGroup exten } } - const columnIndex:int = (eventSeparatorIndex != -1) ? eventSeparatorIndex : eventColumnIndex; - dispatchGridEvent(event, gridEventType, eventHeaderGroupXY, columnIndex); + const columnIndex:int = (pressSeparatorIndex != -1) ? pressSeparatorIndex : eventColumnIndex; + dispatchGridEvent(event, gridEventType, eventHeaderXY, columnIndex); } /** @@ -884,33 +1135,32 @@ public class GridColumnHeaderGroup exten */ protected function gchg_mouseMoveHandler(event:MouseEvent):void { - const eventStageXY:Point = new Point(event.stageX, event.stageY); - const eventHeaderGroupXY:Point = globalToLocal(eventStageXY); - const eventSeparatorIndex:int = getSeparatorIndexAt(eventHeaderGroupXY.x, 0); - const eventColumnIndex:int = - (eventSeparatorIndex == -1) ? getHeaderIndexAt(eventHeaderGroupXY.x, 0) : -1; + const eventHeaderCP:CellPosition = new CellPosition(); + const eventHeaderXY:Point = new Point(); + if (!eventToHeaderLocations(event, eventHeaderCP, eventHeaderXY)) + return; + + const eventSeparatorIndex:int = eventHeaderCP.rowIndex; + const eventColumnIndex:int = (eventSeparatorIndex == -1) ? eventHeaderCP.columnIndex : -1; if (eventSeparatorIndex != rollSeparatorIndex) { if (rollSeparatorIndex != -1) - dispatchGridEvent(event, GridEvent.SEPARATOR_ROLL_OUT, eventHeaderGroupXY, rollSeparatorIndex); + dispatchGridEvent(event, GridEvent.SEPARATOR_ROLL_OUT, eventHeaderXY, rollSeparatorIndex); if (eventSeparatorIndex != -1) - dispatchGridEvent(event, GridEvent.SEPARATOR_ROLL_OVER, eventHeaderGroupXY, eventSeparatorIndex); + dispatchGridEvent(event, GridEvent.SEPARATOR_ROLL_OVER, eventHeaderXY, eventSeparatorIndex); } if (eventColumnIndex != rollColumnIndex) { if (rollColumnIndex != -1) - dispatchGridEvent(event, GridEvent.GRID_ROLL_OUT, eventHeaderGroupXY, rollColumnIndex); + dispatchGridEvent(event, GridEvent.GRID_ROLL_OUT, eventHeaderXY, rollColumnIndex); if (eventColumnIndex != -1) - dispatchGridEvent(event, GridEvent.GRID_ROLL_OVER, eventHeaderGroupXY, eventColumnIndex); + dispatchGridEvent(event, GridEvent.GRID_ROLL_OVER, eventHeaderXY, eventColumnIndex); } rollColumnIndex = eventColumnIndex; rollSeparatorIndex = eventSeparatorIndex; - - // update renderer property - hoverColumnIndex = eventColumnIndex; } /** @@ -929,19 +1179,15 @@ public class GridColumnHeaderGroup exten */ protected function gchg_mouseRollOutHandler(event:MouseEvent):void { - const eventStageXY:Point = new Point(event.stageX, event.stageY); - const eventHeaderGroupXY:Point = globalToLocal(eventStageXY); + const eventHeaderXY:Point = globalToLocal(new Point(event.stageX, event.stageY)); if (rollSeparatorIndex != -1) - dispatchGridEvent(event, GridEvent.SEPARATOR_ROLL_OUT, eventHeaderGroupXY, rollSeparatorIndex); + dispatchGridEvent(event, GridEvent.SEPARATOR_ROLL_OUT, eventHeaderXY, rollSeparatorIndex); else if (rollColumnIndex != -1) - dispatchGridEvent(event, GridEvent.GRID_ROLL_OUT, eventHeaderGroupXY, rollColumnIndex); + dispatchGridEvent(event, GridEvent.GRID_ROLL_OUT, eventHeaderXY, rollColumnIndex); rollColumnIndex = -1; rollSeparatorIndex = -1; - - // update renderer property - hoverColumnIndex = -1; } /** @@ -961,16 +1207,18 @@ public class GridColumnHeaderGroup exten */ protected function gchg_clickHandler(event:MouseEvent):void { - const eventStageXY:Point = new Point(event.stageX, event.stageY); - const eventHeaderGroupXY:Point = globalToLocal(eventStageXY); - const eventSeparatorIndex:int = getSeparatorIndexAt(eventHeaderGroupXY.x, 0); - const eventColumnIndex:int = - (eventSeparatorIndex == -1) ? getHeaderIndexAt(eventHeaderGroupXY.x, 0) : -1; + const eventHeaderCP:CellPosition = new CellPosition(); + const eventHeaderXY:Point = new Point(); + if (!eventToHeaderLocations(event, eventHeaderCP, eventHeaderXY)) + return; + const eventSeparatorIndex:int = eventHeaderCP.rowIndex; + const eventColumnIndex:int = (eventSeparatorIndex == -1) ? eventHeaderCP.columnIndex : -1; + if ((eventSeparatorIndex != -1) && (pressSeparatorIndex == eventSeparatorIndex)) - dispatchGridEvent(event, GridEvent.SEPARATOR_CLICK, eventHeaderGroupXY, eventSeparatorIndex); + dispatchGridEvent(event, GridEvent.SEPARATOR_CLICK, eventHeaderXY, eventSeparatorIndex); else if ((eventColumnIndex != -1) && (pressColumnIndex == eventColumnIndex)) - dispatchGridEvent(event, GridEvent.GRID_CLICK, eventHeaderGroupXY, eventColumnIndex); + dispatchGridEvent(event, GridEvent.GRID_CLICK, eventHeaderXY, eventColumnIndex); } /** @@ -991,16 +1239,18 @@ public class GridColumnHeaderGroup exten */ protected function gchg_doubleClickHandler(event:MouseEvent):void { - const eventStageXY:Point = new Point(event.stageX, event.stageY); - const eventHeaderGroupXY:Point = globalToLocal(eventStageXY); - const eventSeparatorIndex:int = getSeparatorIndexAt(eventHeaderGroupXY.x, 0); - const eventColumnIndex:int = - (eventSeparatorIndex == -1) ? getHeaderIndexAt(eventHeaderGroupXY.x, 0) : -1; + const eventHeaderCP:CellPosition = new CellPosition(); + const eventHeaderXY:Point = new Point(); + if (!eventToHeaderLocations(event, eventHeaderCP, eventHeaderXY)) + return; + + const eventSeparatorIndex:int = eventHeaderCP.rowIndex; + const eventColumnIndex:int = (eventSeparatorIndex == -1) ? eventHeaderCP.columnIndex : -1; if ((eventSeparatorIndex != -1) && (pressSeparatorIndex == eventSeparatorIndex)) - dispatchGridEvent(event, GridEvent.SEPARATOR_DOUBLE_CLICK, eventHeaderGroupXY, eventSeparatorIndex); + dispatchGridEvent(event, GridEvent.SEPARATOR_DOUBLE_CLICK, eventHeaderXY, eventSeparatorIndex); else if ((eventColumnIndex != -1) && (pressColumnIndex == eventColumnIndex)) - dispatchGridEvent(event, GridEvent.GRID_DOUBLE_CLICK, eventHeaderGroupXY, eventColumnIndex); + dispatchGridEvent(event, GridEvent.GRID_DOUBLE_CLICK, eventHeaderXY, eventColumnIndex); } /** @@ -1046,5 +1296,32 @@ public class GridColumnHeaderGroup exten const columns:IList = grid.columns; return ((columnIndex >= 0) && (columnIndex < columns.length)) ? columns.getItemAt(columnIndex) as GridColumn : null; } + + /** + * @private + */ + private function getColumnHeaderViewAtX(x:Number):Group + { + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + + if (ghl.leftGridColumnHeaderView && (x < ghl.centerGridColumnHeaderView.getLayoutBoundsX())) + return ghl.leftGridColumnHeaderView; + + return ghl.centerGridColumnHeaderView; + } + + /** + * @private + */ + private function getColumnHeaderViewAtIndex(columnIndex:int):Group + { + const ghl:GridHeaderLayout = layout as GridHeaderLayout; + + if (ghl.leftGridColumnHeaderView && (columnIndex < dataGrid.lockedColumnCount)) + return ghl.leftGridColumnHeaderView; + + return ghl.centerGridColumnHeaderView; + } + } } \ No newline at end of file Added: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridDragProxy.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridDragProxy.as?rev=1425063&view=auto ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridDragProxy.as (added) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridDragProxy.as Fri Dec 21 18:05:20 2012 @@ -0,0 +1,233 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.components.gridClasses +{ + +import flash.display.DisplayObject; +import flash.geom.Point; +import flash.geom.Rectangle; + +import mx.core.IDataRenderer; +import mx.core.UIComponent; +import mx.core.mx_internal; +import mx.styles.IStyleClient; + +import spark.components.DataGrid; +import spark.components.Grid; +import spark.components.Group; +import spark.components.IItemRenderer; + +use namespace mx_internal; + +/** + * The DataGridDragProxy class defines the default drag proxy + * used when dragging data from a DataGrid control. + * + * @langversion 3.0 + * @playerversion Flash 11 + * @playerversion AIR 3.0 + * @productversion Flex 5.0 + */ +public class DataGridDragProxy extends Group +{ + include "../../core/Version.as"; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Constructor. + * + * @langversion 3.0 + * @playerversion Flash 11 + * @playerversion AIR 3.0 + * @productversion Flex 5.0 + */ + public function DataGridDragProxy() + { + super(); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + // + // Overridden methods + // + //-------------------------------------------------------------------------- + + /** + * @private + */ + override protected function createChildren():void + { + super.createChildren(); + + var dataGrid:DataGrid = DataGrid(owner); + var grid:Grid = dataGrid.grid; + + // Make sure we inherit styles from the drag initiator, as those styles + // may be affecting the appearance of the item renderers. + this.styleName = dataGrid; + + width = grid.width + height = grid.height; + + // Find all visible children within the selection: + var selection:Vector. = grid.selectedIndices; + if (!selection || selection.length == 0) + return; + + var offsetX:Number = 0; + var offsetY:Number = 0; + var scrollRect:Rectangle = dataGrid.scrollRect; + if (scrollRect) + { + offsetX = scrollRect.x; + offsetY = scrollRect.y; + } + + var n:int = selection.length; + for (var i:int = 0; i < n; i++) + { + + var index:int = selection[i]; + if (!grid.isCellVisible(index, 0)) + continue; + + var data:Object = grid.getDataProviderItem(index); + var element:IGridItemRenderer = grid.getItemRendererAt(index, 0); + if (!element) + continue; + + var o:Group = new Group(); + + addElement(o); + + // The drag proxy should have the same layoutDirection as the + // DataGrid. + o.layoutDirection = dataGrid.layoutDirection; + + var totalColumnWidth:Number = 0; + var m:int; + var j:int; + var column:GridColumn; + var clone:IGridItemRenderer; + + m = grid.getVisibleColumnIndices().length; + for (j = 0; j < m; j++) + { + column = GridColumn(grid.columns.getItemAt(j)); + + clone = column.itemToRenderer(data).newInstance(); + + IStyleClient(clone).styleName = DataGrid(owner); + + IDataRenderer(clone).data = data; + clone.visible = true; + + + // Copy the dimensions + clone.width = element.width; + clone.height = element.height; + + // Copy the transform + if (element.hasLayoutMatrix3D) + clone.setLayoutMatrix3D(element.getLayoutMatrix3D(), false); + else + clone.setLayoutMatrix(element.getLayoutMatrix(), false); + + clone.x = totalColumnWidth + element.x + 5; + //clone.y -= offsetY; + + // Copy other relevant properties + clone.depth = element.depth; + clone.visible = element.visible; + if (element.postLayoutTransformOffsets) + clone.postLayoutTransformOffsets = element.postLayoutTransformOffsets; + + // Put it in a dragging state + clone.dragging = true; + + // Add the clone as a child + o.addElement(clone); + clone.label = column.itemToLabel(data); + clone.prepare(false); + clone["validateNow"](); + + // FIXME (dloverin): 10 pixels of padding on each renderer. + // The padding is hard-coded in the item renderer. + totalColumnWidth += clone.width + 10; + } + + + o.setLayoutBoundsSize(totalColumnWidth, element.height); + o.width = totalColumnWidth; + o.height = element.height; + + var pt:Point = new Point(0, 0); + pt = DisplayObject(element).localToGlobal(pt); + pt = DataGrid(owner).globalToLocal(pt); + o.y = pt.y; + o.visible = true; + measuredHeight = o.y + o.height; + measuredWidth = totalColumnWidth; + + } + + o.validateNow(); + invalidateDisplayList(); + } + + /** + * @private + */ + override protected function measure():void + { + super.measure(); + + var w:Number = 0; + var h:Number = 0; + var child:UIComponent; + + for (var i:int = 0; i < numChildren; i++) + { + child = getChildAt(i) as UIComponent; + + if (child) + { + w = Math.max(w, child.x + child.width); + h = Math.max(h, child.y + child.height); + } + } + + measuredWidth = measuredMinWidth = w; + measuredHeight = measuredMinHeight = h; + } +} + +} Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridDragProxy.as ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridDragProxy.as ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridEditor.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridEditor.as?rev=1425063&r1=1425062&r2=1425063&view=diff ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridEditor.as (original) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/DataGridEditor.as Fri Dec 21 18:05:20 2012 @@ -50,6 +50,7 @@ import mx.styles.ISimpleStyleClient; import spark.components.DataGrid; import spark.components.Grid; +import spark.components.gridClasses.GridItemEditorActivationMouseEvent; import spark.events.GridEvent; import spark.events.GridItemEditorEvent; @@ -569,7 +570,7 @@ public class DataGridEditor _editedItemRenderer = item; - // Need to turn on focusable children flag so focus manager will + // Need to turn on focusable children flag so focus manager will // allow focus into the data grid's children. if (restoreFocusableChildren) saveDataGridHasFocusableChildren = dataGrid.hasFocusableChildren; @@ -833,9 +834,11 @@ public class DataGridEditor * by calling the item editor's save() method. If the cancel parameter is true, * then the editor's cancel() method is called instead. * - * @param cancel If false the data in the editor is saved. - * Otherwise the data in the editor is discarded. - * + * @param cancel if true then the data in the editor is discarded, + * otherwise it's saved. + * + * @return true if the data in the editor was saved, false otherwise. + * * @see spark.components.IGridItemEditor * * @langversion 3.0 @@ -861,13 +864,20 @@ public class DataGridEditor * * Close the item editor without saving the data. */ - mx_internal function cancelEdit():void + mx_internal function cancelEdit():Boolean { if (itemEditorInstance) { - // send the cancel event and tear down the editor. - dispatchCancelEvent(); - destroyItemEditor(); + if (itemEditorInstance.cancel()) + { + // send the cancel event and tear down the editor. + dispatchCancelEvent(); + destroyItemEditor(); + } + else + { + return false; + } } else if (editedItemRenderer) { @@ -875,6 +885,8 @@ public class DataGridEditor destroyItemEditor(); } + return true; + } @@ -922,16 +934,19 @@ public class DataGridEditor var itemPosition:Object = editedItemPosition; if (!saveItemEditorSession()) { - // the save was cancelled so dispatch a cancel event. - dispatchCancelEvent(); + // The save was cancelled so check if the editor can be cancelled. + // If it can then dispatch a cancel event. + if (itemEditorInstance.cancel()) + dispatchCancelEvent(); + inEndEdit = false; return false; } var dataGridEvent:GridItemEditorEvent = - new GridItemEditorEvent(GridItemEditorEvent.GRID_ITEM_EDITOR_SESSION_SAVE, false, true); + new GridItemEditorEvent(GridItemEditorEvent.GRID_ITEM_EDITOR_SESSION_SAVE); - // SAVE_GRID_ITEM_EDITOR_SESSION events are cancelable + // GRID_ITEM_EDITOR_SESSION_SAVE events are NOT cancelable dataGridEvent.columnIndex = itemPosition.columnIndex; dataGridEvent.column = dataGrid.columns.getItemAt(itemPosition.columnIndex) as GridColumn; dataGridEvent.rowIndex = itemPosition.rowIndex; @@ -1199,6 +1214,29 @@ public class DataGridEditor } + /** + * @private + * + * Get the effective mouse event that activates an editor. + * If the column has a setting, then use it. Otherwise use the setting on + * the data grid. + */ + private function getEditorActivationMouseEvent(columnIndex:int):String + { + var editorActivationMouseEvent:String = null; + + if (columnIndex >= 0 && columnIndex < dataGrid.columns.length) + { + var column:GridColumn = grid.columns.getItemAt(columnIndex) as GridColumn; + editorActivationMouseEvent = column.editorActivationMouseEvent; + } + + if (!editorActivationMouseEvent) + editorActivationMouseEvent = dataGrid.editorActivationMouseEvent; + + return editorActivationMouseEvent; + } + //-------------------------------------------------------------------------- // // Event handlers @@ -1313,12 +1351,22 @@ public class DataGridEditor return; } + var editorActivationMouseEvent:String = getEditorActivationMouseEvent(columnIndex); + if (editorActivationMouseEvent != GridItemEditorActivationMouseEvent.SINGLE_CLICK && + editorActivationMouseEvent != GridItemEditorActivationMouseEvent.SINGLE_CLICK_ON_SELECTED_CELL) + { + return; // not allowed to start editor on a single click + } + // Don't open and editor if the click was not on a previously selected // cell, unless that cell is an item renderer. We don't want to stop // the item renderer from getting focus so start an edit session. const column:GridColumn = dataGrid.columns.getItemAt(columnIndex) as GridColumn; if (r && - (column.rendererIsEditable || wasCellPreviouslySelected(rowIndex, columnIndex))) + (column.rendererIsEditable || + (wasCellPreviouslySelected(rowIndex, columnIndex) && + editorActivationMouseEvent == GridItemEditorActivationMouseEvent.SINGLE_CLICK_ON_SELECTED_CELL) || + editorActivationMouseEvent == GridItemEditorActivationMouseEvent.SINGLE_CLICK)) { //trace("cell was previously selected: (" + rowIndex + "," + columnIndex + ")"); lastItemDown = r; @@ -1354,6 +1402,13 @@ public class DataGridEditor const rowIndex:int = eventRowIndex; var columnIndex:int = eventColumnIndex; + var editorActivationMouseEvent:String = getEditorActivationMouseEvent(columnIndex); + if (editorActivationMouseEvent != GridItemEditorActivationMouseEvent.SINGLE_CLICK && + editorActivationMouseEvent != GridItemEditorActivationMouseEvent.SINGLE_CLICK_ON_SELECTED_CELL) + { + return; // not allowed to start editor on a single click + } + var r:IVisualElement = event.itemRenderer; //trace("grid_gridMouseUpHandler: itemRenderer = " + event.itemRenderer); if (r && r != editedItemRenderer && @@ -1424,6 +1479,12 @@ public class DataGridEditor lastEvent = event; gotDoubleClickEvent = true; + + // If double-click editing is enabled then start up and editor session. + var editorActivationMouseEvent:String = getEditorActivationMouseEvent(event.columnIndex); + if (editorActivationMouseEvent == GridItemEditorActivationMouseEvent.DOUBLE_CLICK) + dataGrid.startItemEditorSession(event.rowIndex, event.columnIndex); + } /** @@ -1674,9 +1735,10 @@ public class DataGridEditor dataGrid.endItemEditorSession(true); } - // set focus back to the grid so grid logic will deal if focus doesn't - // end up somewhere else - dataGrid.setFocus(); + // If the item editor was destroyed then set focus back to the grid + // so grid logic will deal if focus doesn't end up somewhere else. + if (!itemEditorInstance) + dataGrid.setFocus(); } } Modified: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumn.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumn.as?rev=1425063&r1=1425062&r2=1425063&view=diff ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumn.as (original) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumn.as Fri Dec 21 18:05:20 2012 @@ -553,6 +553,8 @@ public class GridColumn extends EventDis * pressing the F2 key. * * @default true + * + * @see spark.components.DataGrid#editable * * @langversion 3.0 * @playerversion Flash 10 @@ -577,6 +579,48 @@ public class GridColumn extends EventDis } //---------------------------------- + // editorActivationMouseEvent + //---------------------------------- + + private var _editorActivationMouseEvent:String = null; + + [Bindable("editorActivationMouseEventChanged")] + [Inspectable(category="General", enumeration="doubleClick,none,singleClick,singleClickOnSelectedCell", defaultValue="singleClickOnSelectedCell")] + + /** + * The type of mouse event that starts an editor session. Must be one of + * values in GridItemEditorMouseEvent. Each grid + * column may use a different value for cell activation. If no + * value is specified the DataGrid's editorActivationMouseEvent + * will be used. + * + * @default null + * + * @see spark.components.DataGrid + * + * @langversion 3.0 + * @playerversion Flash 11 + * @playerversion AIR 3.0 + * @productversion Flex 5.0 + */ + public function get editorActivationMouseEvent():String + { + return _editorActivationMouseEvent; + } + + /** + * @private + */ + public function set editorActivationMouseEvent(value:String):void + { + if (_editorActivationMouseEvent == value) + return; + + _editorActivationMouseEvent = value; + dispatchChangeEvent("editorActivationMouseEventChanged"); + } + + //---------------------------------- // formatter //---------------------------------- Added: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderView.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderView.as?rev=1425063&view=auto ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderView.as (added) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderView.as Fri Dec 21 18:05:20 2012 @@ -0,0 +1,123 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.components.gridClasses +{ +import flash.events.MouseEvent; +import flash.geom.Point; + +import mx.core.LayoutDirection; +import mx.core.mx_internal; + +import spark.components.GridColumnHeaderGroup; +import spark.components.Group; + +use namespace mx_internal; + +/** + * This class is internal to the DataGrid implementation. + * + * GridColumnHeaderViews are created automatically by the GridColumnHeaderGroup class, based on the values of + * the lockedColumnCount Grid properties. + */ +public class GridColumnHeaderView extends Group +{ + private static const zeroPoint:Point = new Point(0, 0); + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Creates a GridColumnHeaderView group with its layout set to a private GridColumnHeaderView specific value. + */ + public function GridColumnHeaderView() + { + super(); + layout = new GridHeaderViewLayout(); + layout.clipAndEnableScrolling = true; + } + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + //---------------------------------- + // gridColumnHeaderGroup + //---------------------------------- + + /** + * The GridColumnHeaderGroup whose columns this header view is associated with. + * + * This property is set by GridColumnHeaderGroup. + */ + public function get gridColumnHeaderGroup():GridColumnHeaderGroup + { + return gridHeaderViewLayout.gridColumnHeaderGroup; + } + + /** + * @private + */ + public function set gridColumnHeaderGroup(value:GridColumnHeaderGroup):void + { + gridHeaderViewLayout.gridColumnHeaderGroup = value; + } + + /** + * Return this GridColumnHeaderGroup's GridColumnHeaderGroupLayout. + */ + public function get gridHeaderViewLayout():GridHeaderViewLayout + { + return layout as GridHeaderViewLayout; + } + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * True if this GridColumnHeaderView's bounds contain the event. + * + * Currently this method does not account for the possibility that this GridColumnHeaderView has been + * rotated or scaled. + */ + public function containsMouseEvent(event:MouseEvent):Boolean + { + const eventStageX:Number = event.stageX; + const eventStageY:Number = event.stageY; + const origin:Point = localToGlobal(zeroPoint); + + origin.x += horizontalScrollPosition; + if (layoutDirection == LayoutDirection.RTL) + origin.x -= width; + + origin.y += verticalScrollPosition; + + return (eventStageX >= origin.x) && (eventStageY >= origin.y) && + (eventStageX < (origin.x + width)) && (eventStageY < (origin.y + height)); + } +} +} \ No newline at end of file Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderView.as ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderView.as ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as?rev=1425063&r1=1425062&r2=1425063&view=diff ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as (original) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as Fri Dec 21 18:05:20 2012 @@ -31,9 +31,11 @@ import mx.events.PropertyChangeEvent; /** * A sparse data structure that represents the widths and heights of a grid. * - * Provides efficient support for finding the cumulative y distance to the + *

Provides efficient support for finding the cumulative y distance to the * start of a particular cell as well as finding the index of a particular * cell at a certain y value. + * GridDimensions optimizes these operations by bookmarking the most recently + * visited rows.

* * @langversion 3.0 * @playerversion Flash 10 @@ -156,9 +158,12 @@ public class GridDimensions private var rowList:GridRowList = new GridRowList(); private var _columnWidths:Vector. = new Vector.(); - //cache for cumulative y values. + // Bookmark recently visited rows by caching the node representing the row + // and the y-value corresponding to the start of the node. + // startY/recentNode is the bookmark used by getRowIndexAt() private var startY:Number = 0; private var recentNode:GridRowNode = null; + // startY2/recentNode2 is bookmark used by getCellY() private var startY2:Number = 0; private var recentNode2:GridRowNode = null; @@ -302,10 +307,8 @@ public class GridDimensions return; _rowGap = value; - - // reset recent node. - recentNode = null; - recentNode2 = null; + + clearCachedNodes(); } //---------------------------------- @@ -338,10 +341,8 @@ public class GridDimensions return; _columnGap = value; - - // reset recent node. - recentNode = null; - recentNode2 = null; + + clearCachedNodes(); } //---------------------------------- @@ -382,15 +383,15 @@ public class GridDimensions _defaultRowHeight = bound(value, _minRowHeight, _maxRowHeight); useMaxTypicalCellHeight = isNaN(_defaultRowHeight); - // reset recent node. - recentNode = null; - recentNode2 = null; + clearCachedNodes(); } //---------------------------------- // defaultColumnWidth //---------------------------------- + private var _defaultColumnWidth:Number = 150; + /** * The default width of a column. * If this changes, update the ASDoc for GridLayout/getItemRendererAt(). @@ -400,12 +401,28 @@ public class GridDimensions * @playerversion AIR 2.0 * @productversion Flex 4.5 */ - public var defaultColumnWidth:Number = 150; + public function get defaultColumnWidth():Number + { + return _defaultColumnWidth; + } + + /** + * @private + */ + public function set defaultColumnWidth(value:Number):void + { + if (value == _defaultColumnWidth) + return; + + _defaultColumnWidth = value; + } //---------------------------------- // variableRowHeight //---------------------------------- + private var _variableRowHeight:Boolean = false; // default value must match Grid property default value + /** * If variableRowHeight is false, calling getRowHeight * will return the value of defaultRowHeight. @@ -415,7 +432,21 @@ public class GridDimensions * @playerversion AIR 2.0 * @productversion Flex 4.5 */ - public var variableRowHeight:Boolean = false; // default value must match Grid property default value + public function get variableRowHeight():Boolean + { + return _variableRowHeight; + } + + /** + * @private + */ + public function set variableRowHeight(value:Boolean):void + { + if (value == _variableRowHeight) + return; + + _variableRowHeight = value; + } //---------------------------------- // minRowHeight @@ -490,6 +521,20 @@ public class GridDimensions //-------------------------------------------------------------------------- /** + * Clears bookmarked nodes. + * Each bookmarked node is associated with a cumulative y-value representing + * the total height of the grid up to the start of the row. + * These values are cleared as well. + */ + private function clearCachedNodes():void + { + recentNode = null; + startY = 0; + recentNode2 = null; + startY2 = 0; + } + + /** * Returns the height of the row at the given index. If variableRowHeight * is true, then the height in precendence order is: the height set by setRowHeight, * the natural height of the row (determined by the maximum of its cell heights), @@ -551,6 +596,8 @@ public class GridDimensions if (node) node.fixedHeight = bound(height, minRowHeight, maxRowHeight); } + + clearCachedNodes(); } /** @@ -762,11 +809,11 @@ public class GridDimensions // subtract previous node's height and its gap. indDiff = node.rowIndex - prevNode.rowIndex - 1; - currentY = currentY - indDiff * (defaultRowHeight + rowGap) - (prevNode.maxCellHeight + rowGap); + currentY = currentY - indDiff * (defaultRowHeight + rowGap) - (getRowHeight(prevNode.rowIndex) + rowGap); nodeY = currentY; node = prevNode; } - + this.recentNode2 = node; this.startY2 = nodeY; @@ -797,13 +844,14 @@ public class GridDimensions { if (node.rowIndex == row) break; - - currentY += node.maxCellHeight; + + // add next row's height and rowGap + currentY += getRowHeight(node.rowIndex); if (node.rowIndex < _rowCount - 1) currentY += rowGap; nextNode = node.next; - + if (!nextNode || (row > node.rowIndex && row < nextNode.rowIndex)) { // at the beginning or somewhere between nodes @@ -813,7 +861,7 @@ public class GridDimensions break; } - // add next node's maxCellHeight and rowGap + // add estimated heights of rows in between measured rows. indDiff = nextNode.rowIndex - node.rowIndex - 1; currentY = currentY + indDiff * (defaultRowHeight + rowGap); nodeY = currentY; @@ -966,7 +1014,7 @@ public class GridDimensions */ private function isYInRow(y:Number, startY:Number, node:GridRowNode):Boolean { - var end:Number = startY + node.maxCellHeight; + var end:Number = startY + getRowHeight(node.rowIndex); // don't add gap for last row. if (node.rowIndex != rowCount - 1) @@ -1031,7 +1079,7 @@ public class GridDimensions } // subtract previous node's height and its gap. - currentY = prevY - prevNode.maxCellHeight - rowGap; + currentY = prevY - getRowHeight(prevNode.rowIndex) - rowGap; node = node.prev; index = node.rowIndex; } @@ -1070,7 +1118,7 @@ public class GridDimensions break; // currentY increments to end of the current node. - currentY += node.maxCellHeight; + currentY += getRowHeight(node.rowIndex); if (node.rowIndex != rowCount - 1) currentY += rowGap; @@ -1152,7 +1200,7 @@ public class GridDimensions cur -= temp + columnGap; - if (cur <= 0) + if (cur < 0) return i; } @@ -1169,28 +1217,27 @@ public class GridDimensions * @playerversion AIR 2.0 * @productversion Flex 4.5 */ - public function getContentWidth(columnCountOverride:int = -1):Number + public function getContentWidth(columnCountOverride:int = -1, startColumnIndex:int = 0):Number { - const nCols:int = (columnCountOverride == -1) ? _columnCount : columnCountOverride; + const nCols:int = (columnCountOverride == -1) ? columnCount - startColumnIndex : columnCountOverride; var contentWidth:Number = 0; - var width:Number; var measuredColCount:int = 0; - for (var i:int = 0; (i < _columnCount) && (measuredColCount < nCols); i++) + for (var columnIndex:int = startColumnIndex; (columnIndex < columnCount) && (measuredColCount < nCols); columnIndex++) { - if (i >= _columnWidths.length) + if (columnIndex >= _columnWidths.length) { contentWidth += defaultColumnWidth; measuredColCount++; continue; } - width = _columnWidths[i]; + var width:Number = _columnWidths[columnIndex]; // fall back on typical width if (isNaN(width)) { - width = typicalCellWidths[i]; + width = typicalCellWidths[columnIndex]; // column.visible==false, skip this column. if (width == 0) continue; @@ -1204,15 +1251,15 @@ public class GridDimensions measuredColCount++; } - if (nCols > 1) - contentWidth += (nCols - 1) * columnGap; + if (measuredColCount > 1) + contentWidth += (measuredColCount - 1) * columnGap; return contentWidth; } /** * Returns the total layout height of the content including gaps. If - * rowHeightOverride is specified, then the overall height of as many rows + * rowCountOverride is specified, then the overall height of as many rows * is returned. * * @langversion 3.0 @@ -1220,9 +1267,10 @@ public class GridDimensions * @playerversion AIR 2.0 * @productversion Flex 4.5 */ - public function getContentHeight(rowCountOverride:int = -1):Number + public function getContentHeight(rowCountOverride:int = -1, startRowIndex:int = 0):Number { - const nRows:int = (rowCountOverride == -1) ? rowCount : rowCountOverride; + const nRows:int = (rowCountOverride == -1) ? rowCount - startRowIndex : rowCountOverride; + const maxRow:int = (rowCountOverride == -1) ? rowCount : startRowIndex + rowCountOverride; var contentHeight:Number = 0; if (nRows > 1) @@ -1231,12 +1279,14 @@ public class GridDimensions if (!variableRowHeight || rowList.length == 0) return contentHeight + nRows * defaultRowHeight; - var node:GridRowNode = rowList.first; + var node:GridRowNode = (startRowIndex == 0) ? rowList.first : rowList.findNearestLTE(startRowIndex); var numRows:int = 0; - while (node && node.rowIndex < nRows) + while (node && node.rowIndex < maxRow) { - contentHeight += node.maxCellHeight; + if (node.rowIndex < startRowIndex) + continue; + contentHeight += getRowHeight(node.rowIndex); numRows++; node = node.next; } @@ -1256,16 +1306,16 @@ public class GridDimensions * @playerversion AIR 2.0 * @productversion Flex 4.5 */ - public function getTypicalContentWidth(columnCountOverride:int = -1):Number + public function getTypicalContentWidth(columnCountOverride:int = -1, startColumnIndex:int = 0):Number { - const nCols:int = (columnCountOverride == -1) ? _columnCount : columnCountOverride; + const nCols:int = (columnCountOverride == -1) ? columnCount - startColumnIndex : columnCountOverride; var contentWidth:Number = 0; var measuredColCount:int = 0; - for (var columnIndex:int = 0; (columnIndex < _columnCount) && (measuredColCount < nCols); columnIndex++) + for (var columnIndex:int = startColumnIndex; (columnIndex < columnCount) && (measuredColCount < nCols); columnIndex++) { // column.visible==false columns will have a typicalCellWidth of 0, so skip them. - var width:Number = columnIndex < _columnCount ? typicalCellWidths[columnIndex] : NaN; + var width:Number = columnIndex < columnCount ? typicalCellWidths[columnIndex] : NaN; if (width == 0) continue; @@ -1276,7 +1326,7 @@ public class GridDimensions measuredColCount++; } - if (nCols > 1) + if (measuredColCount > 1) contentWidth += (measuredColCount - 1) * columnGap; return contentWidth; @@ -1292,9 +1342,9 @@ public class GridDimensions * @playerversion AIR 2.0 * @productversion Flex 4.5 */ - public function getTypicalContentHeight(rowCountOverride:int = -1):Number + public function getTypicalContentHeight(rowCountOverride:int = -1, startRowIndex:int = 0):Number { - const nRows:int = (rowCountOverride == -1) ? rowCount : rowCountOverride; + const nRows:int = (rowCountOverride == -1) ? rowCount - startRowIndex : rowCountOverride; var contentHeight:Number = 0; if (nRows > 1) @@ -1487,9 +1537,8 @@ public class GridDimensions typicalCellWidths.splice(startColumn, count); typicalCellHeights.splice(startColumn, count); - // cache is invalid because node values might have changed - recentNode = null; - recentNode2 = null; + // bookmarks are invalid because row heights may have changed. + clearCachedNodes(); } /** @@ -1520,9 +1569,8 @@ public class GridDimensions rowList.removeNode(oldNode); } - // cache is invalid now. - recentNode = null; - recentNode2 = null; + // bookmarks are invalid because row heights may have changed. + clearCachedNodes(); } /** @@ -1545,9 +1593,8 @@ public class GridDimensions clearVector(typicalCellHeights, NaN, startColumn, count); clearVector(_columnWidths, NaN, startColumn, count); - // cache is invalid because node values might have changed - recentNode = null; - recentNode2 = null; + // bookmarks are invalid because row heights may have changed. + clearCachedNodes(); } /** @@ -1605,10 +1652,7 @@ public class GridDimensions public function clearHeights():void { rowList.removeAll(); - recentNode = null; - recentNode2 = null; - startY = 0; - startY2 = 0; + clearCachedNodes(); } /** @@ -1656,9 +1700,8 @@ public class GridDimensions this.rowCount += count; - // cache is invalid now. - recentNode = null; - recentNode2 = null; + // bookmarks are invalid because row heights may have changed. + clearCachedNodes(); } /** @@ -1695,9 +1738,8 @@ public class GridDimensions _rowCount -= count; - // cache is invalid now. - recentNode = null; - recentNode2 = null; + // bookmarks are invalid because row heights may have changed. + clearCachedNodes(); return vec; } Added: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensionsView.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensionsView.as?rev=1425063&view=auto ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensionsView.as (added) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensionsView.as Fri Dec 21 18:05:20 2012 @@ -0,0 +1,285 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.components.gridClasses +{ +import flash.geom.Rectangle; + +[ExcludeClass] + +/** + * A "view" of a rectangular region within a GridDimensions object. The origin of the region + * is specified by viewRowIndex,viewColumnIndex and the size of the region by viewRowCount and + * viewColumnCount. + * + * Unless otherwise specified, all of the methods defined here have GridDimensionsView-relative + * parameters and similarly return values relative to the GridView's viewRow,ColumnIndex origin. + * + * All of the methods and properties defined here just delegate to GridDimensions + * methods with the same names and semantics. + * + * This class is internal to the Grid implementation. + * + * @langversion 3.0 + * @playerversion Flash 11 + * @playerversion AIR 3 + * @productversion Flex 5.0 + */ +public class GridDimensionsView +{ + public var gridDimensions:GridDimensions = null; + public var viewRowIndex:int = 0; + public var viewColumnIndex:int = 0; + public var viewRowCount:int = -1; + public var viewColumnCount:int = -1; + + public function GridDimensionsView(gridDimensions:GridDimensions = null, + viewRowIndex:int = 0, viewColumnIndex:int = 0, viewRowCount:int = -1, viewColumnCount:int = -1) + { + super(); + this.gridDimensions = gridDimensions; + this.viewRowIndex = viewRowIndex; + this.viewColumnIndex = viewColumnIndex; + this.viewRowCount = viewRowCount; + this.viewColumnCount = viewColumnCount; + } + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + public function get rowCount():int + { + const nRows:int = gridDimensions.rowCount; + return (viewRowCount == -1) ? nRows - viewRowIndex : viewRowCount; + } + + public function get columnCount():int + { + const nColumns:int = gridDimensions.columnCount; + return (viewColumnCount == -1) ? nColumns - viewColumnIndex : viewColumnCount; + } + + public function get rowGap():Number + { + return gridDimensions.rowGap; + } + + public function get columnGap():Number + { + return gridDimensions.columnGap; + } + + public function get defaultRowHeight():Number + { + return gridDimensions.defaultRowHeight; + } + + public function get defaultColumnWidth():Number + { + return gridDimensions.defaultColumnWidth; + } + + public function get variableRowHeight():Boolean + { + return gridDimensions.variableRowHeight; + } + + public function get minRowHeight():Number + { + return gridDimensions.minRowHeight; + } + + public function get maxRowHeight():Number + { + return gridDimensions.maxRowHeight; + } + + /** + * Return the Grid X coordinate of the GridDimensionView's viewRow,ColumnIndex origin. + */ + public function get viewOriginX():Number + { + return gridDimensions.getCellX(viewRowIndex, viewColumnIndex); + } + + /** + * Return the Grid Y coordinate of the GridDimensionView's viewRow,ColumnIndex origin. + */ + public function get viewOriginY():Number + { + return gridDimensions.getCellY(viewRowIndex, viewColumnIndex); + } + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + public function getRowHeight(row:int):Number + { + return gridDimensions.getRowHeight(row + viewRowIndex); + } + + public function setRowHeight(row:int, height:Number):void + { + gridDimensions.setRowHeight(row + viewRowIndex, height); + } + + public function getColumnWidth(col:int):Number + { + return gridDimensions.getColumnWidth(col + viewColumnIndex); + } + + public function setColumnWidth(col:int, width:Number):void + { + gridDimensions.setColumnWidth(col + viewColumnIndex, width); + } + + public function getCellHeight(row:int, col:int):Number + { + return gridDimensions.getCellHeight(row + viewRowIndex, col + viewColumnIndex); + } + + public function setCellHeight(row:int, col:int, height:Number):void + { + gridDimensions.setCellHeight(row + viewRowIndex, col + viewColumnIndex, height); + } + + public function getCellBounds(row:int, col:int):Rectangle + { + const bounds:Rectangle = gridDimensions.getCellBounds(row + viewRowIndex, col + viewColumnIndex); + if (!bounds) + return null; + + bounds.x -= viewOriginX; + bounds.y -= viewOriginY; + return bounds; + } + + public function getCellX(row:int, col:int):Number + { + return gridDimensions.getCellX(row + viewRowIndex, col + viewColumnIndex) - viewOriginX; + } + + public function getCellY(row:int, col:int):Number + { + return gridDimensions.getCellY(row + viewRowIndex, col + viewColumnIndex) - viewOriginY; + } + + public function getRowBounds(row:int):Rectangle + { + const bounds:Rectangle = gridDimensions.getRowBounds(row + viewRowIndex); + if (!bounds) + return null; + + bounds.x -= viewOriginX; + bounds.y -= viewOriginY; + return bounds; + } + + public function getPadRowBounds(row:int):Rectangle + { + const bounds:Rectangle = gridDimensions.getPadRowBounds(row + viewRowIndex); + if (!bounds) + return null; + + bounds.x -= viewOriginX; + bounds.y -= viewOriginY; + return bounds; + } + + public function getColumnBounds(col:int):Rectangle + { + const bounds:Rectangle = gridDimensions.getColumnBounds(col + viewColumnIndex); + if (!bounds) + return null; + + bounds.x -= viewOriginX; + bounds.y -= viewOriginY; + return bounds; + } + + public function getRowIndexAt(viewX:Number, viewY:Number):int + { + const rowIndex:int = gridDimensions.getRowIndexAt(viewX + viewOriginX, viewY + viewOriginY) - viewRowIndex; + return rowIndex >= 0 ? rowIndex : -1; + } + + public function getColumnIndexAt(viewX:Number, viewY:Number):int + { + const columnIndex:int = gridDimensions.getColumnIndexAt(viewX + viewOriginX, viewY + viewOriginY) - viewColumnIndex; + return columnIndex >= 0 ? columnIndex : -1; + } + + public function getContentWidth(columnCountOverride:int = -1, startColumnIndex:int = 0):Number + { + const nColumns:int = (columnCount== -1) ? viewColumnCount : columnCountOverride; + return gridDimensions.getContentWidth(nColumns, viewColumnIndex + startColumnIndex); + } + + public function getContentHeight(rowCountOverride:int = -1, startRowIndex:int = 0):Number + { + const nRows:int = (rowCount== -1) ? viewRowCount : rowCountOverride; + return gridDimensions.getContentHeight(nRows, viewRowIndex + startRowIndex); + } + + public function getTypicalContentWidth(columnCountOverride:int = -1, startColumnIndex:int = 0):Number + { + const nColumns:int = (columnCount== -1) ? viewColumnCount : columnCountOverride; + return gridDimensions.getTypicalContentWidth(nColumns, viewColumnIndex + startColumnIndex); + } + + public function getTypicalContentHeight(rowCountOverride:int = -1, startRowIndex:int = 0):Number + { + const nRows:int = (rowCount== -1) ? viewRowCount : rowCountOverride; + return gridDimensions.getTypicalContentHeight(nRows, viewRowIndex + startRowIndex); + } + + public function getTypicalCellWidth(columnIndex:int):Number + { + return gridDimensions.getTypicalCellWidth(columnIndex + viewColumnIndex); + } + + public function setTypicalCellWidth(columnIndex:int, value:Number):void + { + gridDimensions.setTypicalCellWidth(columnIndex + viewColumnIndex, value); + } + + public function getTypicalCellHeight(columnIndex:int):Number + { + return gridDimensions.getTypicalCellHeight(columnIndex + viewColumnIndex); + } + + public function setTypicalCellHeight(columnIndex:int, value:Number):void + { + gridDimensions.setTypicalCellHeight(columnIndex + viewColumnIndex, value); + } + + public function toString():String + { + return "GridDimensionsView " + + viewRowIndex + "," + viewColumnIndex + " " + viewRowCount + "X" + viewColumnCount + " " + + gridDimensions.toString(); + } +} +} \ No newline at end of file Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensionsView.as ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensionsView.as ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridHeaderLayout.as URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridHeaderLayout.as?rev=1425063&view=auto ============================================================================== --- incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridHeaderLayout.as (added) +++ incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridHeaderLayout.as Fri Dec 21 18:05:20 2012 @@ -0,0 +1,219 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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.components.gridClasses +{ +import flash.events.Event; + +import spark.components.Grid; +import spark.components.GridColumnHeaderGroup; +import spark.components.Group; +import spark.layouts.supportClasses.LayoutBase; + +//[ExcludeClass] TBD + +/** + * @private + * The internal layout class used by GridColumnHeaderGroup. Responsible for the + * the layout the left and center column header views. There is no gap between the + * two views however there are gaps between the overall left and right header view edges + * defined by leftPadding and rightPadding. + * + * This class is private to the DataGrid implementation. It's only used by the + * DataGrid's columnHeaderGroup skin part. + * + * This layout class is unusual because its updateDisplayList method depends on + * the results of laying out the DataGrid grid's columns, i.e. it depends on the + * the results of the Grid's layout. The DataGrid forces the grid's nestLevel to + * be less than the nestLevel of its columnHeaderGroup to ensure that the grid + * subtree is laid out first. + * + * This layout's measuredWidth is essentially zero because the DataGrid's grid + * dictates the overall measured width. The columnHeaderGroup only contributes + * to the DataGrid's measured height. + */ +public class GridHeaderLayout extends LayoutBase +{ + public function GridHeaderLayout() + { + super(); + } + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + /** + * @private + */ + private function dispatchChangeEvent(type:String):void + { + if (hasEventListener(type)) + dispatchEvent(new Event(type)); + } + + //---------------------------------- + // centerGridColumnHeaderView + //---------------------------------- + + private var _centerGridColumnHeaderView:Group = null; + + [Bindable("centerGridColumnHeaderViewChanged")] + + /** + * Contains the column headers for the Grid's centerGridView, the unlocked columns. + * + * @default null + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 2.5 + * @productversion Flex 5.0 + */ + public function get centerGridColumnHeaderView():Group + { + return _centerGridColumnHeaderView; + } + + /** + * @private + */ + public function set centerGridColumnHeaderView(value:Group):void + { + if (_centerGridColumnHeaderView == value) + return; + + _centerGridColumnHeaderView = value; + dispatchChangeEvent("centerGridColumnHeaderViewChanged"); + } + + //---------------------------------- + // leftGridColumnHeaderView + //---------------------------------- + + private var _leftGridColumnHeaderView:Group = null; + + [Bindable("leftGridColumnHeaderViewChanged")] + + /** + * Contains the column headers for the Grid's leftGridView lockedColumnCount columns. + * + * @default null + * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 2.5 + * @productversion Flex 5.0 + */ + public function get leftGridColumnHeaderView():Group + { + return _leftGridColumnHeaderView; + } + + /** + * @private + */ + public function set leftGridColumnHeaderView(value:Group):void + { + if (_leftGridColumnHeaderView == value) + return; + + _leftGridColumnHeaderView = value; + dispatchChangeEvent("leftGridColumnHeaderViewChanged"); + } + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * @private + */ + override public function measure():void + { + const gridColumnHeaderGroup:GridColumnHeaderGroup = target as GridColumnHeaderGroup; + if (!gridColumnHeaderGroup) + return; + + const paddingLeft:Number = gridColumnHeaderGroup.getStyle("paddingLeft"); + const paddingRight:Number = gridColumnHeaderGroup.getStyle("paddingRight"); + const paddingTop:Number = gridColumnHeaderGroup.getStyle("paddingTop"); + const paddingBottom:Number = gridColumnHeaderGroup.getStyle("paddingBottom"); + + const measuredWidth:Number = Math.max(0, target.getMinBoundsWidth()) + paddingLeft + paddingRight; + const centerView:Group = centerGridColumnHeaderView; + const centerHeight:Number = (centerView) ? centerView.getPreferredBoundsHeight() : 0; + const measuredHeight:Number = centerHeight + paddingTop + paddingBottom; + + target.measuredWidth = Math.ceil(measuredWidth); + target.measuredHeight = Math.ceil(measuredHeight); + target.measuredMinWidth = Math.ceil(measuredWidth); + target.measuredMinHeight = Math.ceil(measuredHeight); + } + + /** + * @private + */ + override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void + { + const gridColumnHeaderGroup:GridColumnHeaderGroup = target as GridColumnHeaderGroup; + if (!gridColumnHeaderGroup || !centerGridColumnHeaderView) + return; + + // Note that paddingLeft guarantees that the centerGridColumnHeaderView lines up + // with the Grid's centerGridView. + + const paddingLeft:Number = gridColumnHeaderGroup.getStyle("paddingLeft"); + const paddingRight:Number = gridColumnHeaderGroup.getStyle("paddingRight"); + const paddingTop:Number = gridColumnHeaderGroup.getStyle("paddingTop"); + const paddingBottom:Number = gridColumnHeaderGroup.getStyle("paddingBottom"); + + const grid:Grid = gridColumnHeaderGroup.dataGrid.grid; + const gridLayout:GridLayout = gridColumnHeaderGroup.dataGrid.grid.layout as GridLayout; + const lockedColumnCount:int = gridColumnHeaderGroup.dataGrid.lockedColumnCount; + + const centerView:Group = centerGridColumnHeaderView; + const leftView:Group = leftGridColumnHeaderView; + const headerHeight:Number = Math.max(0, unscaledHeight - (paddingTop + paddingBottom)); + + var centerGridViewX:Number = gridLayout.centerGridView.getLayoutBoundsX(); + if (lockedColumnCount > 0) + { + leftView.setLayoutBoundsSize(centerGridViewX - paddingLeft, headerHeight); + leftView.setLayoutBoundsPosition(paddingLeft, paddingTop); + } + else + { + centerGridViewX += paddingLeft; + } + + centerView.setLayoutBoundsSize(unscaledWidth - centerGridViewX, headerHeight); + centerView.setLayoutBoundsPosition(centerGridViewX, paddingTop); + + // The DataGrid invalidates this layout when the GridLayout's centerGridView is scrolled + // horizontally. It assumes that the header's centerView has the same contentWidth as + // the centerGridView so it's not necessary to set the content size here. + } + +} +} \ No newline at end of file Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridHeaderLayout.as ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/flex/sdk/branches/develop/frameworks/projects/spark/src/spark/components/gridClasses/GridHeaderLayout.as ------------------------------------------------------------------------------ svn:mime-type = text/plain