flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cframp...@apache.org
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 GMT
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="<i>empty Vector.&lt;int&gt<i>"
  * 
  *    <strong>Styles</strong>
@@ -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.
+     *  
+     *  <p>Setting selectedColumnIndex to -1, the default, means that no column is selected and 
+     *  selected property for all header renderers will be false.</p>
+
+     * 
+     *  @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.<int> = 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.<int> = 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 <code>GridItemEditorMouseEvent</code>. Each grid
+     *  column may use a different value for cell activation. If no
+     *  value is specified the DataGrid's <code>editorActivationMouseEvent
+     *  </code> 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
+ *  <p>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.</p>
  * 
  *  @langversion 3.0
  *  @playerversion Flash 10
@@ -156,9 +158,12 @@ public class GridDimensions 
     private var rowList:GridRowList = new GridRowList();
     private var _columnWidths:Vector.<Number> = new Vector.<Number>();
 
-    //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



Mime
View raw message